Compare commits
95 Commits
server-202
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9ac31b619a | ||
|
|
8dcf813bbc | ||
|
|
1d332848f6 | ||
|
|
39184c3be4 | ||
|
|
a1d9867e68 | ||
|
|
fdd2b94afb | ||
|
|
9979d142f2 | ||
|
|
d027188727 | ||
|
|
b7fd897103 | ||
|
|
1fcc0f7aa5 | ||
|
|
d3875f10ff | ||
|
|
1a3f14591b | ||
|
|
7a068167eb | ||
|
|
1765c2d02d | ||
|
|
cdf0e273b1 | ||
|
|
301b96e067 | ||
|
|
a9b715ffaf | ||
|
|
eb14f9b088 | ||
|
|
834e4e1f96 | ||
|
|
b23a8ec307 | ||
|
|
5fdb3f585f | ||
|
|
2b41dc5dcf | ||
|
|
c0326a1862 | ||
|
|
a9d5434ac6 | ||
|
|
1378777b7b | ||
|
|
959682b0e3 | ||
|
|
8409f85e37 | ||
|
|
cf0307552c | ||
|
|
701df37900 | ||
|
|
0b37ae8be8 | ||
|
|
669a690c8b | ||
|
|
9b738fc300 | ||
|
|
1f92791440 | ||
|
|
abf0a2970b | ||
|
|
9b91a60c75 | ||
|
|
4eb5d9a7ac | ||
|
|
a5d50446ed | ||
|
|
231a48fa87 | ||
|
|
dc43239bcb | ||
|
|
313cced050 | ||
|
|
309b0fe33f | ||
|
|
7d7ec20ae0 | ||
|
|
0e552b63c6 | ||
|
|
affdb4c0bb | ||
|
|
8c62644314 | ||
|
|
811069280f | ||
|
|
ee587919a8 | ||
|
|
4af92d7ae6 | ||
|
|
5fb5a30188 | ||
|
|
be9cdc2276 | ||
|
|
8a98824e5e | ||
|
|
42e78083ab | ||
|
|
779f8ae61c | ||
|
|
9d4a8f87ce | ||
|
|
4346e37421 | ||
|
|
0ca8c95874 | ||
|
|
5aa0fdb821 | ||
|
|
49636311ba | ||
|
|
d0af75f721 | ||
|
|
1d3af05758 | ||
|
|
ac1cfd9fc9 | ||
|
|
1f87e181ce | ||
|
|
5ba86df981 | ||
|
|
7734784de3 | ||
|
|
7254e4a840 | ||
|
|
c86c9cd484 | ||
|
|
62ae049fa8 | ||
|
|
b3ac7e115b | ||
|
|
be20741e9a | ||
|
|
b739d57ee7 | ||
|
|
92d1d7dc21 | ||
|
|
1610226eb4 | ||
|
|
0457d078f8 | ||
|
|
838f284d04 | ||
|
|
7a5da5781c | ||
|
|
3ca22147c0 | ||
|
|
2e9812d0aa | ||
|
|
b1d765665b | ||
|
|
e3d6e38a26 | ||
|
|
1d5c9a109e | ||
|
|
d2b2c31962 | ||
|
|
e7488b4329 | ||
|
|
903c62ab9f | ||
|
|
5518521b73 | ||
|
|
692de451e3 | ||
|
|
1809d1ebbc | ||
|
|
9bc673f40b | ||
|
|
6b78b69fa5 | ||
|
|
4a38cfbdc7 | ||
|
|
d88ff2ad2a | ||
|
|
083caa1c83 | ||
|
|
b39afc1466 | ||
|
|
0987242032 | ||
|
|
1d4da9e1f8 | ||
|
|
3ad5900136 |
14
.devcontainer/devcontainer.json
Normal file
14
.devcontainer/devcontainer.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "Node.js",
|
||||
// "Officially" maintained node devcontainer image from Microsoft
|
||||
// https://github.com/devcontainers/templates/tree/main/src/javascript-node
|
||||
"image": "mcr.microsoft.com/devcontainers/javascript-node:1-20-bookworm",
|
||||
|
||||
// Features to add to the dev container. More info: https://containers.dev/features.
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/github-cli:1": {}
|
||||
},
|
||||
|
||||
// Use 'postCreateCommand' to run commands after the container is created.
|
||||
"postCreateCommand": "npm ci"
|
||||
}
|
||||
@@ -2,8 +2,12 @@ node_modules/
|
||||
shields.env
|
||||
.git/
|
||||
.gitignore
|
||||
.github
|
||||
.vscode/
|
||||
fly.toml
|
||||
|
||||
*.md
|
||||
doc/
|
||||
|
||||
# Improve layer cacheability.
|
||||
Dockerfile
|
||||
|
||||
115
.github/actions/docusaurus-swizzled-warning/package-lock.json
generated
vendored
115
.github/actions/docusaurus-swizzled-warning/package-lock.json
generated
vendored
@@ -89,18 +89,33 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/endpoint": {
|
||||
"version": "9.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.1.tgz",
|
||||
"integrity": "sha512-hRlOKAovtINHQPYHZlfyFwaM8OyetxeoC81lAkBy34uLb8exrZB50SQdeW3EROqiY9G9yxQTpp5OHTV54QD+vA==",
|
||||
"version": "9.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.6.tgz",
|
||||
"integrity": "sha512-H1fNTMA57HbkFESSt3Y9+FBICv+0jFceJFPWDePYlR/iMGrwM5ph+Dd4XRQs+8X+PUFURLQgX9ChPfhJ/1uNQw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^12.0.0",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"@octokit/types": "^13.1.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/endpoint/node_modules/@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/endpoint/node_modules/@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/graphql": {
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.0.2.tgz",
|
||||
@@ -115,22 +130,24 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/openapi-types": {
|
||||
"version": "19.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-19.0.0.tgz",
|
||||
"integrity": "sha512-PclQ6JGMTE9iUStpzMkwLCISFn/wDeRjkZFIKALpvJQNBGwDoYYi2fFvuHwssoQ1rXI5mfh6jgTgWuddeUzfWw=="
|
||||
"version": "20.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz",
|
||||
"integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/plugin-paginate-rest": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.0.0.tgz",
|
||||
"integrity": "sha512-oIJzCpttmBTlEhBmRvb+b9rlnGpmFgDtZ0bB6nq39qIod6A5DP+7RkVLMOixIgRCYSHDTeayWqmiJ2SZ6xgfdw==",
|
||||
"version": "9.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.2.2.tgz",
|
||||
"integrity": "sha512-u3KYkGF7GcZnSD/3UP0S7K5XUFT2FkOQdcfXZGZQPGv3lm4F2Xbf71lvjldr8c1H3nNbF+33cLEkWYbokGWqiQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^12.0.0"
|
||||
"@octokit/types": "^12.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": ">=5"
|
||||
"@octokit/core": "5"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/plugin-rest-endpoint-methods": {
|
||||
@@ -148,14 +165,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request": {
|
||||
"version": "8.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.1.4.tgz",
|
||||
"integrity": "sha512-M0aaFfpGPEKrg7XoA/gwgRvc9MSXHRO2Ioki1qrPDbl1e9YhjIwVoHE7HIKmv/m3idzldj//xBujcFNqGX6ENA==",
|
||||
"version": "8.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.4.1.tgz",
|
||||
"integrity": "sha512-qnB2+SY3hkCmBxZsR/MPCybNmbJe4KAlfWErXq+rBKkQJlbjdJeS85VI9r8UqeLYLvnAenU8Q1okM/0MBsAGXw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/endpoint": "^9.0.0",
|
||||
"@octokit/request-error": "^5.0.0",
|
||||
"@octokit/types": "^12.0.0",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"@octokit/endpoint": "^9.0.6",
|
||||
"@octokit/request-error": "^5.1.1",
|
||||
"@octokit/types": "^13.1.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
@@ -163,11 +180,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request-error": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.0.1.tgz",
|
||||
"integrity": "sha512-X7pnyTMV7MgtGmiXBwmO6M5kIPrntOXdyKZLigNfQWSEQzVxR4a4vo49vJjTWX70mPndj8KhfT4Dx+2Ng3vnBQ==",
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.1.1.tgz",
|
||||
"integrity": "sha512-v9iyEQJH6ZntoENr9/yXxjuezh4My67CBSu9r6Ve/05Iu5gNgnisNWOsoJHTP6k0Rr0+HQIpnH+kyammu90q/g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^12.0.0",
|
||||
"@octokit/types": "^13.1.0",
|
||||
"deprecation": "^2.0.0",
|
||||
"once": "^1.4.0"
|
||||
},
|
||||
@@ -175,12 +193,43 @@
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/types": {
|
||||
"version": "12.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.0.0.tgz",
|
||||
"integrity": "sha512-EzD434aHTFifGudYAygnFlS1Tl6KhbTynEWELQXIbTY8Msvb5nEqTZIm7sbPEt4mQYLZwu3zPKVdeIrw0g7ovg==",
|
||||
"node_modules/@octokit/request-error/node_modules/@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/request-error/node_modules/@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^19.0.0"
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request/node_modules/@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/request/node_modules/@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/types": {
|
||||
"version": "12.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz",
|
||||
"integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^20.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/before-after-hook": {
|
||||
@@ -193,14 +242,6 @@
|
||||
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
|
||||
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
|
||||
},
|
||||
"node_modules/is-plain-object": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
|
||||
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
|
||||
@@ -4,6 +4,11 @@ Note: this changelog is for the shields.io server. The changelog for the badge-m
|
||||
|
||||
---
|
||||
|
||||
## server-2025-03-02
|
||||
|
||||
- time out long running requests more aggressively [#10833](https://github.com/badges/shields/issues/10833)
|
||||
- Dependency updates
|
||||
|
||||
## server-2025-02-02
|
||||
|
||||
- Mark Stubs-only packages with [PypiTypes] badge [#10864](https://github.com/badges/shields/issues/10864)
|
||||
|
||||
12
Dockerfile
12
Dockerfile
@@ -1,5 +1,7 @@
|
||||
FROM node:20-alpine AS builder
|
||||
|
||||
RUN npm install -g "npm@^10"
|
||||
|
||||
RUN mkdir -p /usr/src/app
|
||||
RUN mkdir /usr/src/app/private
|
||||
WORKDIR /usr/src/app
|
||||
@@ -8,14 +10,16 @@ COPY package.json package-lock.json /usr/src/app/
|
||||
# Without the badge-maker package.json and CLI script in place, `npm ci` will fail.
|
||||
COPY badge-maker /usr/src/app/badge-maker/
|
||||
|
||||
RUN npm install -g "npm@^10"
|
||||
# We need dev deps to build the front end. We don't need Cypress, though.
|
||||
RUN NODE_ENV=development CYPRESS_INSTALL_BINARY=0 npm ci
|
||||
|
||||
COPY . /usr/src/app
|
||||
RUN npm run build
|
||||
RUN npm prune --omit=dev
|
||||
RUN npm cache clean --force
|
||||
|
||||
RUN npm run build \
|
||||
&& npm prune --omit=dev --force \
|
||||
&& rm -rf node_modules/.cache \
|
||||
&& rm -rf frontend package-lock.json
|
||||
|
||||
|
||||
# Use multi-stage build to reduce size
|
||||
FROM node:20-alpine
|
||||
|
||||
@@ -96,6 +96,8 @@ If you intend on reporting or contributing a fix related to security vulnerabili
|
||||
|
||||
## Development
|
||||
|
||||
[](https://codespaces.new/badges/shields?quickstart=1)
|
||||
|
||||
1. Install Node 20 or later. You can use the [package manager][] of your choice.
|
||||
Tests need to pass in Node 20 and 22.
|
||||
2. Clone this repository.
|
||||
|
||||
@@ -23,3 +23,7 @@ Report security bugs in third-party modules to the person or team maintaining th
|
||||
We aim to patch confirmed vulnerabilities within 90 days or less, disclosing the details of those vulnerabilities when a patch is published. We ask that you refrain from sharing your report with others while we work on our patch.
|
||||
|
||||
We may want to coordinate an advisory with you to be published simultaneously with the patch, but you are also welcome to self-disclose after 90 days if you prefer. We will never publish information about you or our communications with you without your permission.
|
||||
|
||||
## Bounties
|
||||
|
||||
Everyone who works on shields is an unpaid volunteer. That includes the core team, contributors and people who report security vulnerabilities. This means we are unable to offer bug or security bounties.
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
exports['The badge generator SVG should match snapshot 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="90"
|
||||
height="20"
|
||||
role="img"
|
||||
@@ -61,7 +60,6 @@ exports['The badge generator SVG should match snapshot 1'] = `
|
||||
exports['The badge generator "flat" template badge generation should match snapshots: message/label, no logo 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="90"
|
||||
height="20"
|
||||
role="img"
|
||||
@@ -121,7 +119,6 @@ exports['The badge generator "flat" template badge generation should match snaps
|
||||
exports['The badge generator "flat" template badge generation should match snapshots: message/label, with logo 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="107"
|
||||
height="20"
|
||||
role="img"
|
||||
@@ -152,7 +149,7 @@ exports['The badge generator "flat" template badge generation should match snaps
|
||||
y="3"
|
||||
width="14"
|
||||
height="14"
|
||||
xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
/>
|
||||
<text
|
||||
aria-hidden="true"
|
||||
@@ -190,7 +187,6 @@ exports['The badge generator "flat" template badge generation should match snaps
|
||||
exports['The badge generator "flat" template badge generation should match snapshots: message only, no logo 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="45"
|
||||
height="20"
|
||||
role="img"
|
||||
@@ -236,7 +232,6 @@ exports['The badge generator "flat" template badge generation should match snaps
|
||||
exports['The badge generator "flat" template badge generation should match snapshots: message only, with logo 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="63"
|
||||
height="20"
|
||||
role="img"
|
||||
@@ -265,7 +260,7 @@ exports['The badge generator "flat" template badge generation should match snaps
|
||||
y="3"
|
||||
width="14"
|
||||
height="14"
|
||||
xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
/>
|
||||
<text
|
||||
aria-hidden="true"
|
||||
@@ -289,7 +284,6 @@ exports['The badge generator "flat" template badge generation should match snaps
|
||||
exports['The badge generator "flat" template badge generation should match snapshots: message only, with logo and labelColor 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="69"
|
||||
height="20"
|
||||
role="img"
|
||||
@@ -318,7 +312,7 @@ exports['The badge generator "flat" template badge generation should match snaps
|
||||
y="3"
|
||||
width="14"
|
||||
height="14"
|
||||
xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
/>
|
||||
<text
|
||||
aria-hidden="true"
|
||||
@@ -340,12 +334,7 @@ exports['The badge generator "flat" template badge generation should match snaps
|
||||
`
|
||||
|
||||
exports['The badge generator "flat" template badge generation should match snapshots: message/label, with links 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="90"
|
||||
height="20"
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="90" height="20">
|
||||
<linearGradient id="s" x2="0" y2="100%">
|
||||
<stop offset="0" stop-color="#bbb" stop-opacity=".1" />
|
||||
<stop offset="1" stop-opacity=".1" />
|
||||
@@ -363,7 +352,7 @@ exports['The badge generator "flat" template badge generation should match snaps
|
||||
text-rendering="geometricPrecision"
|
||||
font-size="110"
|
||||
>
|
||||
<a target="_blank" xlink:href="https://shields.io/">
|
||||
<a target="_blank" href="https://shields.io/">
|
||||
<rect width="45" x="0" height="20" fill="rgba(0,0,0,0)" />
|
||||
<text
|
||||
aria-hidden="true"
|
||||
@@ -380,7 +369,7 @@ exports['The badge generator "flat" template badge generation should match snaps
|
||||
cactus
|
||||
</text>
|
||||
</a>
|
||||
<a target="_blank" xlink:href="https://www.google.co.uk/">
|
||||
<a target="_blank" href="https://www.google.co.uk/">
|
||||
<rect width="45" x="45" height="20" fill="rgba(0,0,0,0)" />
|
||||
<text
|
||||
aria-hidden="true"
|
||||
@@ -405,7 +394,6 @@ exports['The badge generator "flat" template badge generation should match snaps
|
||||
exports['The badge generator "flat" template badge generation should match snapshots: black text when the label color is light 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="90"
|
||||
height="20"
|
||||
role="img"
|
||||
@@ -465,7 +453,6 @@ exports['The badge generator "flat" template badge generation should match snaps
|
||||
exports['The badge generator "flat" template badge generation should match snapshots: black text when the message color is light 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="90"
|
||||
height="20"
|
||||
role="img"
|
||||
@@ -525,7 +512,6 @@ exports['The badge generator "flat" template badge generation should match snaps
|
||||
exports['The badge generator "flat-square" template badge generation should match snapshots: message/label, no logo 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="90"
|
||||
height="20"
|
||||
role="img"
|
||||
@@ -557,7 +543,6 @@ exports['The badge generator "flat-square" template badge generation should matc
|
||||
exports['The badge generator "flat-square" template badge generation should match snapshots: message/label, with logo 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="107"
|
||||
height="20"
|
||||
role="img"
|
||||
@@ -580,7 +565,7 @@ exports['The badge generator "flat-square" template badge generation should matc
|
||||
y="3"
|
||||
width="14"
|
||||
height="14"
|
||||
xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
/>
|
||||
<text x="405" y="140" transform="scale(.1)" fill="#fff" textLength="350">
|
||||
cactus
|
||||
@@ -596,7 +581,6 @@ exports['The badge generator "flat-square" template badge generation should matc
|
||||
exports['The badge generator "flat-square" template badge generation should match snapshots: message only, no logo 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="45"
|
||||
height="20"
|
||||
role="img"
|
||||
@@ -625,7 +609,6 @@ exports['The badge generator "flat-square" template badge generation should matc
|
||||
exports['The badge generator "flat-square" template badge generation should match snapshots: message only, with logo 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="63"
|
||||
height="20"
|
||||
role="img"
|
||||
@@ -648,7 +631,7 @@ exports['The badge generator "flat-square" template badge generation should matc
|
||||
y="3"
|
||||
width="14"
|
||||
height="14"
|
||||
xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
/>
|
||||
<text x="405" y="140" transform="scale(.1)" fill="#fff" textLength="350">
|
||||
grown
|
||||
@@ -661,7 +644,6 @@ exports['The badge generator "flat-square" template badge generation should matc
|
||||
exports['The badge generator "flat-square" template badge generation should match snapshots: message only, with logo and labelColor 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="69"
|
||||
height="20"
|
||||
role="img"
|
||||
@@ -684,7 +666,7 @@ exports['The badge generator "flat-square" template badge generation should matc
|
||||
y="3"
|
||||
width="14"
|
||||
height="14"
|
||||
xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
/>
|
||||
<text x="455" y="140" transform="scale(.1)" fill="#fff" textLength="350">
|
||||
grown
|
||||
@@ -695,12 +677,7 @@ exports['The badge generator "flat-square" template badge generation should matc
|
||||
`
|
||||
|
||||
exports['The badge generator "flat-square" template badge generation should match snapshots: message/label, with links 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="90"
|
||||
height="20"
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="90" height="20">
|
||||
<g shape-rendering="crispEdges">
|
||||
<rect width="45" height="20" fill="#0f0" />
|
||||
<rect x="45" width="45" height="20" fill="#b3e" />
|
||||
@@ -712,13 +689,13 @@ exports['The badge generator "flat-square" template badge generation should matc
|
||||
text-rendering="geometricPrecision"
|
||||
font-size="110"
|
||||
>
|
||||
<a target="_blank" xlink:href="https://shields.io/">
|
||||
<a target="_blank" href="https://shields.io/">
|
||||
<rect width="45" x="0" height="20" fill="rgba(0,0,0,0)" />
|
||||
<text x="235" y="140" transform="scale(.1)" fill="#fff" textLength="350">
|
||||
cactus
|
||||
</text>
|
||||
</a>
|
||||
<a target="_blank" xlink:href="https://www.google.co.uk/">
|
||||
<a target="_blank" href="https://www.google.co.uk/">
|
||||
<rect width="45" x="45" height="20" fill="rgba(0,0,0,0)" />
|
||||
<text x="665" y="140" transform="scale(.1)" fill="#fff" textLength="350">
|
||||
grown
|
||||
@@ -732,7 +709,6 @@ exports['The badge generator "flat-square" template badge generation should matc
|
||||
exports['The badge generator "flat-square" template badge generation should match snapshots: black text when the label color is light 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="90"
|
||||
height="20"
|
||||
role="img"
|
||||
@@ -764,7 +740,6 @@ exports['The badge generator "flat-square" template badge generation should matc
|
||||
exports['The badge generator "flat-square" template badge generation should match snapshots: black text when the message color is light 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="90"
|
||||
height="20"
|
||||
role="img"
|
||||
@@ -796,7 +771,6 @@ exports['The badge generator "flat-square" template badge generation should matc
|
||||
exports['The badge generator "plastic" template badge generation should match snapshots: message/label, no logo 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="90"
|
||||
height="18"
|
||||
role="img"
|
||||
@@ -858,7 +832,6 @@ exports['The badge generator "plastic" template badge generation should match sn
|
||||
exports['The badge generator "plastic" template badge generation should match snapshots: message/label, with logo 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="107"
|
||||
height="18"
|
||||
role="img"
|
||||
@@ -891,7 +864,7 @@ exports['The badge generator "plastic" template badge generation should match sn
|
||||
y="2"
|
||||
width="14"
|
||||
height="14"
|
||||
xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
/>
|
||||
<text
|
||||
aria-hidden="true"
|
||||
@@ -929,7 +902,6 @@ exports['The badge generator "plastic" template badge generation should match sn
|
||||
exports['The badge generator "plastic" template badge generation should match snapshots: message only, no logo 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="45"
|
||||
height="18"
|
||||
role="img"
|
||||
@@ -977,7 +949,6 @@ exports['The badge generator "plastic" template badge generation should match sn
|
||||
exports['The badge generator "plastic" template badge generation should match snapshots: message only, with logo 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="63"
|
||||
height="18"
|
||||
role="img"
|
||||
@@ -1008,7 +979,7 @@ exports['The badge generator "plastic" template badge generation should match sn
|
||||
y="2"
|
||||
width="14"
|
||||
height="14"
|
||||
xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
/>
|
||||
<text
|
||||
aria-hidden="true"
|
||||
@@ -1032,7 +1003,6 @@ exports['The badge generator "plastic" template badge generation should match sn
|
||||
exports['The badge generator "plastic" template badge generation should match snapshots: message only, with logo and labelColor 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="69"
|
||||
height="18"
|
||||
role="img"
|
||||
@@ -1063,7 +1033,7 @@ exports['The badge generator "plastic" template badge generation should match sn
|
||||
y="2"
|
||||
width="14"
|
||||
height="14"
|
||||
xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
/>
|
||||
<text
|
||||
aria-hidden="true"
|
||||
@@ -1085,12 +1055,7 @@ exports['The badge generator "plastic" template badge generation should match sn
|
||||
`
|
||||
|
||||
exports['The badge generator "plastic" template badge generation should match snapshots: message/label, with links 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="90"
|
||||
height="18"
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="90" height="18">
|
||||
<linearGradient id="s" x2="0" y2="100%">
|
||||
<stop offset="0" stop-color="#fff" stop-opacity=".7" />
|
||||
<stop offset=".1" stop-color="#aaa" stop-opacity=".1" />
|
||||
@@ -1110,7 +1075,7 @@ exports['The badge generator "plastic" template badge generation should match sn
|
||||
text-rendering="geometricPrecision"
|
||||
font-size="110"
|
||||
>
|
||||
<a target="_blank" xlink:href="https://shields.io/">
|
||||
<a target="_blank" href="https://shields.io/">
|
||||
<rect width="45" x="0" height="18" fill="rgba(0,0,0,0)" />
|
||||
<text
|
||||
aria-hidden="true"
|
||||
@@ -1127,7 +1092,7 @@ exports['The badge generator "plastic" template badge generation should match sn
|
||||
cactus
|
||||
</text>
|
||||
</a>
|
||||
<a target="_blank" xlink:href="https://www.google.co.uk/">
|
||||
<a target="_blank" href="https://www.google.co.uk/">
|
||||
<rect width="45" x="45" height="18" fill="rgba(0,0,0,0)" />
|
||||
<text
|
||||
aria-hidden="true"
|
||||
@@ -1152,7 +1117,6 @@ exports['The badge generator "plastic" template badge generation should match sn
|
||||
exports['The badge generator "plastic" template badge generation should match snapshots: black text when the label color is light 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="90"
|
||||
height="18"
|
||||
role="img"
|
||||
@@ -1214,7 +1178,6 @@ exports['The badge generator "plastic" template badge generation should match sn
|
||||
exports['The badge generator "plastic" template badge generation should match snapshots: black text when the message color is light 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="90"
|
||||
height="18"
|
||||
role="img"
|
||||
@@ -1276,7 +1239,6 @@ exports['The badge generator "plastic" template badge generation should match sn
|
||||
exports['The badge generator "for-the-badge" template badge generation should match snapshots: message/label, no logo 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="146.75"
|
||||
height="28"
|
||||
role="img"
|
||||
@@ -1315,7 +1277,6 @@ exports['The badge generator "for-the-badge" template badge generation should ma
|
||||
exports['The badge generator "for-the-badge" template badge generation should match snapshots: message/label, with logo 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="163.75"
|
||||
height="28"
|
||||
role="img"
|
||||
@@ -1338,7 +1299,7 @@ exports['The badge generator "for-the-badge" template badge generation should ma
|
||||
y="7"
|
||||
width="14"
|
||||
height="14"
|
||||
xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
/>
|
||||
<text transform="scale(.1)" x="532.5" y="175" textLength="485" fill="#fff">
|
||||
CACTUS
|
||||
@@ -1361,7 +1322,6 @@ exports['The badge generator "for-the-badge" template badge generation should ma
|
||||
exports['The badge generator "for-the-badge" template badge generation should match snapshots: message only, no logo 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="74.25"
|
||||
height="28"
|
||||
role="img"
|
||||
@@ -1396,7 +1356,6 @@ exports['The badge generator "for-the-badge" template badge generation should ma
|
||||
exports['The badge generator "for-the-badge" template badge generation should match snapshots: message only, with logo 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="94.25"
|
||||
height="28"
|
||||
role="img"
|
||||
@@ -1418,7 +1377,7 @@ exports['The badge generator "for-the-badge" template badge generation should ma
|
||||
y="7"
|
||||
width="14"
|
||||
height="14"
|
||||
xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
/>
|
||||
<text
|
||||
transform="scale(.1)"
|
||||
@@ -1438,7 +1397,6 @@ exports['The badge generator "for-the-badge" template badge generation should ma
|
||||
exports['The badge generator "for-the-badge" template badge generation should match snapshots: message only, with logo and labelColor 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="106.25"
|
||||
height="28"
|
||||
role="img"
|
||||
@@ -1461,7 +1419,7 @@ exports['The badge generator "for-the-badge" template badge generation should ma
|
||||
y="7"
|
||||
width="14"
|
||||
height="14"
|
||||
xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
/>
|
||||
<text
|
||||
transform="scale(.1)"
|
||||
@@ -1479,12 +1437,7 @@ exports['The badge generator "for-the-badge" template badge generation should ma
|
||||
`
|
||||
|
||||
exports['The badge generator "for-the-badge" template badge generation should match snapshots: message/label, with links 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="146.75"
|
||||
height="28"
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="146.75" height="28">
|
||||
<g shape-rendering="crispEdges">
|
||||
<rect width="72.5" height="28" fill="#0f0" />
|
||||
<rect x="72.5" width="74.25" height="28" fill="#b3e" />
|
||||
@@ -1496,7 +1449,7 @@ exports['The badge generator "for-the-badge" template badge generation should ma
|
||||
text-rendering="geometricPrecision"
|
||||
font-size="100"
|
||||
>
|
||||
<a target="_blank" xlink:href="https://shields.io/">
|
||||
<a target="_blank" href="https://shields.io/">
|
||||
<rect width="72.5" height="28" fill="rgba(0,0,0,0)" />
|
||||
<text
|
||||
transform="scale(.1)"
|
||||
@@ -1508,7 +1461,7 @@ exports['The badge generator "for-the-badge" template badge generation should ma
|
||||
CACTUS
|
||||
</text>
|
||||
</a>
|
||||
<a target="_blank" xlink:href="https://www.google.co.uk/">
|
||||
<a target="_blank" href="https://www.google.co.uk/">
|
||||
<rect width="74.25" height="28" x="72.5" fill="rgba(0,0,0,0)" />
|
||||
<text
|
||||
transform="scale(.1)"
|
||||
@@ -1529,7 +1482,6 @@ exports['The badge generator "for-the-badge" template badge generation should ma
|
||||
exports['The badge generator "for-the-badge" template badge generation should match snapshots: black text when the label color is light 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="146.75"
|
||||
height="28"
|
||||
role="img"
|
||||
@@ -1568,7 +1520,6 @@ exports['The badge generator "for-the-badge" template badge generation should ma
|
||||
exports['The badge generator "for-the-badge" template badge generation should match snapshots: black text when the message color is light 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="146.75"
|
||||
height="28"
|
||||
role="img"
|
||||
@@ -1607,7 +1558,6 @@ exports['The badge generator "for-the-badge" template badge generation should ma
|
||||
exports['The badge generator "social" template badge generation should match snapshots: message/label, no logo 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="95"
|
||||
height="20"
|
||||
role="img"
|
||||
@@ -1697,7 +1647,6 @@ exports['The badge generator "social" template badge generation should match sna
|
||||
exports['The badge generator "social" template badge generation should match snapshots: message/label, with logo 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="112"
|
||||
height="20"
|
||||
role="img"
|
||||
@@ -1740,7 +1689,7 @@ exports['The badge generator "social" template badge generation should match sna
|
||||
y="3"
|
||||
width="14"
|
||||
height="14"
|
||||
xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
/>
|
||||
<g
|
||||
aria-hidden="true"
|
||||
@@ -1794,7 +1743,6 @@ exports['The badge generator "social" template badge generation should match sna
|
||||
exports['The badge generator "social" template badge generation should match snapshots: message only, no logo 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="59"
|
||||
height="20"
|
||||
role="img"
|
||||
@@ -1882,7 +1830,6 @@ exports['The badge generator "social" template badge generation should match sna
|
||||
exports['The badge generator "social" template badge generation should match snapshots: message only, with logo 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="73"
|
||||
height="20"
|
||||
role="img"
|
||||
@@ -1925,7 +1872,7 @@ exports['The badge generator "social" template badge generation should match sna
|
||||
y="3"
|
||||
width="14"
|
||||
height="14"
|
||||
xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
/>
|
||||
<g
|
||||
aria-hidden="true"
|
||||
@@ -1977,7 +1924,6 @@ exports['The badge generator "social" template badge generation should match sna
|
||||
exports['The badge generator "social" template badge generation should match snapshots: message only, with logo and labelColor 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="73"
|
||||
height="20"
|
||||
role="img"
|
||||
@@ -2020,7 +1966,7 @@ exports['The badge generator "social" template badge generation should match sna
|
||||
y="3"
|
||||
width="14"
|
||||
height="14"
|
||||
xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
/>
|
||||
<g
|
||||
aria-hidden="true"
|
||||
@@ -2070,12 +2016,7 @@ exports['The badge generator "social" template badge generation should match sna
|
||||
`
|
||||
|
||||
exports['The badge generator "social" template badge generation should match snapshots: message/label, with links 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="95"
|
||||
height="20"
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="95" height="20">
|
||||
<style>
|
||||
a:hover #llink {
|
||||
fill: url(#b);
|
||||
@@ -2117,7 +2058,7 @@ exports['The badge generator "social" template badge generation should match sna
|
||||
font-size="110px"
|
||||
line-height="14px"
|
||||
>
|
||||
<a target="_blank" xlink:href="https://shields.io/">
|
||||
<a target="_blank" href="https://shields.io/">
|
||||
<text
|
||||
aria-hidden="true"
|
||||
x="235"
|
||||
@@ -2140,7 +2081,7 @@ exports['The badge generator "social" template badge generation should match sna
|
||||
rx="2"
|
||||
/>
|
||||
</a>
|
||||
<a target="_blank" xlink:href="https://www.google.co.uk/">
|
||||
<a target="_blank" href="https://www.google.co.uk/">
|
||||
<rect width="42" x="53" height="20" fill="rgba(0,0,0,0)" />
|
||||
<text
|
||||
aria-hidden="true"
|
||||
@@ -2164,7 +2105,6 @@ exports['The badge generator "social" template badge generation should match sna
|
||||
exports['The badge generator "flat" template badge generation should match snapshots: message with custom suffix 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="107"
|
||||
height="20"
|
||||
role="img"
|
||||
@@ -2195,7 +2135,7 @@ exports['The badge generator "flat" template badge generation should match snaps
|
||||
y="3"
|
||||
width="14"
|
||||
height="14"
|
||||
xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
/>
|
||||
<text
|
||||
aria-hidden="true"
|
||||
@@ -2233,7 +2173,6 @@ exports['The badge generator "flat" template badge generation should match snaps
|
||||
exports['The badge generator "flat-square" template badge generation should match snapshots: message with custom suffix 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="107"
|
||||
height="20"
|
||||
role="img"
|
||||
@@ -2256,7 +2195,7 @@ exports['The badge generator "flat-square" template badge generation should matc
|
||||
y="3"
|
||||
width="14"
|
||||
height="14"
|
||||
xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
/>
|
||||
<text x="405" y="140" transform="scale(.1)" fill="#fff" textLength="350">
|
||||
cactus
|
||||
@@ -2272,7 +2211,6 @@ exports['The badge generator "flat-square" template badge generation should matc
|
||||
exports['The badge generator "plastic" template badge generation should match snapshots: message with custom suffix 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="107"
|
||||
height="18"
|
||||
role="img"
|
||||
@@ -2305,7 +2243,7 @@ exports['The badge generator "plastic" template badge generation should match sn
|
||||
y="2"
|
||||
width="14"
|
||||
height="14"
|
||||
xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
/>
|
||||
<text
|
||||
aria-hidden="true"
|
||||
@@ -2343,7 +2281,6 @@ exports['The badge generator "plastic" template badge generation should match sn
|
||||
exports['The badge generator "for-the-badge" template badge generation should match snapshots: message with custom suffix 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="163.75"
|
||||
height="28"
|
||||
role="img"
|
||||
@@ -2366,7 +2303,7 @@ exports['The badge generator "for-the-badge" template badge generation should ma
|
||||
y="7"
|
||||
width="14"
|
||||
height="14"
|
||||
xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
/>
|
||||
<text transform="scale(.1)" x="532.5" y="175" textLength="485" fill="#fff">
|
||||
CACTUS
|
||||
@@ -2389,7 +2326,6 @@ exports['The badge generator "for-the-badge" template badge generation should ma
|
||||
exports['The badge generator "social" template badge generation should match snapshots: message with custom suffix 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="112"
|
||||
height="20"
|
||||
role="img"
|
||||
@@ -2432,7 +2368,7 @@ exports['The badge generator "social" template badge generation should match sna
|
||||
y="3"
|
||||
width="14"
|
||||
height="14"
|
||||
xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
/>
|
||||
<g
|
||||
aria-hidden="true"
|
||||
@@ -2486,7 +2422,6 @@ exports['The badge generator "social" template badge generation should match sna
|
||||
exports['The badge generator badges with logos should always produce the same badge default badge with logo 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="113"
|
||||
height="20"
|
||||
role="img"
|
||||
@@ -2517,7 +2452,7 @@ exports['The badge generator badges with logos should always produce the same ba
|
||||
y="3"
|
||||
width="14"
|
||||
height="14"
|
||||
xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
/>
|
||||
<text
|
||||
aria-hidden="true"
|
||||
@@ -2555,7 +2490,6 @@ exports['The badge generator badges with logos should always produce the same ba
|
||||
exports['The badge generator badges with logo-only should always produce the same badge flat badge, logo-only 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="25"
|
||||
height="20"
|
||||
role="img"
|
||||
@@ -2584,7 +2518,7 @@ exports['The badge generator badges with logo-only should always produce the sam
|
||||
y="3"
|
||||
width="14"
|
||||
height="14"
|
||||
xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
@@ -2594,7 +2528,6 @@ exports['The badge generator badges with logo-only should always produce the sam
|
||||
exports['The badge generator badges with logo-only should always produce the same badge flat-square badge, logo-only 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="25"
|
||||
height="20"
|
||||
role="img"
|
||||
@@ -2617,7 +2550,7 @@ exports['The badge generator badges with logo-only should always produce the sam
|
||||
y="3"
|
||||
width="14"
|
||||
height="14"
|
||||
xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
@@ -2627,7 +2560,6 @@ exports['The badge generator badges with logo-only should always produce the sam
|
||||
exports['The badge generator badges with logo-only should always produce the same badge social badge, logo-only 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="26"
|
||||
height="20"
|
||||
role="img"
|
||||
@@ -2667,7 +2599,7 @@ exports['The badge generator badges with logo-only should always produce the sam
|
||||
y="3"
|
||||
width="14"
|
||||
height="14"
|
||||
xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
/>
|
||||
<g
|
||||
aria-hidden="true"
|
||||
@@ -2706,7 +2638,6 @@ exports['The badge generator badges with logo-only should always produce the sam
|
||||
exports['The badge generator badges with logo-only should always produce the same badge plastic badge, logo-only 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="25"
|
||||
height="18"
|
||||
role="img"
|
||||
@@ -2737,7 +2668,7 @@ exports['The badge generator badges with logo-only should always produce the sam
|
||||
y="2"
|
||||
width="14"
|
||||
height="14"
|
||||
xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
@@ -2747,7 +2678,6 @@ exports['The badge generator badges with logo-only should always produce the sam
|
||||
exports['The badge generator badges with logo-only should always produce the same badge for-the-badge badge, logo-only 1'] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="35"
|
||||
height="28"
|
||||
role="img"
|
||||
@@ -2769,7 +2699,7 @@ exports['The badge generator badges with logo-only should always produce the sam
|
||||
y="7"
|
||||
width="14"
|
||||
height="14"
|
||||
xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
href="data:image/svg+xml;base64,PHN2ZyB4bWxu"
|
||||
/>
|
||||
<text
|
||||
transform="scale(.1)"
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
# Changelog
|
||||
|
||||
## Unreleased
|
||||
|
||||
- Switching to using `href`s instead of the old `xlink:href` syntax
|
||||
|
||||
## 4.1.0
|
||||
|
||||
### Features
|
||||
|
||||
@@ -62,7 +62,7 @@ function getLogoElement({ logo, horizPadding, badgeHeight, logoWidth }) {
|
||||
y: 0.5 * (badgeHeight - logoHeight),
|
||||
width: logoWidth,
|
||||
height: logoHeight,
|
||||
'xlink:href': logo,
|
||||
href: logo,
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -83,13 +83,12 @@ function renderBadge(
|
||||
? new XmlElement({
|
||||
name: 'a',
|
||||
content,
|
||||
attrs: { target: '_blank', 'xlink:href': leftLink },
|
||||
attrs: { target: '_blank', href: leftLink },
|
||||
})
|
||||
: new ElementList({ content })
|
||||
|
||||
const svgAttrs = {
|
||||
xmlns: 'http://www.w3.org/2000/svg',
|
||||
'xmlns:xlink': 'http://www.w3.org/1999/xlink',
|
||||
width,
|
||||
height,
|
||||
}
|
||||
@@ -244,7 +243,7 @@ class Badge {
|
||||
return new XmlElement({
|
||||
name: 'a',
|
||||
content: [rect, shadow, text],
|
||||
attrs: { target: '_blank', 'xlink:href': link },
|
||||
attrs: { target: '_blank', href: link },
|
||||
})
|
||||
}
|
||||
|
||||
@@ -605,7 +604,7 @@ function social({
|
||||
? new XmlElement({
|
||||
name: 'a',
|
||||
content: [shadow, text, rect],
|
||||
attrs: { target: '_blank', 'xlink:href': leftLink },
|
||||
attrs: { target: '_blank', href: leftLink },
|
||||
})
|
||||
: new ElementList({ content: [rect, shadow, text] })
|
||||
}
|
||||
@@ -655,7 +654,7 @@ function social({
|
||||
? new XmlElement({
|
||||
name: 'a',
|
||||
content: [rect, shadow, text],
|
||||
attrs: { target: '_blank', 'xlink:href': rightLink },
|
||||
attrs: { target: '_blank', href: rightLink },
|
||||
})
|
||||
: new ElementList({ content: [shadow, text] })
|
||||
}
|
||||
@@ -869,7 +868,7 @@ function forTheBadge({
|
||||
content: [rect, text],
|
||||
attrs: {
|
||||
target: '_blank',
|
||||
'xlink:href': leftLink,
|
||||
href: leftLink,
|
||||
},
|
||||
})
|
||||
} else {
|
||||
@@ -908,7 +907,7 @@ function forTheBadge({
|
||||
content: [rect, text],
|
||||
attrs: {
|
||||
target: '_blank',
|
||||
'xlink:href': rightLink,
|
||||
href: rightLink,
|
||||
},
|
||||
})
|
||||
} else {
|
||||
|
||||
@@ -22,4 +22,4 @@ public:
|
||||
rasterUrl: 'https://raster.shields.io'
|
||||
userAgentBase: 'Shields.io'
|
||||
requireCloudflare: true
|
||||
requestTimeoutSeconds: 20
|
||||
requestTimeoutSeconds: 8
|
||||
|
||||
@@ -47,10 +47,6 @@ const optionalStringWhenNamedLogoPresent = Joi.alternatives().conditional(
|
||||
},
|
||||
)
|
||||
|
||||
const optionalNumberWhenAnyLogoPresent = Joi.alternatives()
|
||||
.conditional('namedLogo', { is: Joi.string().required(), then: Joi.number() })
|
||||
.conditional('logoSvg', { is: Joi.string().required(), then: Joi.number() })
|
||||
|
||||
const serviceDataSchema = Joi.object({
|
||||
isError: Joi.boolean(),
|
||||
label: Joi.string().allow(''),
|
||||
@@ -66,7 +62,6 @@ const serviceDataSchema = Joi.object({
|
||||
logoSvg: Joi.string(),
|
||||
logoColor: optionalStringWhenNamedLogoPresent,
|
||||
logoSize: optionalStringWhenNamedLogoPresent,
|
||||
logoWidth: optionalNumberWhenAnyLogoPresent,
|
||||
cacheSeconds: Joi.number().integer().min(0),
|
||||
style: Joi.string(),
|
||||
})
|
||||
@@ -155,12 +150,18 @@ class BaseService {
|
||||
static get _cacheLength() {
|
||||
const cacheLengths = {
|
||||
build: 30,
|
||||
license: 3600,
|
||||
version: 300,
|
||||
debug: 60,
|
||||
downloads: 900,
|
||||
rating: 900,
|
||||
social: 900,
|
||||
|
||||
'platform-support': 300,
|
||||
size: 300,
|
||||
version: 300,
|
||||
|
||||
chat: 1800,
|
||||
downloads: 1800,
|
||||
rating: 1800,
|
||||
social: 1800,
|
||||
|
||||
license: 14400,
|
||||
}
|
||||
return cacheLengths[this.category]
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import toArray from './to-array.js'
|
||||
// 1. When `?logo=` contains a simple-icons logo or contains a base64-encoded
|
||||
// SVG, that logo is used. When a `&logoColor=` is specified, that color is
|
||||
// used (except for the base64-encoded logos). Otherwise the default color
|
||||
// is used. The appearance of the logo can be customized using `logoWidth`,
|
||||
// is used.
|
||||
// When `?logo=` is specified, any logo-related parameters specified
|
||||
// dynamically by the service, or by default in the service, are ignored.
|
||||
// 2. The second precedence is the dynamic logo returned by a service. This is
|
||||
@@ -52,11 +52,7 @@ export default function coalesceBadge(
|
||||
colorB: legacyOverrideColor,
|
||||
colorA: legacyOverrideLabelColor,
|
||||
} = overrides
|
||||
let {
|
||||
logoWidth: overrideLogoWidth,
|
||||
color: overrideColor,
|
||||
labelColor: overrideLabelColor,
|
||||
} = overrides
|
||||
let { color: overrideColor, labelColor: overrideLabelColor } = overrides
|
||||
|
||||
// Only use the legacy properties if the new ones are not provided
|
||||
if (typeof overrideColor === 'undefined') {
|
||||
@@ -73,7 +69,6 @@ export default function coalesceBadge(
|
||||
if (typeof overrideLabelColor === 'number') {
|
||||
overrideLabelColor = `${overrideLabelColor}`
|
||||
}
|
||||
overrideLogoWidth = +overrideLogoWidth || undefined
|
||||
|
||||
const {
|
||||
isError,
|
||||
@@ -85,7 +80,6 @@ export default function coalesceBadge(
|
||||
namedLogo: serviceNamedLogo,
|
||||
logoColor: serviceLogoColor,
|
||||
logoSize: serviceLogoSize,
|
||||
logoWidth: serviceLogoWidth,
|
||||
link: serviceLink,
|
||||
cacheSeconds: serviceCacheSeconds,
|
||||
style: serviceStyle,
|
||||
@@ -131,7 +125,6 @@ export default function coalesceBadge(
|
||||
// If the logo has been overridden it does not make sense to inherit the
|
||||
// original width or position.
|
||||
logoSize = overrideLogoSize
|
||||
logoWidth = overrideLogoWidth
|
||||
} else {
|
||||
if (serviceLogoSvg) {
|
||||
logoSvgBase64 = svg2base64(serviceLogoSvg)
|
||||
@@ -143,12 +136,11 @@ export default function coalesceBadge(
|
||||
namedLogoColor = coalesce(overrideLogoColor, serviceLogoColor)
|
||||
}
|
||||
logoSize = coalesce(overrideLogoSize, serviceLogoSize)
|
||||
logoWidth = coalesce(overrideLogoWidth, serviceLogoWidth)
|
||||
}
|
||||
if (namedLogo) {
|
||||
const iconSize = getIconSize(String(namedLogo).toLowerCase())
|
||||
|
||||
if (!logoWidth && iconSize && logoSize === 'auto') {
|
||||
if (iconSize && logoSize === 'auto') {
|
||||
logoWidth = (iconSize.width / iconSize.height) * DEFAULT_LOGO_HEIGHT
|
||||
}
|
||||
|
||||
|
||||
@@ -185,7 +185,6 @@ describe('coalesceBadge', function () {
|
||||
{
|
||||
namedLogo: 'appveyor',
|
||||
logoColor: 'red',
|
||||
logoWidth: 100,
|
||||
},
|
||||
{},
|
||||
).logo,
|
||||
@@ -246,20 +245,6 @@ describe('coalesceBadge', function () {
|
||||
})
|
||||
})
|
||||
|
||||
describe('Logo width', function () {
|
||||
it('overrides the logoWidth', function () {
|
||||
expect(coalesceBadge({ logoWidth: 20 }, {}, {})).to.include({
|
||||
logoWidth: 20,
|
||||
})
|
||||
})
|
||||
|
||||
it('applies the logo width', function () {
|
||||
expect(
|
||||
coalesceBadge({}, { namedLogo: 'npm', logoWidth: 275 }, {}),
|
||||
).to.include({ logoWidth: 275 })
|
||||
})
|
||||
})
|
||||
|
||||
describe('Links', function () {
|
||||
it('overrides the links', function () {
|
||||
expect(
|
||||
|
||||
@@ -12,7 +12,6 @@ const globalQueryParams = new Set([
|
||||
'logo',
|
||||
'logoColor',
|
||||
'logoSize',
|
||||
'logoWidth',
|
||||
'link',
|
||||
'colorA',
|
||||
'colorB',
|
||||
|
||||
@@ -119,7 +119,7 @@ describe('The server', function () {
|
||||
)
|
||||
expect(statusCode).to.equal(200)
|
||||
expect(headers['content-type']).to.equal('image/svg+xml;charset=utf-8')
|
||||
expect(headers['content-length']).to.equal('1130')
|
||||
expect(headers['content-length']).to.equal('1087')
|
||||
})
|
||||
|
||||
it('correctly calculates the content-length header for multi-byte unicode characters', async function () {
|
||||
|
||||
@@ -224,6 +224,7 @@ const config = [
|
||||
'badge-maker/node_modules/',
|
||||
'!.github/',
|
||||
'frontend/.docusaurus/**',
|
||||
'**/package.json',
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
@@ -115,7 +115,11 @@ const config = {
|
||||
title: 'Stats',
|
||||
items: [
|
||||
{
|
||||
label: 'Service Status',
|
||||
label: 'Service Status (Upptime)',
|
||||
href: 'https://badges.github.io/uptime-monitoring/',
|
||||
},
|
||||
{
|
||||
label: 'Service Status (NodePing)',
|
||||
href: 'https://nodeping.com/reports/status/YBISBQB254',
|
||||
},
|
||||
{
|
||||
|
||||
@@ -59,8 +59,6 @@ const FeatureList = [
|
||||
>
|
||||
docker image
|
||||
</a>
|
||||
<br />
|
||||
<code>docker pull shieldsio/shields</code>
|
||||
</>
|
||||
),
|
||||
},
|
||||
|
||||
@@ -83,20 +83,20 @@ describe('Logo helpers', function () {
|
||||
})
|
||||
|
||||
it('preserves color if medium logo on dark background', function () {
|
||||
const logo = prepareNamedLogo({ name: 'android' })
|
||||
const logo = prepareNamedLogo({ name: 'mastodon' })
|
||||
const decodedLogo = Buffer.from(
|
||||
logo.replace('data:image/svg+xml;base64,', ''),
|
||||
'base64',
|
||||
).toString('ascii')
|
||||
expect(decodedLogo).to.contain('fill="#34A853"')
|
||||
expect(decodedLogo).to.contain('fill="#6364FF"')
|
||||
})
|
||||
it('preserves color if medium logo on light background', function () {
|
||||
const logo = prepareNamedLogo({ name: 'android', style: 'social' })
|
||||
const logo = prepareNamedLogo({ name: 'mastodon', style: 'social' })
|
||||
const decodedLogo = Buffer.from(
|
||||
logo.replace('data:image/svg+xml;base64,', ''),
|
||||
'base64',
|
||||
).toString('ascii')
|
||||
expect(decodedLogo).to.contain('fill="#34A853"')
|
||||
expect(decodedLogo).to.contain('fill="#6364FF"')
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
1346
package-lock.json
generated
1346
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
69
package.json
69
package.json
@@ -21,11 +21,11 @@
|
||||
"url": "https://github.com/badges/shields"
|
||||
},
|
||||
"dependencies": {
|
||||
"@renovatebot/pep440": "^4.0.1",
|
||||
"@renovatebot/pep440": "^4.1.0",
|
||||
"@renovatebot/ruby-semver": "^4.0.0",
|
||||
"@sentry/node": "^8.53.0",
|
||||
"@sentry/node": "^9.10.0",
|
||||
"@shields_io/camp": "^18.1.2",
|
||||
"@xmldom/xmldom": "0.9.7",
|
||||
"@xmldom/xmldom": "0.9.8",
|
||||
"badge-maker": "file:badge-maker",
|
||||
"byte-size": "^9.0.1",
|
||||
"bytes": "^3.1.2",
|
||||
@@ -37,33 +37,33 @@
|
||||
"cross-env": "^7.0.3",
|
||||
"dayjs": "^1.11.13",
|
||||
"decamelize": "^3.2.0",
|
||||
"emojic": "^1.1.17",
|
||||
"emojic": "^1.1.18",
|
||||
"escape-string-regexp": "^4.0.0",
|
||||
"fast-xml-parser": "^4.5.1",
|
||||
"fast-xml-parser": "^5.0.9",
|
||||
"glob": "^11.0.1",
|
||||
"global-agent": "^3.0.0",
|
||||
"got": "^14.4.5",
|
||||
"got": "^14.4.6",
|
||||
"graphql": "16.10.0",
|
||||
"graphql-tag": "^2.12.6",
|
||||
"joi": "17.13.3",
|
||||
"joi-extension-semver": "5.0.0",
|
||||
"js-yaml": "^4.1.0",
|
||||
"jsonpath-plus": "^10.2.0",
|
||||
"jsonpath-plus": "^10.3.0",
|
||||
"lodash.countby": "^4.6.0",
|
||||
"lodash.groupby": "^4.6.0",
|
||||
"lodash.times": "^4.3.2",
|
||||
"matcher": "^5.0.0",
|
||||
"node-env-flag": "^0.1.0",
|
||||
"node-pg-migrate": "^7.9.0",
|
||||
"node-pg-migrate": "^7.9.1",
|
||||
"parse-link-header": "^2.0.0",
|
||||
"path-to-regexp": "^6.3.0",
|
||||
"pg": "^8.13.1",
|
||||
"pg": "^8.14.1",
|
||||
"priorityqueuejs": "^2.0.0",
|
||||
"prom-client": "^15.1.3",
|
||||
"qs": "^6.14.0",
|
||||
"query-string": "^9.1.1",
|
||||
"semver": "~7.7.0",
|
||||
"simple-icons": "14.4.0",
|
||||
"semver": "~7.7.1",
|
||||
"simple-icons": "14.11.1",
|
||||
"smol-toml": "1.3.1",
|
||||
"svg-path-bbox": "^2.1.0",
|
||||
"svgpath": "^2.6.0",
|
||||
@@ -134,7 +134,7 @@
|
||||
},
|
||||
"nodemonConfig": {
|
||||
"verbose": true,
|
||||
"ext": "js",
|
||||
"ext": "js,yml",
|
||||
"ignore": [
|
||||
"package.json",
|
||||
"**/*.spec.js",
|
||||
@@ -142,77 +142,78 @@
|
||||
"**/*.integration.js",
|
||||
"frontend/",
|
||||
"build/",
|
||||
"cypress/"
|
||||
"cypress/",
|
||||
".github/"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@docusaurus/core": "^3.7.0",
|
||||
"@docusaurus/preset-classic": "^3.7.0",
|
||||
"@easyops-cn/docusaurus-search-local": "^0.48.4",
|
||||
"@easyops-cn/docusaurus-search-local": "^0.49.1",
|
||||
"@mdx-js/react": "^3.1.0",
|
||||
"@typescript-eslint/parser": "^8.22.0",
|
||||
"@typescript-eslint/parser": "^8.28.0",
|
||||
"c8": "^10.1.3",
|
||||
"caller": "^1.1.0",
|
||||
"chai": "5.1.2",
|
||||
"chai": "5.2.0",
|
||||
"chai-as-promised": "^8.0.1",
|
||||
"chai-datetime": "^1.8.1",
|
||||
"child-process-promise": "^2.2.1",
|
||||
"clsx": "^2.1.1",
|
||||
"concurrently": "^9.1.2",
|
||||
"cypress": "^14.0.1",
|
||||
"cypress": "^14.2.1",
|
||||
"cypress-wait-for-stable-dom": "^0.1.0",
|
||||
"danger": "^12.3.3",
|
||||
"danger": "^12.3.4",
|
||||
"deepmerge": "^4.3.1",
|
||||
"docusaurus-preset-openapi": "0.7.6",
|
||||
"eslint": "9.19.0",
|
||||
"eslint-config-prettier": "^10.0.1",
|
||||
"eslint": "9.23.0",
|
||||
"eslint-config-prettier": "^10.1.1",
|
||||
"eslint-plugin-chai-friendly": "1.0.1",
|
||||
"eslint-plugin-cypress": "4.1.0",
|
||||
"eslint-plugin-cypress": "4.2.0",
|
||||
"eslint-plugin-icedfrisby": "0.2.0",
|
||||
"eslint-plugin-import": "2.31.0",
|
||||
"eslint-plugin-jsdoc": "50.6.3",
|
||||
"eslint-plugin-jsdoc": "50.6.9",
|
||||
"eslint-plugin-mocha": "10.5.0",
|
||||
"eslint-plugin-prettier": "5.2.3",
|
||||
"eslint-plugin-prettier": "5.2.5",
|
||||
"eslint-plugin-promise": "7.2.1",
|
||||
"eslint-plugin-react-hooks": "5.1.0",
|
||||
"eslint-plugin-react-hooks": "5.2.0",
|
||||
"eslint-plugin-sort-class-members": "1.21.0",
|
||||
"form-data": "^4.0.1",
|
||||
"globals": "15.14.0",
|
||||
"form-data": "^4.0.2",
|
||||
"globals": "16.0.0",
|
||||
"icedfrisby": "4.0.0",
|
||||
"icedfrisby-nock": "^2.1.0",
|
||||
"is-svg": "^5.1.0",
|
||||
"jsdoc": "^4.0.4",
|
||||
"lint-staged": "^15.4.3",
|
||||
"lint-staged": "^15.5.0",
|
||||
"lodash.difference": "^4.5.0",
|
||||
"minimist": "^1.2.8",
|
||||
"mocha": "^11.1.0",
|
||||
"mocha-env-reporter": "^4.0.0",
|
||||
"mocha-junit-reporter": "^2.2.1",
|
||||
"mocha-yaml-loader": "^1.0.3",
|
||||
"neostandard": "0.12.0",
|
||||
"neostandard": "0.12.1",
|
||||
"nock": "13.5.6",
|
||||
"node-mocks-http": "^1.16.2",
|
||||
"nodemon": "^3.1.9",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"open-cli": "^8.0.0",
|
||||
"portfinder": "^1.0.32",
|
||||
"prettier": "3.4.2",
|
||||
"portfinder": "^1.0.35",
|
||||
"prettier": "3.5.3",
|
||||
"prism-react-renderer": "^2.4.1",
|
||||
"react": "^18.3.0",
|
||||
"react-dom": "^18.3.1",
|
||||
"read-all-stdin-sync": "^1.0.5",
|
||||
"rimraf": "^6.0.1",
|
||||
"sazerac": "^2.0.0",
|
||||
"simple-git-hooks": "^2.11.1",
|
||||
"sinon": "^19.0.2",
|
||||
"simple-git-hooks": "^2.12.1",
|
||||
"sinon": "^20.0.0",
|
||||
"sinon-chai": "4.0.0",
|
||||
"snap-shot-it": "^7.9.10",
|
||||
"start-server-and-test": "2.0.10",
|
||||
"start-server-and-test": "2.0.11",
|
||||
"tsd": "^0.31.2",
|
||||
"url": "^0.11.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^20.10.0",
|
||||
"node": "^20 || ^22",
|
||||
"npm": "^9 || ^10 || ^11"
|
||||
},
|
||||
"type": "module",
|
||||
|
||||
@@ -62,4 +62,9 @@ if (fs.existsSync(legacySecretsPath)) {
|
||||
}
|
||||
export const server = new Server(config)
|
||||
|
||||
process.on('SIGTERM', async () => {
|
||||
console.log('SIGTERM received, shutting down...')
|
||||
await server.stop()
|
||||
})
|
||||
|
||||
await server.start()
|
||||
|
||||
46
services/ansible/ansible-collection-downloads.service.js
Normal file
46
services/ansible/ansible-collection-downloads.service.js
Normal file
@@ -0,0 +1,46 @@
|
||||
import Joi from 'joi'
|
||||
import { renderDownloadsBadge } from '../downloads.js'
|
||||
import { BaseJsonService, pathParams } from '../index.js'
|
||||
|
||||
const ansibleCollectionSchema = Joi.object({
|
||||
// Ansible docs don't mention this but it appears in the API responses
|
||||
download_count: Joi.number().required(),
|
||||
}).required()
|
||||
|
||||
export default class AnsibleGalaxyCollectionDownloads extends BaseJsonService {
|
||||
static category = 'downloads'
|
||||
static route = { base: 'ansible/collection/d', pattern: ':namespace/:name' }
|
||||
|
||||
static openApi = {
|
||||
'/ansible/collection/d/{namespace}/{name}': {
|
||||
get: {
|
||||
summary: 'Ansible Collection Downloads',
|
||||
parameters: pathParams(
|
||||
{ name: 'namespace', example: 'community' },
|
||||
{ name: 'name', example: 'general' },
|
||||
),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
static defaultBadgeData = { label: 'collection downloads' }
|
||||
|
||||
static render({ downloads }) {
|
||||
return renderDownloadsBadge({ downloads })
|
||||
}
|
||||
|
||||
async fetch({ namespace, name }) {
|
||||
return this._requestJson({
|
||||
schema: ansibleCollectionSchema,
|
||||
url: `https://galaxy.ansible.com/api/v3/plugin/ansible/content/published/collections/index/${namespace}/${name}/`,
|
||||
})
|
||||
}
|
||||
|
||||
async handle({ namespace, name }) {
|
||||
const { download_count: downloads } = await this.fetch({
|
||||
namespace,
|
||||
name,
|
||||
})
|
||||
return this.constructor.render({ downloads })
|
||||
}
|
||||
}
|
||||
16
services/ansible/ansible-collection-downloads.tester.js
Normal file
16
services/ansible/ansible-collection-downloads.tester.js
Normal file
@@ -0,0 +1,16 @@
|
||||
import { ServiceTester } from '../tester.js'
|
||||
import { isMetric } from '../test-validators.js'
|
||||
|
||||
export const t = new ServiceTester({
|
||||
id: 'AnsibleGalaxyCollectionDownloads',
|
||||
title: 'AnsibleGalaxyCollectionDownloads',
|
||||
pathPrefix: '/ansible/collection/d',
|
||||
})
|
||||
|
||||
t.create('collection downloads (valid)')
|
||||
.get('/community/general.json')
|
||||
.expectBadge({ label: 'collection downloads', message: isMetric })
|
||||
|
||||
t.create('collection downloads (not found)')
|
||||
.get('/not/real.json')
|
||||
.expectBadge({ label: 'collection downloads', message: 'not found' })
|
||||
47
services/ansible/ansible-collection-version.service.js
Normal file
47
services/ansible/ansible-collection-version.service.js
Normal file
@@ -0,0 +1,47 @@
|
||||
import Joi from 'joi'
|
||||
import { renderVersionBadge } from '../version.js'
|
||||
import { BaseJsonService, pathParams } from '../index.js'
|
||||
|
||||
const ansibleCollectionSchema = Joi.object({
|
||||
highest_version: Joi.object({
|
||||
version: Joi.string().required(),
|
||||
}).required(),
|
||||
}).required()
|
||||
|
||||
export default class AnsibleGalaxyCollectionVersion extends BaseJsonService {
|
||||
static category = 'version'
|
||||
static route = { base: 'ansible/collection/v', pattern: ':namespace/:name' }
|
||||
|
||||
static openApi = {
|
||||
'/ansible/collection/v/{namespace}/{name}': {
|
||||
get: {
|
||||
summary: 'Ansible Collection Version',
|
||||
parameters: pathParams(
|
||||
{ name: 'namespace', example: 'community' },
|
||||
{ name: 'name', example: 'general' },
|
||||
),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
static defaultBadgeData = { label: 'galaxy' }
|
||||
|
||||
static render({ version }) {
|
||||
return renderVersionBadge({ version })
|
||||
}
|
||||
|
||||
async fetch({ namespace, name }) {
|
||||
return this._requestJson({
|
||||
schema: ansibleCollectionSchema,
|
||||
url: `https://galaxy.ansible.com/api/v3/plugin/ansible/content/published/collections/index/${namespace}/${name}/`,
|
||||
})
|
||||
}
|
||||
|
||||
async handle({ namespace, name }) {
|
||||
const { highest_version: highestVersion } = await this.fetch({
|
||||
namespace,
|
||||
name,
|
||||
})
|
||||
return this.constructor.render({ version: highestVersion.version })
|
||||
}
|
||||
}
|
||||
16
services/ansible/ansible-collection-version.tester.js
Normal file
16
services/ansible/ansible-collection-version.tester.js
Normal file
@@ -0,0 +1,16 @@
|
||||
import { ServiceTester } from '../tester.js'
|
||||
import { isSemver } from '../test-validators.js'
|
||||
|
||||
export const t = new ServiceTester({
|
||||
id: 'AnsibleGalaxyCollectionVersion',
|
||||
title: 'AnsibleGalaxyCollectionVersion',
|
||||
pathPrefix: '/ansible/collection/v',
|
||||
})
|
||||
|
||||
t.create('collection version (valid)')
|
||||
.get('/community/general.json')
|
||||
.expectBadge({ label: 'galaxy', message: isSemver })
|
||||
|
||||
t.create('collection version (not found)')
|
||||
.get('/not/real.json')
|
||||
.expectBadge({ label: 'galaxy', message: 'not found' })
|
||||
@@ -1,4 +1,5 @@
|
||||
import { ServiceTester } from '../tester.js'
|
||||
|
||||
export const t = new ServiceTester({
|
||||
id: 'AnsibleGalaxyCollectionName',
|
||||
title: 'AnsibleGalaxyCollectionName',
|
||||
|
||||
@@ -145,7 +145,7 @@ export default class Codecov extends BaseSvgScrapingService {
|
||||
|
||||
async fetch({ vcsName, user, repo, branch, token, flag }) {
|
||||
const url = `https://codecov.io/${vcsName}/${user}/${repo}${
|
||||
branch ? `/branches/${branch}` : ''
|
||||
branch ? `/branch/${branch}` : ''
|
||||
}/graph/badge.svg`
|
||||
return this._requestSvg({
|
||||
schema,
|
||||
|
||||
@@ -36,7 +36,6 @@ const endpointSchema = Joi.object({
|
||||
logoSvg: Joi.string(),
|
||||
logoColor: optionalStringWhenNamedLogoPresent,
|
||||
logoSize: optionalStringWhenNamedLogoPresent,
|
||||
logoWidth: optionalNumberWhenAnyLogoPresent,
|
||||
style: Joi.string(),
|
||||
cacheSeconds: Joi.number().integer().min(0),
|
||||
/*
|
||||
@@ -45,6 +44,7 @@ const endpointSchema = Joi.object({
|
||||
passing it should not throw an error
|
||||
*/
|
||||
logoPosition: optionalNumberWhenAnyLogoPresent,
|
||||
logoWidth: optionalNumberWhenAnyLogoPresent,
|
||||
})
|
||||
// `namedLogo` or `logoSvg`; not both.
|
||||
.oxor('namedLogo', 'logoSvg')
|
||||
|
||||
@@ -101,13 +101,6 @@ The endpoint badge takes a single required query param: <code>url</code>, which
|
||||
Supported for simple-icons logos only.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>logoWidth</code></td>
|
||||
<td>
|
||||
Default: none. Same meaning as the query string. Can be overridden by
|
||||
the query string.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>style</code></td>
|
||||
<td>
|
||||
@@ -156,7 +149,6 @@ export default class Endpoint extends BaseJsonService {
|
||||
logoSvg,
|
||||
logoColor,
|
||||
logoSize,
|
||||
logoWidth,
|
||||
style,
|
||||
cacheSeconds,
|
||||
}) {
|
||||
@@ -170,7 +162,6 @@ export default class Endpoint extends BaseJsonService {
|
||||
logoSvg,
|
||||
logoColor,
|
||||
logoSize,
|
||||
logoWidth,
|
||||
style,
|
||||
// don't allow the user to set cacheSeconds any shorter than this._cacheLength
|
||||
cacheSeconds: Math.max(
|
||||
|
||||
@@ -118,6 +118,8 @@ t.create('custom svg logo')
|
||||
expect(body).to.include(getSimpleIcon({ name: 'npm' }))
|
||||
})
|
||||
|
||||
// The logoWidth param was removed, but passing it should not
|
||||
// throw a validation error. It should just do nothing.
|
||||
t.create('logoWidth')
|
||||
.get('.json?url=https://example.com/badge')
|
||||
.intercept(nock =>
|
||||
@@ -132,7 +134,6 @@ t.create('logoWidth')
|
||||
.expectBadge({
|
||||
label: 'hey',
|
||||
message: 'yo',
|
||||
logoWidth: 30,
|
||||
})
|
||||
|
||||
// The logoPosition param was removed, but passing it should not
|
||||
|
||||
@@ -32,7 +32,7 @@ class BasePackagistService extends BaseJsonService {
|
||||
* @param {string} attrs.server URL for the packagist registry server (Optional)
|
||||
* @returns {object} Parsed response
|
||||
*/
|
||||
async fetch({ user, repo, schema, server = 'https://packagist.org' }) {
|
||||
async fetch({ user, repo, schema, server = 'https://repo.packagist.org' }) {
|
||||
const url = `${server}/p2/${user.toLowerCase()}/${repo.toLowerCase()}.json`
|
||||
|
||||
return this._requestJson({
|
||||
@@ -56,7 +56,12 @@ class BasePackagistService extends BaseJsonService {
|
||||
* @param {string} attrs.server URL for the packagist registry server (Optional)
|
||||
* @returns {object} Parsed response
|
||||
*/
|
||||
async fetchDev({ user, repo, schema, server = 'https://packagist.org' }) {
|
||||
async fetchDev({
|
||||
user,
|
||||
repo,
|
||||
schema,
|
||||
server = 'https://repo.packagist.org',
|
||||
}) {
|
||||
const url = `${server}/p2/${user.toLowerCase()}/${repo.toLowerCase()}~dev.json`
|
||||
|
||||
return this._requestJson({
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import { redirector } from '../index.js'
|
||||
|
||||
export default redirector({
|
||||
// SourceForge commit count service used to only have project name as a parameter
|
||||
// and the repository name was always `git`.
|
||||
// The service was later updated to have the repository name as a parameter.
|
||||
// This redirector is used to keep the old URLs working.
|
||||
category: 'activity',
|
||||
route: {
|
||||
base: 'sourceforge/commit-count',
|
||||
pattern: ':project',
|
||||
},
|
||||
transformPath: ({ project }) => `/sourceforge/commit-count/${project}/git`,
|
||||
dateAdded: new Date('2025-03-15'),
|
||||
})
|
||||
@@ -0,0 +1,6 @@
|
||||
import { createServiceTester } from '../tester.js'
|
||||
export const t = await createServiceTester()
|
||||
|
||||
t.create('commit count (redirect)')
|
||||
.get('/guitarix.json')
|
||||
.expectRedirect('/sourceforge/commit-count/guitarix/git.json')
|
||||
@@ -11,17 +11,25 @@ export default class SourceforgeCommitCount extends BaseJsonService {
|
||||
|
||||
static route = {
|
||||
base: 'sourceforge/commit-count',
|
||||
pattern: ':project',
|
||||
pattern: ':project/:repo',
|
||||
}
|
||||
|
||||
static openApi = {
|
||||
'/sourceforge/commit-count/{project}': {
|
||||
'/sourceforge/commit-count/{project}/{repo}': {
|
||||
get: {
|
||||
summary: 'SourceForge Commit Count',
|
||||
parameters: pathParams({
|
||||
name: 'project',
|
||||
example: 'guitarix',
|
||||
}),
|
||||
parameters: pathParams(
|
||||
{
|
||||
name: 'project',
|
||||
example: 'guitarix',
|
||||
},
|
||||
{
|
||||
name: 'repo',
|
||||
example: 'git',
|
||||
description:
|
||||
'The repository name, usually `git` but might be different.',
|
||||
},
|
||||
),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -35,18 +43,18 @@ export default class SourceforgeCommitCount extends BaseJsonService {
|
||||
}
|
||||
}
|
||||
|
||||
async fetch({ project }) {
|
||||
async fetch({ project, repo }) {
|
||||
return this._requestJson({
|
||||
url: `https://sourceforge.net/rest/p/${project}/git`,
|
||||
url: `https://sourceforge.net/rest/p/${project}/${repo}`,
|
||||
schema,
|
||||
httpErrors: {
|
||||
404: 'project not found',
|
||||
404: 'project or repo not found',
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
async handle({ project }) {
|
||||
const body = await this.fetch({ project })
|
||||
async handle({ project, repo }) {
|
||||
const body = await this.fetch({ project, repo })
|
||||
return this.constructor.render({
|
||||
commitCount: body.commit_count,
|
||||
})
|
||||
|
||||
@@ -3,9 +3,17 @@ import { createServiceTester } from '../tester.js'
|
||||
export const t = await createServiceTester()
|
||||
|
||||
t.create('commit count')
|
||||
.get('/guitarix.json')
|
||||
.get('/guitarix/git.json')
|
||||
.expectBadge({ label: 'commit count', message: isMetric })
|
||||
|
||||
t.create('commit count (non default repo)')
|
||||
.get('/opencamera/code.json')
|
||||
.expectBadge({ label: 'commit count', message: isMetric })
|
||||
|
||||
t.create('commit count (project not found)')
|
||||
.get('/that-doesnt-exist.json')
|
||||
.expectBadge({ label: 'commit count', message: 'project not found' })
|
||||
.get('/that-doesnt-exist/git.json')
|
||||
.expectBadge({ label: 'commit count', message: 'project or repo not found' })
|
||||
|
||||
t.create('commit count (repo not found)')
|
||||
.get('/guitarix/invalid-repo.json')
|
||||
.expectBadge({ label: 'commit count', message: 'project or repo not found' })
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import { redirector } from '../index.js'
|
||||
|
||||
export default redirector({
|
||||
// SourceForge last commit service used to only have project name as a parameter
|
||||
// and the repository name was always `git`.
|
||||
// The service was later updated to have the repository name as a parameter.
|
||||
// This redirector is used to keep the old URLs working.
|
||||
category: 'activity',
|
||||
route: {
|
||||
base: 'sourceforge/last-commit',
|
||||
pattern: ':project',
|
||||
},
|
||||
transformPath: ({ project }) => `/sourceforge/last-commit/${project}/git`,
|
||||
dateAdded: new Date('2025-03-08'),
|
||||
})
|
||||
@@ -0,0 +1,6 @@
|
||||
import { createServiceTester } from '../tester.js'
|
||||
export const t = await createServiceTester()
|
||||
|
||||
t.create('last commit (redirect)')
|
||||
.get('/guitarix.json')
|
||||
.expectRedirect('/sourceforge/last-commit/guitarix/git.json')
|
||||
@@ -17,35 +17,43 @@ export default class SourceforgeLastCommit extends BaseJsonService {
|
||||
|
||||
static route = {
|
||||
base: 'sourceforge/last-commit',
|
||||
pattern: ':project',
|
||||
pattern: ':project/:repo',
|
||||
}
|
||||
|
||||
static openApi = {
|
||||
'/sourceforge/last-commit/{project}': {
|
||||
'/sourceforge/last-commit/{project}/{repo}': {
|
||||
get: {
|
||||
summary: 'SourceForge Last Commit',
|
||||
parameters: pathParams({
|
||||
name: 'project',
|
||||
example: 'guitarix',
|
||||
}),
|
||||
parameters: pathParams(
|
||||
{
|
||||
name: 'project',
|
||||
example: 'guitarix',
|
||||
},
|
||||
{
|
||||
name: 'repo',
|
||||
example: 'git',
|
||||
description:
|
||||
'The repository name, usually `git` but might be different.',
|
||||
},
|
||||
),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
static defaultBadgeData = { label: 'last commit' }
|
||||
|
||||
async fetch({ project }) {
|
||||
async fetch({ project, repo }) {
|
||||
return this._requestJson({
|
||||
url: `https://sourceforge.net/rest/p/${project}/git/commits`,
|
||||
url: `https://sourceforge.net/rest/p/${project}/${repo}/commits`,
|
||||
schema,
|
||||
httpErrors: {
|
||||
404: 'project not found',
|
||||
404: 'project or repo not found',
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
async handle({ project }) {
|
||||
const body = await this.fetch({ project })
|
||||
async handle({ project, repo }) {
|
||||
const body = await this.fetch({ project, repo })
|
||||
return renderDateBadge(body.commits[0].committed_date)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,9 +3,17 @@ import { createServiceTester } from '../tester.js'
|
||||
export const t = await createServiceTester()
|
||||
|
||||
t.create('last commit')
|
||||
.get('/guitarix.json')
|
||||
.get('/guitarix/git.json')
|
||||
.expectBadge({ label: 'last commit', message: isFormattedDate })
|
||||
|
||||
t.create('last commit (non default repo)')
|
||||
.get('/opencamera/code.json')
|
||||
.expectBadge({ label: 'last commit', message: isFormattedDate })
|
||||
|
||||
t.create('last commit (project not found)')
|
||||
.get('/that-doesnt-exist.json')
|
||||
.expectBadge({ label: 'last commit', message: 'project not found' })
|
||||
.get('/that-doesnt-exist/fake.json')
|
||||
.expectBadge({ label: 'last commit', message: 'project or repo not found' })
|
||||
|
||||
t.create('last commit (repo not found)')
|
||||
.get('/guitarix/fake-repo.json')
|
||||
.expectBadge({ label: 'last commit', message: 'project or repo not found' })
|
||||
|
||||
Reference in New Issue
Block a user