Compare commits

...

842 Commits
2.1.0 ... 2.2.1

Author SHA1 Message Date
chris48s
98f380b254 improve logo escaping (#3511)
* escape logo in make-badge

* 2.2.1 release notes

* tighten up validation of logo param
2019-05-30 18:28:37 +01:00
chris48s
829971f0ef Fix BadgeFactory.create() docblock (#3506)
* fix docblock

* add a reminder in make-badge.js
2019-05-30 12:28:17 +01:00
chris48s
bfe0bde83d switch [powershellgallery] platform example (#3504)
The example we were previously using
(Az.Storage) now renders

platform | not specified

This replaces the example with a
package that gives us a valid result
2019-05-29 21:21:35 +01:00
Marcin Mielnicki
9008c4ef0f Show a badge pattern instead of a badge url (#3438)
* Show patterns instead of real paths

* realBadge property instead of preview.buildFromExample

* E2e test for displaying a badge

* Check bagde url in badge wrapper

* expectBadgeExample helper function

* Remove a hostname from badge url

* Simpler Cypress assertions

* realBadge -> isBadgeSuggestion

* Do not show regexp in patterns
2019-05-29 21:17:27 +02:00
chris48s
f50fcac107 fix 'failing service test' template (#3503) 2019-05-29 16:30:16 +01:00
chris48s
ebb70d57f7 gh-badges v2.2.0 (#3501) 2019-05-29 16:16:32 +01:00
chris48s
6fe566de41 Run package tests on multiple node versions with nvm (#3498)
* run package tests on multiple node versions with nvm

* Add release schedule to package readme
2019-05-29 15:55:27 +01:00
chris48s
65dba94fa8 Stop calling variables "which"; affects [chocolatey codeclimate conda crates debug gem github mozillaobservatory nuget powershellgallery pub resharper vaadindirectory] (#3495)
* which --> variant

* which --> alias

* which --> format

* improve param names in codeclimate

* improve param names in github-issue-detail

* update github-issue-detail unit tests
2019-05-28 23:00:12 +01:00
chris48s
52e90af310 improve docs on examples (#3496)
closes #3440
2019-05-28 18:17:59 +01:00
chris48s
fd271b834e Switch dependabot to yaml config (#3494) 2019-05-28 18:09:56 +01:00
dependabot-preview[bot]
f9ec7d0445 Build(deps-dev): bump react-error-overlay from 5.1.4 to 5.1.6 (#3485)
Bumps [react-error-overlay](https://github.com/facebook/create-react-app/tree/HEAD/packages/react-error-overlay) from 5.1.4 to 5.1.6.
- [Release notes](https://github.com/facebook/create-react-app/releases)
- [Changelog](https://github.com/facebook/create-react-app/blob/master/CHANGELOG-1.x.md)
- [Commits](https://github.com/facebook/create-react-app/commits/react-error-overlay@5.1.6/packages/react-error-overlay)
2019-05-27 16:47:55 -05:00
dependabot-preview[bot]
eb2325310c Build(deps-dev): bump @babel/core from 7.4.3 to 7.4.5 (#3492)
Bumps [@babel/core](https://github.com/babel/babel) from 7.4.3 to 7.4.5.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.4.3...v7.4.5)
2019-05-27 16:30:40 -05:00
Caleb Cartwright
b7982f4459 feat: deprecate jitpack downloads badge (#3493) 2019-05-27 16:21:50 -05:00
dependabot-preview[bot]
91ce3af172 Build(deps-dev): bump @babel/preset-env from 7.4.4 to 7.4.5 (#3491)
Bumps [@babel/preset-env](https://github.com/babel/babel) from 7.4.4 to 7.4.5.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.4.4...v7.4.5)
2019-05-27 15:54:31 -05:00
dependabot-preview[bot]
c54a7a0042 Build(deps-dev): bump lint-staged from 8.1.5 to 8.1.7 (#3487)
Bumps [lint-staged](https://github.com/okonet/lint-staged) from 8.1.5 to 8.1.7.
- [Release notes](https://github.com/okonet/lint-staged/releases)
- [Commits](https://github.com/okonet/lint-staged/compare/v8.1.5...v8.1.7)
2019-05-27 20:03:55 +02:00
dependabot-preview[bot]
1e3d66f3e9 Build(deps-dev): bump eslint-plugin-import from 2.17.2 to 2.17.3 (#3489)
Bumps [eslint-plugin-import](https://github.com/benmosher/eslint-plugin-import) from 2.17.2 to 2.17.3.
- [Release notes](https://github.com/benmosher/eslint-plugin-import/releases)
- [Changelog](https://github.com/benmosher/eslint-plugin-import/blob/master/CHANGELOG.md)
- [Commits](https://github.com/benmosher/eslint-plugin-import/compare/v2.17.2...v2.17.3)
2019-05-27 11:20:19 -05:00
dependabot-preview[bot]
b2281880d1 Build(deps-dev): bump eslint-config-prettier from 4.1.0 to 4.3.0 (#3488)
Bumps [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) from 4.1.0 to 4.3.0.
- [Release notes](https://github.com/prettier/eslint-config-prettier/releases)
- [Changelog](https://github.com/prettier/eslint-config-prettier/blob/master/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-config-prettier/compare/v4.1.0...v4.3.0)
2019-05-27 11:13:46 -05:00
dependabot-preview[bot]
099b7b4eb9 Build(deps-dev): bump js-yaml-loader from 1.0.1 to 1.2.0 (#3483)
Bumps [js-yaml-loader](https://github.com/wwilsman/js-yaml-loader) from 1.0.1 to 1.2.0.
- [Release notes](https://github.com/wwilsman/js-yaml-loader/releases)
- [Commits](https://github.com/wwilsman/js-yaml-loader/compare/v1.0.1...v1.2.0)
2019-05-27 13:52:48 +01:00
dependabot-preview[bot]
ab711fca05 Build(deps-dev): bump cypress from 3.3.0 to 3.3.1 (#3490)
Bumps [cypress](https://github.com/cypress-io/cypress) from 3.3.0 to 3.3.1.
- [Release notes](https://github.com/cypress-io/cypress/releases)
- [Commits](https://github.com/cypress-io/cypress/compare/v3.3.0...v3.3.1)
2019-05-27 12:53:51 +01:00
dependabot-preview[bot]
ae0f4e236a Build(deps-dev): bump nodemon from 1.19.0 to 1.19.1 (#3486)
Bumps [nodemon](https://github.com/remy/nodemon) from 1.19.0 to 1.19.1.
- [Release notes](https://github.com/remy/nodemon/releases)
- [Commits](https://github.com/remy/nodemon/compare/v1.19.0...v1.19.1)
2019-05-27 12:45:38 +01:00
dependabot-preview[bot]
8b3bbdb228 Build(deps): bump check-node-version from 3.3.0 to 4.0.1 (#3467)
Bumps [check-node-version](https://github.com/parshap/check-node-version) from 3.3.0 to 4.0.1.
- [Release notes](https://github.com/parshap/check-node-version/releases)
- [Changelog](https://github.com/parshap/check-node-version/blob/master/CHANGELOG.md)
- [Commits](https://github.com/parshap/check-node-version/compare/v3.3.0...v4.0.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-05-26 11:41:03 -04:00
Pierre-Yves B
638ad39b9e Open Collective funding link (#3481) 2019-05-26 12:12:04 +01:00
dependabot-preview[bot]
46c4063880 Build(deps): bump camp from 17.2.2 to 17.2.4 (#3466)
Bumps [camp](https://github.com/espadrine/sc) from 17.2.2 to 17.2.4.
- [Release notes](https://github.com/espadrine/sc/releases)
- [Commits](https://github.com/espadrine/sc/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-05-25 11:51:13 +01:00
Caleb Cartwright
27bb914172 tests(jsdelivr): increase timeout (#3479) 2019-05-24 13:31:35 +01:00
Caleb Cartwright
37030b92a0 tests(GitHubReleaseDate): fix service tests (#3477) 2019-05-23 19:31:49 +01:00
Josep Bernad
d685cde52b Add [Subreddit] subscribers (#3443)
* Add subreddit subscribers service file.

* Fix small detail in service and add the tests files.

* Apply suggested changes by the reviewer.

* Trying to make tests work.

* Update services/reddit/subreddit-subscribers.tester.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/reddit/subreddit-subscribers.tester.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Apply suggested changes.

* Add different handler for non existing and invalid subreddits.

* Update services/reddit/subreddit-subscribers.service.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>
2019-05-22 16:43:13 -05:00
Caleb Cartwright
02ee34d2a5 feat: deprecate waffle service (#3473) 2019-05-22 10:04:30 +01:00
Caleb Cartwright
f94efe74db fix(aur): update test and example package targets (#3475) 2019-05-22 09:57:15 +01:00
dependabot[bot]
a74ddc87ef Build(deps-dev): bump gatsby from 2.3.33 to 2.5.7 (#3472)
Bumps [gatsby](https://github.com/gatsbyjs/gatsby) from 2.3.33 to 2.5.7.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/compare/gatsby@2.3.33...gatsby@2.5.7)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-05-21 18:14:27 -05:00
dependabot[bot]
c358ad3cd9 Build(deps-dev): bump enzyme-adapter-react-16 from 1.12.1 to 1.13.1 (#3469)
Bumps [enzyme-adapter-react-16](https://github.com/airbnb/enzyme/tree/HEAD/packages/enzyme-adapter-react-16) from 1.12.1 to 1.13.1.
- [Release notes](https://github.com/airbnb/enzyme/releases)
- [Changelog](https://github.com/airbnb/enzyme/blob/master/CHANGELOG.md)
- [Commits](https://github.com/airbnb/enzyme/commits/enzyme-adapter-react-16@1.13.1/packages/enzyme-adapter-react-16)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-05-21 17:30:49 -05:00
dependabot[bot]
f5b3119a43 Build(deps-dev): bump husky from 2.1.0 to 2.3.0 (#3463)
Bumps [husky](https://github.com/typicode/husky) from 2.1.0 to 2.3.0.
- [Release notes](https://github.com/typicode/husky/releases)
- [Changelog](https://github.com/typicode/husky/blob/master/CHANGELOG.md)
- [Commits](https://github.com/typicode/husky/compare/v2.1.0...v2.3.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-05-20 19:57:46 +01:00
dependabot[bot]
066a2957a4 Build(deps-dev): bump @babel/plugin-proposal-class-properties (#3462)
Bumps [@babel/plugin-proposal-class-properties](https://github.com/babel/babel) from 7.4.0 to 7.4.4.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.4.0...v7.4.4)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-05-20 10:37:30 -05:00
dependabot[bot]
d593da8337 Build(deps-dev): bump eslint-plugin-react from 7.12.4 to 7.13.0 (#3461)
Bumps [eslint-plugin-react](https://github.com/yannickcr/eslint-plugin-react) from 7.12.4 to 7.13.0.
- [Release notes](https://github.com/yannickcr/eslint-plugin-react/releases)
- [Changelog](https://github.com/yannickcr/eslint-plugin-react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/yannickcr/eslint-plugin-react/compare/v7.12.4...v7.13.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-05-20 07:36:06 -05:00
dependabot[bot]
91e013a738 Build(deps-dev): bump cypress from 3.2.0 to 3.3.0 (#3468)
Bumps [cypress](https://github.com/cypress-io/cypress) from 3.2.0 to 3.3.0.
- [Release notes](https://github.com/cypress-io/cypress/releases)
- [Commits](https://github.com/cypress-io/cypress/compare/v3.2.0...v3.3.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-05-20 07:13:30 -05:00
dependabot[bot]
91f5f8f557 Build(deps-dev): bump nyc from 14.0.0 to 14.1.1 (#3470)
Bumps [nyc](https://github.com/istanbuljs/nyc) from 14.0.0 to 14.1.1.
- [Release notes](https://github.com/istanbuljs/nyc/releases)
- [Changelog](https://github.com/istanbuljs/nyc/blob/master/CHANGELOG.md)
- [Commits](https://github.com/istanbuljs/nyc/compare/v14.0.0...v14.1.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-05-20 06:58:07 -05:00
dependabot[bot]
b3e58c67be Build(deps-dev): bump mocha-junit-reporter from 1.21.0 to 1.22.0 (#3464)
Bumps [mocha-junit-reporter](https://github.com/michaelleeallen/mocha-junit-reporter) from 1.21.0 to 1.22.0.
- [Release notes](https://github.com/michaelleeallen/mocha-junit-reporter/releases)
- [Commits](https://github.com/michaelleeallen/mocha-junit-reporter/compare/v1.21.0...v1.22.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-05-20 05:53:29 -05:00
Pierre-Yves B
570ba18333 lastCompletedBuild for [Jenkins] badges and better discoverability (#3460) 2019-05-16 21:29:16 +01:00
Josep Bernad
17446efb45 Improvements in the TUTORIAL.md file (#3435)
* Improve tutorial file with explaining how to solve an error.

* Fix typo.

* Fix typo.

* Add more information about the fix.

* Apply suggested changes.

* Add missing method in the first example

* Modify the second example that did't compile.

* Add troubleshooting for the localhost and link to the issue solving it.

* Rephrase.

* Update doc/TUTORIAL.md

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Add get category() function explanation in both examples.

* Update doc/TUTORIAL.md

Co-Authored-By: Paul Melnikow <github@paulmelnikow.com>
2019-05-15 19:40:18 +01:00
dependabot[bot]
b87bf0f4ba Build(deps-dev): bump snap-shot-it from 6.3.5 to 7.4.4 (#3455)
Bumps [snap-shot-it](https://github.com/bahmutov/snap-shot-it) from 6.3.5 to 7.4.4.
- [Release notes](https://github.com/bahmutov/snap-shot-it/releases)
- [Commits](https://github.com/bahmutov/snap-shot-it/compare/v6.3.5...v7.4.4)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-05-14 18:49:08 -05:00
dependabot[bot]
aee5f0da02 Build(deps-dev): bump sazerac from 0.4.2 to 1.0.0 (#3453)
Bumps [sazerac](https://github.com/sazeracjs/sazerac) from 0.4.2 to 1.0.0.
- [Release notes](https://github.com/sazeracjs/sazerac/releases)
- [Changelog](https://github.com/sazeracjs/sazerac/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sazeracjs/sazerac/compare/v0.4.2...v1.0.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-05-14 15:34:36 -05:00
Caleb Cartwright
60e69ee43b docs: fix link in Contributing guide (#3457) 2019-05-14 15:25:55 -05:00
Caleb Cartwright
9fe238a81f fix(stackexchange): questions/month badge with 0 questions (#3456) 2019-05-13 20:41:56 -04:00
dependabot[bot]
04d75f09c5 Build(deps-dev): bump react from 16.8.5 to 16.8.6 (#3446)
Bumps [react](https://github.com/facebook/react/tree/HEAD/packages/react) from 16.8.5 to 16.8.6.
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v16.8.6/packages/react)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-05-13 19:16:38 -05:00
dependabot[bot]
30460a770d Build(deps-dev): bump opn-cli from 4.1.0 to 5.0.0 (#3452)
* Build(deps-dev): bump opn-cli from 4.1.0 to 5.0.0

Bumps [opn-cli](https://github.com/sindresorhus/open-cli) from 4.1.0 to 5.0.0.
- [Release notes](https://github.com/sindresorhus/open-cli/releases)
- [Commits](https://github.com/sindresorhus/open-cli/compare/v4.1.0...v5.0.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>

* chore: update script to reflect new bin name
2019-05-13 18:58:28 -05:00
dependabot[bot]
c5946cd617 Build(deps-dev): bump @babel/register from 7.4.0 to 7.4.4 (#3451)
Bumps [@babel/register](https://github.com/babel/babel) from 7.4.0 to 7.4.4.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.4.0...v7.4.4)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-05-13 22:30:41 +01:00
dependabot[bot]
905577bba3 Build(deps-dev): bump babel-plugin-istanbul from 5.1.2 to 5.1.4 (#3448)
Bumps [babel-plugin-istanbul](https://github.com/istanbuljs/babel-plugin-istanbul) from 5.1.2 to 5.1.4.
- [Release notes](https://github.com/istanbuljs/babel-plugin-istanbul/releases)
- [Changelog](https://github.com/istanbuljs/babel-plugin-istanbul/blob/master/CHANGELOG.md)
- [Commits](https://github.com/istanbuljs/babel-plugin-istanbul/compare/v5.1.2...v5.1.4)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-05-13 22:23:00 +01:00
dependabot[bot]
9253c4c32f Build(deps-dev): bump react-helmet from 5.2.0 to 5.2.1 (#3449)
Bumps [react-helmet](https://github.com/nfl/react-helmet) from 5.2.0 to 5.2.1.
- [Release notes](https://github.com/nfl/react-helmet/releases)
- [Changelog](https://github.com/nfl/react-helmet/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nfl/react-helmet/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-05-13 22:13:13 +01:00
dependabot[bot]
ab3b77ec32 Build(deps-dev): bump start-server-and-test from 1.7.12 to 1.9.0 (#3450)
Bumps [start-server-and-test](https://github.com/bahmutov/start-server-and-test) from 1.7.12 to 1.9.0.
- [Release notes](https://github.com/bahmutov/start-server-and-test/releases)
- [Commits](https://github.com/bahmutov/start-server-and-test/compare/v1.7.12...v1.9.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-05-13 22:06:46 +01:00
dependabot[bot]
2edd390aa9 Build(deps-dev): bump nock from 11.0.0-beta.10 to 11.0.0-beta.14 (#3454)
Bumps [nock](https://github.com/nock/nock) from 11.0.0-beta.10 to 11.0.0-beta.14.
- [Release notes](https://github.com/nock/nock/releases)
- [Changelog](https://github.com/nock/nock/blob/beta/CHANGELOG.md)
- [Commits](https://github.com/nock/nock/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-05-13 21:58:23 +01:00
dependabot[bot]
0e6dff769d Build(deps): bump glob from 7.1.3 to 7.1.4 (#3447)
Bumps [glob](https://github.com/isaacs/node-glob) from 7.1.3 to 7.1.4.
- [Release notes](https://github.com/isaacs/node-glob/releases)
- [Changelog](https://github.com/isaacs/node-glob/blob/master/changelog.md)
- [Commits](https://github.com/isaacs/node-glob/compare/v7.1.3...v7.1.4)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-05-13 20:59:06 +02:00
Pierre-Yves B
992bd81baa Fixed Wordpress rating examples (#3445) 2019-05-12 22:12:47 +01:00
chris48s
7caf301730 switch [circleci] service to scrape SVG badge, reorganise routes (#3413)
* switch [circleci] service to scrape SVG badge

* reorganise [circleci] routes

Default URL is now
circleci/build/gh/badges/shields/master?token=abc123
There are redirects on the legacy routes to provide
backwards compatibility for existing users
2019-05-11 17:55:32 +01:00
chris48s
3bb614ff39 fix [microbadger] examples (#3439) 2019-05-09 16:39:40 -04:00
Marcin Mielnicki
283601423f Redirect an old png badge with a number as a color; test on [static] (#3412)
Fixes https://github.com/badges/shields/issues/3260

Problem happens when a value of a color in an old PNG static badge is a number: http://localhost:8080/my-label/my-message.png?color=1. In this case `color` in `queryParams` is a number. 
0a0b5b3f03/core/server/server.js (L203-L212)

Surprisingly service test listed below is passing currently on master - value `1` is represented in `queryParams` as a String (only in test). 
`services/static-badge/static-badge.tester.js`
```js
t.create('Old static badge with a number as a color')
  .get('/foo/bar.png?color=1', { followRedirect: false })
  .expectStatus(301)
  .expectHeader('Location', '/badge/foo-bar-1.png')
```

Moreover I added some code + description allowing to debug server.
2019-05-08 12:33:43 -04:00
Paul Melnikow
7afb26ef14 Add some aliases for license colors; refactor; test colors for [PypiLicense] (#3431)
This covers some of the license strings used by the PyPI badges like **BSD** which currently shows up in lightgrey.
2019-05-07 23:32:15 -04:00
Jeffrey Paul
9b3fd375bb Update references to "WordPress" (#3434)
Fixes #3432
2019-05-07 11:39:00 -04:00
Chris Gavin
d6c875c519 Fix [LGTM] badges for non-GitHub projects. (#3362)
* Fix LGTM badges for non-GitHub projects.

* Allow using full repository host names in LGTM badge URLs.

* Add an LGTM redirector service to redirect old LGTM badge URLs to new LGTM badge URLs.

* Add LGTM redirector tester.

* Remove unneeded check in LGTM base file.

Co-Authored-By: chrisgavin <chris@chrisgavin.me>
2019-05-07 07:46:14 -07:00
Paul Melnikow
5e8fcc3b3c MarkupModal: Convert from class component to function component (#3415)
This continues the work from #3096, of converting our class components to function components.
2019-05-06 12:13:06 -04:00
dependabot[bot]
e5829fb353 Build(deps): bump dotenv from 7.0.0 to 8.0.0 (#3420)
Bumps [dotenv](https://github.com/motdotla/dotenv) from 7.0.0 to 8.0.0.
- [Release notes](https://github.com/motdotla/dotenv/releases)
- [Changelog](https://github.com/motdotla/dotenv/blob/master/CHANGELOG.md)
- [Commits](https://github.com/motdotla/dotenv/compare/v7.0.0...v8.0.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-05-06 09:06:45 -04:00
dependabot[bot]
43b0b408db Build(deps-dev): bump @babel/preset-env from 7.3.1 to 7.4.4 (#3423)
Bumps [@babel/preset-env](https://github.com/babel/babel) from 7.3.1 to 7.4.4.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.3.1...v7.4.4)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-05-06 09:00:36 -04:00
dependabot[bot]
af9a28459d Build(deps-dev): bump eslint-plugin-node from 8.0.1 to 9.0.1 (#3419)
Bumps [eslint-plugin-node](https://github.com/mysticatea/eslint-plugin-node) from 8.0.1 to 9.0.1.
- [Release notes](https://github.com/mysticatea/eslint-plugin-node/releases)
- [Commits](https://github.com/mysticatea/eslint-plugin-node/compare/v8.0.1...v9.0.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-05-06 08:20:34 -04:00
dependabot[bot]
168da685dd Build(deps): bump pretty-bytes from 5.1.0 to 5.2.0 (#3422)
Bumps [pretty-bytes](https://github.com/sindresorhus/pretty-bytes) from 5.1.0 to 5.2.0.
- [Release notes](https://github.com/sindresorhus/pretty-bytes/releases)
- [Commits](https://github.com/sindresorhus/pretty-bytes/compare/v5.1.0...v5.2.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-05-06 08:09:21 -04:00
dependabot[bot]
f6dd3bb8dd Build(deps): bump query-string from 6.4.2 to 6.5.0 (#3424)
Bumps [query-string](https://github.com/sindresorhus/query-string) from 6.4.2 to 6.5.0.
- [Release notes](https://github.com/sindresorhus/query-string/releases)
- [Commits](https://github.com/sindresorhus/query-string/compare/v6.4.2...v6.5.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-05-06 10:55:06 +01:00
dependabot[bot]
ed75191739 Build(deps-dev): bump node-mocks-http from 1.7.3 to 1.7.5 (#3426)
Bumps [node-mocks-http](https://github.com/howardabrams/node-mocks-http) from 1.7.3 to 1.7.5.
- [Release notes](https://github.com/howardabrams/node-mocks-http/releases)
- [Changelog](https://github.com/howardabrams/node-mocks-http/blob/master/HISTORY.md)
- [Commits](https://github.com/howardabrams/node-mocks-http/compare/v1.7.3...v1.7.5)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-05-06 10:32:49 +01:00
Paul Melnikow
786bac21ce Convert remaining uses of node-fetch to got (#3417) 2019-05-06 10:10:07 +01:00
Paul Melnikow
4d5acd54df Remove unused pretty dependency (#3416)
Looks like this was added way back in #1163 and is definitely not the way things are happening now. I don't see anywhere else it's being used.
2019-05-06 10:00:25 +01:00
Paul Melnikow
1da791e778 LogoPage: Update function style (#3414)
Many of the components (e.g. the ones in `common.js`) have already been converted to this style. This file was missed.
2019-05-06 09:51:07 +01:00
dependabot[bot]
ac34705524 Build(deps-dev): bump eslint-plugin-import from 2.17.1 to 2.17.2 (#3427)
Bumps [eslint-plugin-import](https://github.com/benmosher/eslint-plugin-import) from 2.17.1 to 2.17.2.
- [Release notes](https://github.com/benmosher/eslint-plugin-import/releases)
- [Changelog](https://github.com/benmosher/eslint-plugin-import/blob/master/CHANGELOG.md)
- [Commits](https://github.com/benmosher/eslint-plugin-import/compare/v2.17.1...v2.17.2)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-05-06 09:41:08 +01:00
dependabot[bot]
1333ff8ba4 Build(deps): bump simple-icons from 1.9.24 to 1.9.26 (#3421)
Bumps [simple-icons](https://github.com/simple-icons/simple-icons) from 1.9.24 to 1.9.26.
- [Release notes](https://github.com/simple-icons/simple-icons/releases)
- [Commits](https://github.com/simple-icons/simple-icons/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-05-06 09:34:12 +01:00
dependabot[bot]
86e9457fed Build(deps-dev): bump nodemon from 1.18.11 to 1.19.0 (#3418)
Bumps [nodemon](https://github.com/remy/nodemon) from 1.18.11 to 1.19.0.
- [Release notes](https://github.com/remy/nodemon/releases)
- [Commits](https://github.com/remy/nodemon/compare/v1.18.11...v1.19.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-05-06 09:28:00 +01:00
Pierre-Yves B
0a0b5b3f03 Added support for branches in "commits since" GitHub badge (#3411) 2019-05-05 10:47:07 -04:00
Ville Skyttä
3b73900b8a Add [Fedora] package version support (#3372) 2019-05-03 17:15:38 -04:00
Ville Skyttä
742f287f06 Move optional path components to the end for [Debian] and [Ubuntu] (#3409)
Refs https://github.com/badges/shields/pull/3372
2019-05-03 17:05:57 -04:00
Paul Melnikow
001ade3704 Move checkErrorResponse from lib/ to core/ [chrome] (#3408) 2019-05-02 18:07:18 -04:00
Paul Melnikow
a0da978886 Bury the loader fixtures with the code that uses them (#3407)
One less thing to have in the root of the project!
2019-05-02 12:36:00 -04:00
Paul Melnikow
c3bc0ac96f Take the Endpoint badge out of beta (#3405)
Close #2838
2019-05-01 23:05:34 -04:00
Marcin Mielnicki
65d42d5cb1 Remove IP filtering documentation for metrics (#3406) 2019-05-01 22:50:27 +02:00
Paul Melnikow
73ed7778fd Automatically reload the server when it changes (#3401)
While working on #2428 I found myself wanting to reload the server frequently. This is working great and reducing my iteration time significantly. I should have tackled this way sooner! 🙊 

I’ve left `verbose` on which seems useful, at least in the short term while we’re tuning the configuration.

Close #2426
2019-05-01 16:39:25 -04:00
Ville Skyttä
26852eece9 Add [Ubuntu] package version support (#3398)
* Add [Ubuntu] package version support

https://api.launchpad.net/1.0/

* Mark 400 responses as series not found

* Extract API call into separate fetch function
2019-05-01 11:24:21 -05:00
Marcin Mielnicki
ec244fe305 Remove code duplication in CircleCI configuration; test on [jetbrains] (#3400)
* Remove code duplication in CircleCI configuration

* Common steps moved to the root
2019-04-30 23:21:50 +02:00
dependabot[bot]
6abff761dd Build(deps-dev): bump gatsby-plugin-remove-trailing-slashes (#3387)
Bumps [gatsby-plugin-remove-trailing-slashes](https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-plugin-remove-trailing-slashes) from 2.0.10 to 2.0.11.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-remove-trailing-slashes/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-remove-trailing-slashes@2.0.11/packages/gatsby-plugin-remove-trailing-slashes)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-30 20:21:30 +02:00
Ville Skyttä
8f4042f4c8 Distro version improvements (#3397) 2019-04-30 11:24:50 -04:00
Paul Melnikow
ae2499bf53 Generate JSON badges without using a template [GithubSearch] (#3395)
Warm up for #2428.
2019-04-29 23:26:52 -04:00
Paul Melnikow
7980a65d7f [WordpressPlatformTests] Support tested version without trailing ".0" (#3396)
See https://circleci.com/gh/badges/shields/52378 for an example failure,
where a value of `5.2` is triggering "TypeError: Invalid Version: 5.2"
2019-04-29 21:52:57 -04:00
Paul Melnikow
b2e21da34d Remove legacy helper makeBadgeData (#3392)
Close #3369
2019-04-29 19:44:25 -04:00
dependabot[bot]
b752bbfd5a Bump escape-string-regexp from 1.0.5 to 2.0.0; move to dev deps (#3383) 2019-04-29 18:35:56 -04:00
dependabot[bot]
91592802da Build(deps-dev): bump gatsby from 2.3.25 to 2.3.33 (#3389)
Bumps [gatsby](https://github.com/gatsbyjs/gatsby) from 2.3.25 to 2.3.33.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/compare/gatsby@2.3.25...gatsby@2.3.33)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-29 18:27:10 -04:00
Paul Melnikow
ad182885ad Get two service helpers to 100% coverage (#3391) 2019-04-29 14:16:33 -04:00
Pierre-Yves B
9a869e24ba Added link test expectations (#3376) 2019-04-29 18:52:58 +01:00
Paul Melnikow
a0492c5283 Remove unused callback-based error helpers (#3371) 2019-04-29 13:35:57 -04:00
dependabot[bot]
ca4763b0ff Build(deps-dev): bump @babel/plugin-proposal-object-rest-spread (#3379)
Bumps [@babel/plugin-proposal-object-rest-spread](https://github.com/babel/babel) from 7.4.3 to 7.4.4.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.4.3...v7.4.4)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-29 19:19:40 +02:00
Marcin Mielnicki
2462951254 Run entrypoint tests in CI (#3390)
* Start server in test without args from mocha

* Entrypoint tests added to CI
2019-04-29 19:09:52 +02:00
dependabot[bot]
a994c13655 Build(deps-dev): bump @babel/polyfill from 7.4.3 to 7.4.4 (#3381)
Bumps [@babel/polyfill](https://github.com/babel/babel) from 7.4.3 to 7.4.4.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.4.3...v7.4.4)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-29 18:51:30 +02:00
Marcin Mielnicki
eeb78ccf15 Badge suggestion feature fix (#3331)
* Display suggested badges

* E2e test for badge suggestion

* Suggest resource returns example with pattern

* Do not require preview in MarkupModalContent

* Skip integration test for suggestion

* Unmodifiable path in customizer

* Use suggested link

* Allow to change suggested badges

* Enable skipped test

* Enable skipped test

* Code refactoring

* Code refactoring

* Code refactoring

* Code refactoring

* Code refactoring

* Code refactoring

* Unused code removed

* Unused code removed

* getExampleWithServiceByPattern helper added

* BadgeExamples uses examples instead of services definitions

* Revert "getExampleWithServiceByPattern helper added"

This reverts commit 80839fd705.

* style removed from example

* example.exact replaced with preview.buildFromExample

* keywords are required again

* Code refactoring

* More e2e tests for suggestion feature

* Code refactoring

* Build add with a base url

* showActualParams -> isPrefilled

* A new schema for BadgeExamples

* Link moved to queryParams

* Updated documentation for the suggest reponse format

* Link moved to queryParams - another test updated

* Revert "Link moved to queryParams - another test updated"

This reverts commit b5f811bb07.

* Revert "Link moved to queryParams"

This reverts commit 3b54c6d2b4.

* Disable changes in path in suggested badges

* 'link' element documentation restored
2019-04-29 18:38:27 +02:00
dependabot[bot]
2fc4e71410 Build(deps): bump check-node-version from 3.2.0 to 3.3.0 (#3386)
Bumps [check-node-version](https://github.com/parshap/check-node-version) from 3.2.0 to 3.3.0.
- [Release notes](https://github.com/parshap/check-node-version/releases)
- [Changelog](https://github.com/parshap/check-node-version/blob/master/CHANGELOG.md)
- [Commits](https://github.com/parshap/check-node-version/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-29 11:54:53 -04:00
dependabot[bot]
26a8c7c52a Build(deps-dev): bump snap-shot-it from 6.3.3 to 6.3.5 (#3382)
Bumps [snap-shot-it](https://github.com/bahmutov/snap-shot-it) from 6.3.3 to 6.3.5.
- [Release notes](https://github.com/bahmutov/snap-shot-it/releases)
- [Commits](https://github.com/bahmutov/snap-shot-it/compare/v6.3.3...v6.3.5)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-29 17:10:39 +02:00
dependabot[bot]
cc61ab31e9 Build(deps-dev): bump react-select from 2.4.2 to 2.4.3 (#3380)
Bumps [react-select](https://github.com/JedWatson/react-select) from 2.4.2 to 2.4.3.
- [Release notes](https://github.com/JedWatson/react-select/releases)
- [Changelog](https://github.com/JedWatson/react-select/blob/master/.sweet-changelogs.js)
- [Commits](https://github.com/JedWatson/react-select/compare/v2.4.2...v2.4.3)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-29 16:59:18 +02:00
dependabot[bot]
48efd0ed8f Build(deps-dev): bump husky from 1.3.1 to 2.1.0 (#3384)
Bumps [husky](https://github.com/typicode/husky) from 1.3.1 to 2.1.0.
- [Release notes](https://github.com/typicode/husky/releases)
- [Changelog](https://github.com/typicode/husky/blob/master/CHANGELOG.md)
- [Commits](https://github.com/typicode/husky/compare/v1.3.1...v2.1.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-29 16:46:55 +02:00
dependabot[bot]
722398a413 Build(deps-dev): bump mocha from 6.1.3 to 6.1.4 (#3388)
Bumps [mocha](https://github.com/mochajs/mocha) from 6.1.3 to 6.1.4.
- [Release notes](https://github.com/mochajs/mocha/releases)
- [Changelog](https://github.com/mochajs/mocha/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mochajs/mocha/compare/v6.1.3...v6.1.4)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-29 16:33:24 +02:00
Ville Skyttä
802c3cd8e8 Allow tilde as optional suffix separator (#3378)
For example [Debian] uses them, typically for pre-releases.
2019-04-29 15:11:55 +01:00
chris48s
5f29f6a175 case-insentitive asset name compare in [githubdownloads] (#3377)
closes #3364
2019-04-29 15:05:27 +01:00
Ville Skyttä
3875d292a6 Add [Debian] package version support (#3373)
https://wiki.debian.org/Services/api.ftp-master.debian.org
2019-04-29 14:58:45 +01:00
Ville Skyttä
75def85eca Add [ArchLinux] package version support (#3374) 2019-04-28 21:19:42 +01:00
Pierre-Yves B
2806eb8a00 Legacy services clean up (#3367)
* Deleted remaining legacy service bits

* Removed badge from README

* Removed no longer needed try/catch

* Deleted refactoring script

* Switched to const

* Reinstated doc

* Ran Prettier
2019-04-27 19:25:01 +01:00
Pierre-Yves B
499fb8dbaf Fixed color of GitHub forks badge (#3366) 2019-04-27 13:48:47 -04:00
Caleb Cartwright
07a8d2ecbe refactor [Scrutinizer] (#3266)
* refactor(Scrutinizer): migrated to new BaseJsonService

* refactor(ScrutinizerCoverage): updated color scale to match

* refactor(Scrutinizer): switched to multiple classes to handle dif. git hosts

* refactor(Scrutinizer): finished migrating to new service arch.

* fix(Scrutinizer): fixed branch check logic

* refactor(Scrutinizer): inline transforms based on PR feedback

* refactor(ScrutinizerCoverage): change handling of no coverage scenario
2019-04-26 21:50:28 -05:00
James Cahill
01d745122b refactor [mavencentral] (#3290)
* refactor maven central

* misc fixes

- include a pretty message on NotFound when the filter returns no results

- split the group and artifact into seperate variables

- remove the connection error test

* remove xml parsing test and add inexistent version prefix test

* use existing test validators and shorthand createservicetester
2019-04-25 18:35:50 -05:00
Paul Melnikow
2215693557 Rewrite [GithubTag] (#3360)
Ref #2863
2019-04-25 11:23:16 -04:00
Paul Melnikow
0088a9d0da Unify remaining service order and enforce (#3359)
Ref #3353
2019-04-24 16:53:33 -04:00
Paul Melnikow
f8aeb56129 Unify order of more services (#3358)
Ref #3353
2019-04-24 15:08:26 -04:00
Paul Melnikow
1dd8d1329c Unify order of another handful of services (#3356)
Ref #3353
2019-04-24 15:03:23 -04:00
Paul Melnikow
36f50f2a02 Refactor [cii] (#3357) 2019-04-24 08:36:39 -05:00
Paul Melnikow
051e7d04c1 Rewrite [travisphpversion]; improve error message in expectBadge (#3352)
The change in `expectBadge` prints a more helpful error when `message` is empty.

Ref #2863
2019-04-23 23:03:21 -04:00
Paul Melnikow
1cdcaabd38 Unify order of properties and methods in services (#3353)
I find having these in a consistent order makes the services much faster to read.

This is the order I’ve generally been using:

1. Category
2. Route
3. Examples
4. Rendering
5. Other helpers (`fetch()`, `transform()`)
6. `handle()`
2019-04-23 21:36:04 -04:00
Caleb Cartwright
12191e20c4 refactor [JenkinsTests JenkinsCoverage], also run [JenkinsBuild] (#3337)
* refactor(JenkinsTests): finished core refactor to new service model

* refactor(JenkinsTests): more updates

* refactor(JenkinsCoverage): minor refactor to leverage new common Jenkins content

* refactor(JenkinsBuild): update redirector to include shorthand alias

* chore: apply suggestion on jenkins-tests.service.js

Co-Authored-By: calebcartwright <calebcartwright@users.noreply.github.com>

* refactor(JenkinsTests): rename test helpers

* chore: cleanup JenkinsCoverage redirector

* chore: cleanup JenkinsBuild redirector

* chore: cleanup test docs
2019-04-23 20:20:34 -05:00
Paul Melnikow
8ad0b105b1 Make the config from env more obvious at first glance; explain cascading config (#3355) 2019-04-23 13:57:23 -04:00
Caleb Cartwright
6547a5765c chore: minor cleanup (#3354) 2019-04-23 10:22:47 -04:00
Guy Saar
d3ec64c789 [Bit] add bit components count service (#3338)
* [Bit] add bit components count service

* [Bit] change 404 error to 'collection not found'

* [Bit] remove comment

* [Bit] change collection schema

* [Bit] use isMetric

* [Bit] replace static color to dynamic color

* [BIt] change bit total components route

* change scope to collection

* change all scope var to collection
2019-04-23 06:54:51 -05:00
Paul Melnikow
ca22d01606 Rewrite [GithubDownloads] (#3351)
For consistency with other download badges, I changed some formatting:

-  **downloads | 24k total** -> **downloads | 24k**
- **downloads | 3k** -> **downloads@latest | 3k**
- **downloads | 3k v0.29.0** -> **downloads@v0.29.0 | 3k**

Ref #2863
2019-04-22 22:55:31 -04:00
Paul Melnikow
f13326dddf Rewrite [githubcommitssince]; also test [githubrelease] (#3350) 2019-04-22 18:54:58 -05:00
dependabot[bot]
aa32f48765 Build(deps-dev): bump gatsby-plugin-react-helmet from 3.0.10 to 3.0.12 (#3347)
Bumps [gatsby-plugin-react-helmet](https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-plugin-react-helmet) from 3.0.10 to 3.0.12.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-react-helmet/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-react-helmet@3.0.12/packages/gatsby-plugin-react-helmet)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-22 18:45:52 -05:00
dependabot[bot]
d5cc72b3a8 Build(deps-dev): bump babel-plugin-istanbul from 5.1.1 to 5.1.2 (#3344)
Bumps [babel-plugin-istanbul](https://github.com/istanbuljs/babel-plugin-istanbul) from 5.1.1 to 5.1.2.
- [Release notes](https://github.com/istanbuljs/babel-plugin-istanbul/releases)
- [Changelog](https://github.com/istanbuljs/babel-plugin-istanbul/blob/master/CHANGELOG.md)
- [Commits](https://github.com/istanbuljs/babel-plugin-istanbul/compare/v5.1.1...v5.1.2)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-22 18:35:05 -05:00
dependabot[bot]
35d328b222 Build(deps): bump camelcase from 5.2.0 to 5.3.1 (#3349)
Bumps [camelcase](https://github.com/sindresorhus/camelcase) from 5.2.0 to 5.3.1.
- [Release notes](https://github.com/sindresorhus/camelcase/releases)
- [Commits](https://github.com/sindresorhus/camelcase/compare/v5.2.0...v5.3.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-22 21:09:24 +01:00
dependabot[bot]
7f2e0f5913 Build(deps-dev): bump clipboard-copy from 2.0.1 to 3.0.0 (#3346)
Bumps [clipboard-copy](https://github.com/feross/clipboard-copy) from 2.0.1 to 3.0.0.
- [Release notes](https://github.com/feross/clipboard-copy/releases)
- [Commits](https://github.com/feross/clipboard-copy/compare/v2.0.1...v3.0.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-22 20:53:23 +01:00
dependabot[bot]
884a6041dd Build(deps-dev): bump gatsby from 2.3.22 to 2.3.25 (#3343)
Bumps [gatsby](https://github.com/gatsbyjs/gatsby) from 2.3.22 to 2.3.25.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/compare/gatsby@2.3.22...gatsby@2.3.25)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-22 20:48:00 +01:00
dependabot[bot]
093b5d19ed Build(deps-dev): bump humanize-string from 1.0.2 to 2.1.0 (#3340)
Bumps [humanize-string](https://github.com/sindresorhus/humanize-string) from 1.0.2 to 2.1.0.
- [Release notes](https://github.com/sindresorhus/humanize-string/releases)
- [Commits](https://github.com/sindresorhus/humanize-string/compare/v1.0.2...v2.1.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-22 20:42:30 +01:00
dependabot[bot]
3db3552dde Build(deps-dev): bump is-png from 1.1.0 to 2.0.0 (#3342)
Bumps [is-png](https://github.com/sindresorhus/is-png) from 1.1.0 to 2.0.0.
- [Release notes](https://github.com/sindresorhus/is-png/releases)
- [Commits](https://github.com/sindresorhus/is-png/compare/v1.1.0...v2.0.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-22 20:35:38 +01:00
dependabot[bot]
90fc3e65d8 Build(deps-dev): bump opn-cli from 4.0.0 to 4.1.0 (#3341)
Bumps [opn-cli](https://github.com/sindresorhus/opn-cli) from 4.0.0 to 4.1.0.
- [Release notes](https://github.com/sindresorhus/opn-cli/releases)
- [Commits](https://github.com/sindresorhus/opn-cli/compare/v4.0.0...v4.1.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-22 12:45:50 -05:00
dependabot[bot]
b800cfed0f Build(deps-dev): bump sinon from 7.3.1 to 7.3.2 (#3348)
Bumps [sinon](https://github.com/sinonjs/sinon) from 7.3.1 to 7.3.2.
- [Release notes](https://github.com/sinonjs/sinon/releases)
- [Changelog](https://github.com/sinonjs/sinon/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sinonjs/sinon/compare/v7.3.1...v7.3.2)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-22 12:13:20 -05:00
dependabot[bot]
1e8f0b05c9 Build(deps-dev): bump nock from 11.0.0-beta.6 to 11.0.0-beta.10 (#3345)
Bumps [nock](https://github.com/nock/nock) from 11.0.0-beta.6 to 11.0.0-beta.10.
- [Release notes](https://github.com/nock/nock/releases)
- [Changelog](https://github.com/nock/nock/blob/beta/CHANGELOG.md)
- [Commits](https://github.com/nock/nock/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-22 10:55:23 -05:00
Paul Melnikow
5828223356 Refactor [Wordpress] services (#3324)
- Prefer inline transforms to take place in `handle()` rather than `render()`
- Avoid inversion of control by removing `BaseWordpress#handle()`, passing `extensionType` into `fetch()`, and removing one layer of subclassing
- Move “not found” checks into `fetch()`
- Cache wordpress versions instead of fetching on each request
- Start to convert aliases to redirects (there are more of these which could be tackled in a follow-on)
- Replace at least one route `format` with a `pattern` (ref #3329)
- Partially reorder: name, category, route, examples, defaultBadgeData, render, fetch, handle

Some of this is in line with our established patterns or makes it clearly easier to follow; some of it is arguably stylistic.
2019-04-22 10:45:25 -05:00
chris48s
05af1f82b2 refactor [vaadindirectory] badges (#3339) 2019-04-21 21:10:30 +01:00
Paul Melnikow
b55e3eef60 Rewrite [codeclimate] analysis (#3321)
* WIP

* Rewrite [codeclimate] analysis

Ref #2683

* Tweak names

* chore: tweak redirector category
2019-04-21 11:44:07 -05:00
Paul Melnikow
a291ba73a3 Use url pattern for [nexus] + minor cleanup (#3326)
* Use url `pattern` for [nexus]

* chore: minor nexus example tweaks

* chore: fix prettier issue

* refactor(Nexus): minor refactor to fix tests and examples

* chore: increase timeout on nexus service tests

* chore: prettified for prettier

* tests(Nexus): increase timeout for recurringly slow test

* chore: update nexus schema with docs
2019-04-20 16:23:42 -05:00
Caleb Cartwright
049057c230 add strictSSL query param toggle to [coverity] (#3336)
* feat(coverity): adding query param toggle for strict ssl

* feat: disable coverity strict ssl check by default
2019-04-20 13:52:48 -05:00
Caleb Cartwright
a144f957b6 refactor [JenkinsBuild] (#3302)
* refactor(JenkinsBuild): ported to new service model

* refactor(JenkinsBuild): added redirector for jenkins-ci route

* refactor(JenkinsBuild): trying to debug test on circle

* refactor(JenkinsBuild): fix test of mock creds

* chore: fix typo in wrong file 🤦

* refactor(JenkinsBuild): update route

* refactor(JenkinsBuild): fixed service test

* refactor(JenkinsBuild): made strictSSL configurable via QP
2019-04-19 15:34:21 -05:00
Caleb Cartwright
4ae393565a refactor: deprecated php-eye/hhvm badges (#3335) 2019-04-18 21:05:38 -05:00
Paul Melnikow
b069dbbaad Use route patterns in [snap-ci nsp gratipay githubmanifest codacy cauditor bithound] (#3327)
Ref #3329
2019-04-18 18:15:48 -05:00
Paul Melnikow
066193c002 Readme: Update node compatibility (#3330) 2019-04-17 15:15:46 -04:00
Paul Melnikow
d1f00b93e8 [security] Bump nyc from 13.3.0 to 14.0.0 (#3323) 2019-04-17 14:51:56 -04:00
Paul Melnikow
b431923e35 Minor rename in [node] (#3325) 2019-04-17 13:13:24 -04:00
Paul Melnikow
5bedbbd9c1 [security] npm audit fixes; ignore [security] in PR title (#3322) 2019-04-17 11:30:34 -04:00
Pierre-Yves B
0a9611d574 Migrated JenkinsPluginVersion to new service architecture (#3317) 2019-04-17 06:53:45 +01:00
Paul Melnikow
cffa29dd5c Fix [codeclimatecoverage] coverage-percentage route (#3320) 2019-04-16 23:39:03 -04:00
Paul Melnikow
fc5cd07a0f Consolidate [DubDownloads] into one service (#3319)
Same idea as #3318.
2019-04-16 21:50:15 -04:00
Paul Melnikow
b79d1952c0 Consolidate [NpmDownloads] into one service (#3318)
This moves the four npm download services into a single class, in line with #3174, and other service implementations we've written in the last couple months. 

1. Change the suffixes from **/m** to **/month** for consistency.
2. Add tests of one of the intervals besides total.
3. Rewrite mocked service tests as unit tests.
4. Use (and work with) the `intervalMap` pattern that I think @calebcartwright started us using.
2019-04-16 19:18:16 -04:00
Cedric van Putten
483ecf24de [Drone] Add Drone build badge (#3240)
* Add drone build badge based on travis

* Fix wrong mocked endpoint for done builder

* Refactor service tester using helper method

* Add missing failure status to red statuses

* Remove extraneous invalid svg test from drone

* Test on failure red status in build status spec

* refactor(drone): use json service instead of svg

* refactor(drone): remove status text and extraneous build path in test

* refactor(drone): allow defining self-hosted drone instances

* fix(drone): use proper urls in drone examples

* fix(drone): add drone token authorization for self-hosted instances

* refactor(drone): call render build status badge directly instead of render

* refactor(drone): use server query parameter for self-hosted instances

* fix(drone): separate url and query params in example

* fix(drone): use actual build status message in examples

* fix(drone): add missing message for status code 401

Co-Authored-By: byCedric <me@bycedric.com>

* refactor(drone): remove color from drone tests

* refactor(drone): remove extraneous comments from drone tests

* refactor(drone): remove unused static preview method

* refactor(drone): remove unused static render method

* refactor(drone): reuse render build status badge helper in static previews

* fix(drone): test inaccessible repos on new message
2019-04-16 11:33:15 -05:00
Paul Melnikow
91d6dd6643 Rewrite [codeclimate] coverage (#3316)
Attacking this in two pieces for ease of review. The legacy implementation for coverage is still there, though I disabled it via the route. That whole file will be removed in the next PR.

Ref #2863
2019-04-15 23:47:25 -04:00
Caleb Cartwright
700b61e16b Refactor [Sonar] (#3189)
* refactor(sonar)

* refactor(sonarqube): creating separate services for SQ badges

* refactor(sonar): more sonar refactorings

* refactor(sonar): fixed duplicate service names from c/p

* refactor(sonar): finished violations service impl

* refactor(sonar): finished unit tests for violations service

* feat(sonar): violation badge updates

* refactor(sonar): finished doc. api density service

* feat(sonar): added quality gate service

* chore: sonar doc tweaks

* refactor(sonar): added redirector service

* refactor(sonar): added examples

* refactor(sonar): minor example updates

* refactor(sonar): added final tests

* chore(sonar): removed unneeded test spec file for base class

* refactor(sonar): updates based on PR feedback

* refactor(sonar): change query param to sonarVersion

* refactor(sonar): fixing query param issue

* refactor(sonar): fix test color for generic metric

* chore: fix lint/prettier issue

* chore(sonar): update query param name in examples

* refactor(sonar): make schema metric key required

* reactor(sonar): fix tests

* refactor(sonar): added more example listings

* refactor(sonar): minor style updates

* refactor(sonar): update examples

* refactor(Sonar): minor example tweaks
2019-04-15 17:03:57 -05:00
dependabot[bot]
c2472f3397 Bump config from 3.0.1 to 3.1.0 (#3311)
Bumps [config](https://github.com/lorenwest/node-config) from 3.0.1 to 3.1.0.
- [Release notes](https://github.com/lorenwest/node-config/releases)
- [Changelog](https://github.com/lorenwest/node-config/blob/master/History.md)
- [Commits](https://github.com/lorenwest/node-config/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-15 14:06:39 -04:00
dependabot[bot]
1684f1ac51 Bump snap-shot-it from 6.2.10 to 6.3.3 (#3312)
Bumps [snap-shot-it](https://github.com/bahmutov/snap-shot-it) from 6.2.10 to 6.3.3.
- [Release notes](https://github.com/bahmutov/snap-shot-it/releases)
- [Commits](https://github.com/bahmutov/snap-shot-it/compare/v6.2.10...v6.3.3)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-15 13:38:26 -04:00
dependabot[bot]
f3303c4a41 Bump gatsby from 2.1.19 to 2.3.22 (#3307)
Bumps [gatsby](https://github.com/gatsbyjs/gatsby) from 2.1.19 to 2.3.22.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/compare/gatsby@2.1.19...gatsby@2.3.22)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-15 13:11:07 -04:00
Caleb Cartwright
89e749f714 fix [gratipay] test (#3303)
Not really sure what happened, but the test for the deprecated gratipay/gittp service has been failing for a while with a 404 badge not found error. For example

`AssertionError: label mismatch: expected '404' to equal 'gratipay'`

This tweaks the rout pattern so the test is passing again.
2019-04-15 13:05:30 -04:00
dependabot[bot]
709554daa4 Bump danger from 7.1.0 to 7.1.2 (#3308)
Bumps [danger](https://github.com/danger/danger-js) from 7.1.0 to 7.1.2.
- [Release notes](https://github.com/danger/danger-js/releases)
- [Changelog](https://github.com/danger/danger-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/danger/danger-js/compare/7.1.0...7.1.2)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-15 12:58:38 -04:00
Caleb Cartwright
9221075d31 fix [sourcegraph] test (#3304) 2019-04-15 12:53:15 -04:00
Caleb Cartwright
263e1be06d tests(Maintenance): refactor and test (#3305)
One of the tests for the Maintenance service that was added when the service was refactored is failing 
`AssertionError: message mismatch: expected 'no! (as of 2018)' to equal 'stale (as of 2019)'`

I believe the test was added in an attempt to cover the one of the code paths, but that original test would only pass a couple months out of the year. 

Testing those paths with the original implementation would have required a lot of stubbing clocks/timers, so instead I refactored the code a bit. I removed the flaky live/service test, and added some unit tests instead (which made more sense to me since this service badge doesn't hit a live endpoint)
2019-04-15 12:47:06 -04:00
dependabot[bot]
9598d80bdd Bump is-svg from 3.0.0 to 4.1.0 (#3315)
Bumps [is-svg](https://github.com/sindresorhus/is-svg) from 3.0.0 to 4.1.0.
- [Release notes](https://github.com/sindresorhus/is-svg/releases)
- [Commits](https://github.com/sindresorhus/is-svg/compare/v3.0.0...v4.1.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-15 12:41:31 -04:00
dependabot[bot]
765d6ddc23 Bump @babel/plugin-proposal-object-rest-spread from 7.3.4 to 7.4.3 (#3309)
Bumps [@babel/plugin-proposal-object-rest-spread](https://github.com/babel/babel) from 7.3.4 to 7.4.3.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.3.4...v7.4.3)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-15 08:22:35 -05:00
dependabot[bot]
ab08541b71 Bump @babel/polyfill from 7.2.5 to 7.4.3 (#3310)
Bumps [@babel/polyfill](https://github.com/babel/babel) from 7.2.5 to 7.4.3.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.2.5...v7.4.3)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-15 08:04:29 -05:00
dependabot[bot]
b7fb6ed853 Bump @babel/core from 7.4.0 to 7.4.3 (#3314)
Bumps [@babel/core](https://github.com/babel/babel) from 7.4.0 to 7.4.3.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.4.0...v7.4.3)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-15 07:50:48 -05:00
dependabot[bot]
de4a289cdf Bump eslint-plugin-import from 2.16.0 to 2.17.1 (#3313)
Bumps [eslint-plugin-import](https://github.com/benmosher/eslint-plugin-import) from 2.16.0 to 2.17.1.
- [Release notes](https://github.com/benmosher/eslint-plugin-import/releases)
- [Changelog](https://github.com/benmosher/eslint-plugin-import/blob/master/CHANGELOG.md)
- [Commits](https://github.com/benmosher/eslint-plugin-import/compare/v2.16.0...v2.17.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-15 07:09:10 -05:00
dependabot[bot]
335fca170b Bump mocha from 6.1.1 to 6.1.3 (#3306)
Bumps [mocha](https://github.com/mochajs/mocha) from 6.1.1 to 6.1.3.
- [Release notes](https://github.com/mochajs/mocha/releases)
- [Changelog](https://github.com/mochajs/mocha/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mochajs/mocha/compare/v6.1.1...v6.1.3)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-15 06:43:52 -05:00
Tesla_Ice_Zhang
e12e625141 Add pull request merge/open/closed badge (#3295) 2019-04-14 09:57:26 -05:00
Paul Melnikow
ab95e8415f Rewrite [GitHubForks] (#3299) 2019-04-13 20:12:31 -04:00
Paul Melnikow
11cd0bdbc5 Split up [codeclimate] tests (#3300)
* Split up [codeclimate] tests

* Fix copy-pasta
2019-04-13 18:47:59 -05:00
Paul Melnikow
d343fddb2c Rewrite [dynamicxml] tests, and fix issue with attribute filters (#3298)
This fixes queries with an attribute filter in the middle, such as //book[@id='bk102']/title.

Close #3089
2019-04-13 15:06:36 -04:00
Paul Melnikow
64b6e6c81c Bump anafanafo from 0.1.0 to 1.0.0 (#3296) 2019-04-13 12:47:44 -04:00
Eray Erdin
6935be5d50 [Jitpack] Added Downloads Badge (#3291)
* added jitpack downloads pack

* added jitpack downloads badge

* used isMetricOverTimePeriod in jitpack-downloads.tester
2019-04-12 08:09:56 -05:00
Paul Melnikow
2e1d47baed Prettier: Enforce standard line endings (#3293)
This requires lf (typical for git repos, Linux, Mac OS) rather than crlf (typical for Windows).
2019-04-11 20:23:40 -04:00
Paul Melnikow
4a85d08059 Prettier now has a --check option (#3292) 2019-04-11 18:55:30 -04:00
dependabot[bot]
f86dbb4fbf Bump tmp from 0.0.33 to 0.1.0 (#3283)
Bumps [tmp](https://github.com/raszi/node-tmp) from 0.0.33 to 0.1.0.
- [Release notes](https://github.com/raszi/node-tmp/releases)
- [Commits](https://github.com/raszi/node-tmp/compare/v0.0.33...v0.1.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-10 19:26:28 +01:00
dependabot[bot]
df406bf40d Bump decamelize from 3.1.1 to 3.2.0 (#3279)
Bumps [decamelize](https://github.com/sindresorhus/decamelize) from 3.1.1 to 3.2.0.
- [Release notes](https://github.com/sindresorhus/decamelize/releases)
- [Commits](https://github.com/sindresorhus/decamelize/compare/v3.1.1...v3.2.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-09 21:17:35 +01:00
dependabot[bot]
2f10f7d9c9 Bump js-yaml from 3.12.2 to 3.13.1 (#3277)
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 3.12.2 to 3.13.1.
- [Release notes](https://github.com/nodeca/js-yaml/releases)
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/3.12.2...3.13.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-09 21:11:59 +01:00
dependabot[bot]
b6eae86e5b Bump query-string from 6.4.0 to 6.4.2 (#3280)
Bumps [query-string](https://github.com/sindresorhus/query-string) from 6.4.0 to 6.4.2.
- [Release notes](https://github.com/sindresorhus/query-string/releases)
- [Commits](https://github.com/sindresorhus/query-string/compare/v6.4.0...v6.4.2)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-09 21:05:39 +01:00
dependabot[bot]
efe41428fe Bump enzyme-adapter-react-16 from 1.9.1 to 1.12.1 (#3285)
Bumps [enzyme-adapter-react-16](https://github.com/airbnb/enzyme/tree/HEAD/packages/enzyme-adapter-react-16) from 1.9.1 to 1.12.1.
- [Release notes](https://github.com/airbnb/enzyme/releases)
- [Changelog](https://github.com/airbnb/enzyme/blob/master/CHANGELOG.md)
- [Commits](https://github.com/airbnb/enzyme/commits/enzyme-adapter-react-16@1.12.1/packages/enzyme-adapter-react-16)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-09 20:55:08 +01:00
dependabot[bot]
e73df6eda4 Bump fast-xml-parser from 3.12.13 to 3.12.16 (#3284)
Bumps [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) from 3.12.13 to 3.12.16.
- [Release notes](https://github.com/NaturalIntelligence/fast-xml-parser/releases)
- [Changelog](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md)
- [Commits](https://github.com/NaturalIntelligence/fast-xml-parser/commits/3.12.16)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-09 17:39:54 +02:00
dependabot[bot]
268abae623 Bump eslint-plugin-promise from 4.0.1 to 4.1.1 (#3281)
Bumps [eslint-plugin-promise](https://github.com/xjamundx/eslint-plugin-promise) from 4.0.1 to 4.1.1.
- [Release notes](https://github.com/xjamundx/eslint-plugin-promise/releases)
- [Changelog](https://github.com/xjamundx/eslint-plugin-promise/blob/master/CHANGELOG.md)
- [Commits](https://github.com/xjamundx/eslint-plugin-promise/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-09 07:35:16 -04:00
dependabot[bot]
8f845b6ef7 Bump babel-preset-gatsby from 0.1.8 to 0.1.11 (#3286)
Bumps babel-preset-gatsby from 0.1.8 to 0.1.11.

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-09 07:19:16 -04:00
Pierre-Yves B
fd5553b810 [Node] tests improvements (#3288) 2019-04-08 20:44:28 +01:00
dependabot[bot]
be65f6eaf6 Bump prom-client from 11.2.1 to 11.3.0 (#3287)
Bumps [prom-client](https://github.com/siimon/prom-client) from 11.2.1 to 11.3.0.
- [Release notes](https://github.com/siimon/prom-client/releases)
- [Changelog](https://github.com/siimon/prom-client/blob/master/CHANGELOG.md)
- [Commits](https://github.com/siimon/prom-client/compare/v11.2.1...v11.3.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-08 20:53:22 +02:00
dependabot[bot]
f831fc11d8 Bump mocha-junit-reporter from 1.18.0 to 1.21.0 (#3278)
Bumps [mocha-junit-reporter](https://github.com/michaelleeallen/mocha-junit-reporter) from 1.18.0 to 1.21.0.
- [Release notes](https://github.com/michaelleeallen/mocha-junit-reporter/releases)
- [Commits](https://github.com/michaelleeallen/mocha-junit-reporter/compare/v1.18.0...v1.21.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-08 06:44:10 -05:00
dependabot[bot]
fc0e456de2 Bump mocha from 6.0.2 to 6.1.1 (#3282)
Bumps [mocha](https://github.com/mochajs/mocha) from 6.0.2 to 6.1.1.
- [Release notes](https://github.com/mochajs/mocha/releases)
- [Changelog](https://github.com/mochajs/mocha/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mochajs/mocha/compare/v6.0.2...v6.1.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-08 06:26:34 -05:00
Paul Melnikow
991d4a1cad Bump Danger (which now ships with Chainsmoker!) and some housekeeping (#3276)
See https://github.com/danger/danger-js/issues/431#issuecomment-480269809 and danger/danger-js#850
2019-04-07 14:06:22 -05:00
chris48s
83c3c70908 refactor [puppetforge] service, add tests (#3275)
This migrates the puppetforge-modules from legacy
services to the new service arch
There are also some changes to the puppetforge-users
badges, but its just moving code around
2019-04-07 19:35:30 +01:00
Pierre-Yves B
25f8541e5b JSON format modernisation and _shields_test removal (#3272)
* Modernised JSON format and removed _shields_test style

* Added logoWidth and labelColor fields to JSON response

* Reinstated and updated comment

* Extended expectBadge to accept Joi schemas for all fields
2019-04-07 18:57:55 +01:00
Caleb Cartwright
93333509c6 Fix [NpmDependencyVersion] (#3274)
* fix(NpmDependencyVersion): refs #3271

* refactor(NpmDependencyVersion): tweaked route based on PR feedback
2019-04-07 12:28:11 +01:00
Pierre-Yves B
167fb89ff0 Updated IcedFrisby version (#3270) 2019-04-05 21:57:08 +01:00
dependabot[bot]
18b3f97879 Bump react-dom from 16.8.5 to 16.8.6 (#3254)
Bumps [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom) from 16.8.5 to 16.8.6.
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v16.8.6/packages/react-dom)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-05 17:58:11 +02:00
Marcin Mielnicki
9e3bc86a5e In CI, run e2e tests on the build (#3269)
* In CI, run e2e tests on the build

* Windows compatibility in "e2e-on-build" script

Co-Authored-By: platan <marcin.mielnicki@gmail.com>
2019-04-04 23:42:03 +02:00
dependabot[bot]
afec96c9cd Bump react-error-overlay from 5.1.3 to 5.1.4 (#3255)
Bumps [react-error-overlay](https://github.com/facebook/create-react-app) from 5.1.3 to 5.1.4.
- [Release notes](https://github.com/facebook/create-react-app/releases)
- [Changelog](https://github.com/facebook/create-react-app/blob/master/CHANGELOG-1.x.md)
- [Commits](https://github.com/facebook/create-react-app/compare/react-error-overlay@5.1.3...react-error-overlay@5.1.4)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-04 04:57:13 -07:00
dependabot[bot]
3929b5aad0 Bump @babel/register from 7.0.0 to 7.4.0 (#3248)
Bumps [@babel/register](https://github.com/babel/babel) from 7.0.0 to 7.4.0.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.0.0...v7.4.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-04 04:34:21 -07:00
dependabot[bot]
37bdc96ca7 Bump react-pose from 4.0.7 to 4.0.8 (#3252)
Bumps [react-pose](https://github.com/Popmotion/popmotion) from 4.0.7 to 4.0.8.
- [Release notes](https://github.com/Popmotion/popmotion/releases)
- [Commits](https://github.com/Popmotion/popmotion/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-04 04:29:33 -07:00
Paul Melnikow
766d55e001 [pypi] Improve formatting of trove-based licenses (#3265)
Currently the trove-based license classifiers generate different formatting than the legacy license classifiers. This brings them into alignment.
2019-04-04 04:22:47 -07:00
Denis Duliçi
48e454c63d Fixed GitHub release downloads, run [GithubDownloads] (#3256)
* fixed github release downloads

* npm run prettier code push.

* master package-lock.json file
2019-04-03 17:28:48 -05:00
Caleb Cartwright
7f24e93671 refactor [GithubIssueDetail] (#3259)
* refactor(GithubIssueDetail): ported to new service model

* refactor(GithubIssueDetail): updates based on PR discussions

* refactor(GithubIssueDetail): minor updates and additional tests

* refactor(GithubIssueDetail): minor updates to render functions per PR disc.
2019-04-03 11:59:49 -05:00
Caleb Cartwright
4b81f824d9 refactor(GithubIssues) (#3263) 2019-04-03 10:26:03 -05:00
dependabot[bot]
65487f5a57 Bump decamelize from 2.0.0 to 3.1.1 (#3247)
Bumps [decamelize](https://github.com/sindresorhus/decamelize) from 2.0.0 to 3.1.1.
- [Release notes](https://github.com/sindresorhus/decamelize/releases)
- [Commits](https://github.com/sindresorhus/decamelize/compare/v2.0.0...v3.1.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-02 17:23:59 -05:00
dependabot[bot]
9c858dafbe Bump dotenv from 6.2.0 to 7.0.0 (#3246)
Bumps [dotenv](https://github.com/motdotla/dotenv) from 6.2.0 to 7.0.0.
- [Release notes](https://github.com/motdotla/dotenv/releases)
- [Changelog](https://github.com/motdotla/dotenv/blob/master/CHANGELOG.md)
- [Commits](https://github.com/motdotla/dotenv/compare/v6.2.0...v7.0.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-02 16:53:22 -05:00
Marcin Mielnicki
c81b482082 End to end tests (#3262)
* Frontend test using Cypress

* test:end-to-end script added

* cypress and eslint-plugin-cypress moved to dev dependencies

* Run end-to-end tests at CI using end2end script

* cypress/screenshots/ added to gitignore

* end2end job added

* Dedicated docker image for Cypress

* Store videos and screenshots

* Prepare and store junit report

* Use junit reporter

* Code refactoring

* Code refactoring

* Code refactoring

* lint-staged for json, md and yml files

* Format json config

* Assert that PyPI - License is displayed

* Do not create fixtures
2019-04-02 22:25:37 +02:00
dependabot[bot]
e701d36277 Bump semver from 5.6.0 to 6.0.0 (#3253)
Bumps [semver](https://github.com/npm/node-semver) from 5.6.0 to 6.0.0.
- [Release notes](https://github.com/npm/node-semver/releases)
- [Changelog](https://github.com/npm/node-semver/blob/master/CHANGELOG.md)
- [Commits](https://github.com/npm/node-semver/compare/v5.6.0...v6.0.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-02 15:14:56 -05:00
dependabot[bot]
d8fef68628 Bump simple-icons from 1.9.23 to 1.9.24 (#3251)
Bumps [simple-icons](https://github.com/simple-icons/simple-icons) from 1.9.23 to 1.9.24.
- [Release notes](https://github.com/simple-icons/simple-icons/releases)
- [Commits](https://github.com/simple-icons/simple-icons/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-02 08:39:11 -07:00
Caleb Cartwright
c2f44cc284 Fix [TeamCity] build (#3245)
Fix #3244

Updated schema validation on statusText field to account for additional text suffixes
2019-04-02 08:36:21 -07:00
dependabot[bot]
23538fe8d7 Bump sinon from 7.2.6 to 7.3.1 (#3249)
Bumps [sinon](https://github.com/sinonjs/sinon) from 7.2.6 to 7.3.1.
- [Release notes](https://github.com/sinonjs/sinon/releases)
- [Changelog](https://github.com/sinonjs/sinon/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sinonjs/sinon/compare/v7.2.6...v7.3.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-02 08:10:54 -07:00
Eray Erdin
c7b37a5de8 Fixed [Jitpack] Badges According to Shields Convention (#3257)
* added fixed jitpack badge

* removing accidental pasted file

* updated transformPath for jitpack-version-redirector service

* refactored jitpack.*.js to jitpack-version.*.js
2019-04-01 17:25:39 -05:00
dependabot[bot]
1421d3a950 Bump eslint from 5.15.3 to 5.16.0 (#3250)
Bumps [eslint](https://github.com/eslint/eslint) from 5.15.3 to 5.16.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v5.15.3...v5.16.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-01 09:12:01 -07:00
chris48s
a12ece3d7c refactor [twitter] service (#3241)
* refactor [twitter] service

* pass screen_names in options.qs
2019-03-31 14:00:37 -05:00
Caleb Cartwright
b03b644451 Fix [packagist] badges (#3239)
* fix(packagist): updated schema and version svc to resolve #3238

* refactor(packagist): multiple changes relative to #3238
2019-03-31 09:45:13 -05:00
James Cahill
f0e037e040 refactor [Packagist] service (#3004) 2019-03-27 17:59:41 -04:00
Paul Melnikow
bd92aef3bc Bump gatsby-plugin-page-creator (#3237)
Ref gatsbyjs/gatsby#11304

Fix #3209 Fix #3208
2019-03-27 16:55:14 -04:00
chris48s
96d416068c rewrite Github Languages, split into [githubcodesize githublanguagecount githubtoplanguage] (#3225) 2019-03-25 20:54:58 -04:00
dependabot[bot]
b269661333 Bump gatsby-plugin-styled-components from 3.0.6 to 3.0.7 (#3229)
Bumps [gatsby-plugin-styled-components](https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-plugin-styled-components) from 3.0.6 to 3.0.7.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-styled-components/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-styled-components@3.0.7/packages/gatsby-plugin-styled-components)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-25 20:02:35 +00:00
dependabot[bot]
68df6a58ed Bump @babel/plugin-proposal-class-properties from 7.3.4 to 7.4.0 (#3226)
Bumps [@babel/plugin-proposal-class-properties](https://github.com/babel/babel) from 7.3.4 to 7.4.0.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.3.4...v7.4.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-25 19:46:05 +00:00
dependabot[bot]
8b463a03a4 Bump react from 16.8.3 to 16.8.5 (#3228)
Bumps [react](https://github.com/facebook/react/tree/HEAD/packages/react) from 16.8.3 to 16.8.5.
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v16.8.5/packages/react)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-25 19:39:30 +00:00
dependabot[bot]
ae6fe1d4ca Bump @babel/core from 7.3.4 to 7.4.0 (#3232)
Bumps [@babel/core](https://github.com/babel/babel) from 7.3.4 to 7.4.0.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.3.4...v7.4.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-25 19:36:13 +00:00
dependabot[bot]
324eaf2ef2 Bump gatsby-plugin-remove-trailing-slashes from 2.0.7 to 2.0.10 (#3231)
Bumps [gatsby-plugin-remove-trailing-slashes](https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-plugin-remove-trailing-slashes) from 2.0.7 to 2.0.10.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-remove-trailing-slashes/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-remove-trailing-slashes@2.0.10/packages/gatsby-plugin-remove-trailing-slashes)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-25 19:30:11 +00:00
dependabot[bot]
ff7c380eac Bump styled-components from 4.1.3 to 4.2.0 (#3235)
Bumps [styled-components](https://github.com/styled-components/styled-components) from 4.1.3 to 4.2.0.
- [Release notes](https://github.com/styled-components/styled-components/releases)
- [Changelog](https://github.com/styled-components/styled-components/blob/master/CHANGELOG.md)
- [Commits](https://github.com/styled-components/styled-components/compare/v4.1.3...styled-components@4.2.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-25 19:27:04 +00:00
dependabot[bot]
5762b5cfd5 Bump react-dom from 16.8.4 to 16.8.5 (#3230)
Bumps [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom) from 16.8.4 to 16.8.5.
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v16.8.5/packages/react-dom)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-25 19:23:34 +00:00
dependabot[bot]
776cdbbfc7 Bump eslint-plugin-react-hooks from 1.5.1 to 1.6.0 (#3227)
Bumps [eslint-plugin-react-hooks](https://github.com/facebook/react/tree/HEAD/packages/eslint-plugin-react-hooks) from 1.5.1 to 1.6.0.
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/HEAD/packages/eslint-plugin-react-hooks)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-25 19:19:00 +00:00
dependabot[bot]
7b221c1943 Bump mocha from 6.0.1 to 6.0.2 (#3234)
Bumps [mocha](https://github.com/mochajs/mocha) from 6.0.1 to 6.0.2.
- [Release notes](https://github.com/mochajs/mocha/releases)
- [Changelog](https://github.com/mochajs/mocha/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mochajs/mocha/compare/v6.0.1...v6.0.2)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-25 19:16:04 +00:00
dependabot[bot]
cbbe06cb46 Bump eslint from 5.15.2 to 5.15.3 (#3233)
Bumps [eslint](https://github.com/eslint/eslint) from 5.15.2 to 5.15.3.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v5.15.2...v5.15.3)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-25 19:11:26 +00:00
dependabot[bot]
4d40f44ded Bump @babel/plugin-proposal-class-properties from 7.3.3 to 7.3.4 (#3194)
Bumps [@babel/plugin-proposal-class-properties](https://github.com/babel/babel) from 7.3.3 to 7.3.4.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.3.3...v7.3.4)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-24 12:10:21 -04:00
chris48s
d59785b35d refactor [puppetforgeusers], add tests (#3224) 2019-03-24 11:55:28 -04:00
tooomm
4911e11584 add more helpful syntax links to dynamic badges (#3223) 2019-03-22 22:00:10 +00:00
chris48s
4f5268aa0f refactor [githubreleasedate] (#3206) 2019-03-18 17:36:17 -05:00
chris48s
5706b82f92 throw Deprecated() when [waffle] shuts down (#3219) 2019-03-18 17:29:34 -05:00
dependabot[bot]
e209db37e5 Bump gatsby-plugin-catch-links from 2.0.12 to 2.0.13 (#3214)
Bumps [gatsby-plugin-catch-links](https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-plugin-catch-links) from 2.0.12 to 2.0.13.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-catch-links/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-catch-links@2.0.13/packages/gatsby-plugin-catch-links)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-18 21:39:09 +00:00
dependabot[bot]
70be83d250 Bump gatsby-plugin-react-helmet from 3.0.8 to 3.0.10 (#3211)
Bumps [gatsby-plugin-react-helmet](https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-plugin-react-helmet) from 3.0.8 to 3.0.10.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-react-helmet/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-react-helmet@3.0.10/packages/gatsby-plugin-react-helmet)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-18 21:36:35 +00:00
dependabot[bot]
7f7f941d9c Bump react-select from 2.4.1 to 2.4.2 (#3217)
Bumps [react-select](https://github.com/JedWatson/react-select) from 2.4.1 to 2.4.2.
- [Release notes](https://github.com/JedWatson/react-select/releases)
- [Changelog](https://github.com/JedWatson/react-select/blob/master/.sweet-changelogs.js)
- [Commits](https://github.com/JedWatson/react-select/compare/v2.4.1...v2.4.2)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-18 21:29:16 +00:00
dependabot[bot]
85478b5e51 Bump query-string from 6.3.0 to 6.4.0 (#3213)
Bumps [query-string](https://github.com/sindresorhus/query-string) from 6.3.0 to 6.4.0.
- [Release notes](https://github.com/sindresorhus/query-string/releases)
- [Commits](https://github.com/sindresorhus/query-string/compare/v6.3.0...v6.4.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-18 21:23:36 +00:00
dependabot[bot]
c43f51d483 Bump gatsby-plugin-page-creator from 2.0.8 to 2.0.10 (#3216)
Bumps [gatsby-plugin-page-creator](https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-plugin-page-creator) from 2.0.8 to 2.0.10.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-page-creator/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-page-creator@2.0.10/packages/gatsby-plugin-page-creator)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-18 21:13:09 +00:00
dependabot[bot]
2127a6934c Bump eslint-plugin-react-hooks from 1.2.0 to 1.5.1 (#3212)
Bumps [eslint-plugin-react-hooks](https://github.com/facebook/react/tree/HEAD/packages/eslint-plugin-react-hooks) from 1.2.0 to 1.5.1.
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/HEAD/packages/eslint-plugin-react-hooks)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-18 21:05:39 +00:00
dependabot[bot]
6e5b5c2bcf Bump eslint from 5.14.1 to 5.15.2 (#3210)
Bumps [eslint](https://github.com/eslint/eslint) from 5.14.1 to 5.15.2.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v5.14.1...v5.15.2)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-18 21:01:44 +00:00
dependabot[bot]
3559bff5aa Bump react-dom from 16.8.3 to 16.8.4 (#3191)
Bumps [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom) from 16.8.3 to 16.8.4.
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v16.8.4/packages/react-dom)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-18 20:58:14 +00:00
dependabot[bot]
000053acf8 Bump danger from 7.0.14 to 7.0.15 (#3215)
Bumps [danger](https://github.com/danger/danger-js) from 7.0.14 to 7.0.15.
- [Release notes](https://github.com/danger/danger-js/releases)
- [Changelog](https://github.com/danger/danger-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/danger/danger-js/compare/7.0.14...7.0.15)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-18 20:55:08 +00:00
Marcin Mielnicki
e43593e3bb OVH link fix (#3207) 2019-03-17 18:10:42 +01:00
chris48s
6e203d2455 refactor [githubreposize] (#3205) 2019-03-16 12:43:52 -05:00
Matthew Ratzke
f4ad1aa6fc fix [clojars] snapshot fallback (#3187)
* fix snapshot fallback

* fix prettier formatting

* update schema

* chore: test schema tweak

* fix schema

* Add allow null on schema
2019-03-14 20:27:54 -05:00
Paul Melnikow
2a9e1bbd83 Lengthen timeouts on [jsdelivr] tests (#3201)
These are failing pretty often in CI.
2019-03-13 10:05:24 -05:00
chris48s
2b29c226e0 refactor [githublastcommit] (#3199) 2019-03-13 00:17:39 -04:00
chris48s
9496b6d84c refactor [githubsize] (#3198) 2019-03-12 18:51:46 +00:00
dependabot[bot]
b0ff851e5c Bump simple-icons from 1.9.21 to 1.9.23 (#3193)
Bumps [simple-icons](https://github.com/simple-icons/simple-icons) from 1.9.21 to 1.9.23.
- [Release notes](https://github.com/simple-icons/simple-icons/releases)
- [Commits](https://github.com/simple-icons/simple-icons/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-11 20:38:29 +00:00
dependabot[bot]
1316310503 Bump eslint-config-prettier from 4.0.0 to 4.1.0 (#3192)
Bumps [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) from 4.0.0 to 4.1.0.
- [Release notes](https://github.com/prettier/eslint-config-prettier/releases)
- [Changelog](https://github.com/prettier/eslint-config-prettier/blob/master/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-config-prettier/compare/v4.0.0...v4.1.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-11 20:34:08 +00:00
dependabot[bot]
0cdb4319ff Bump lint-staged from 8.1.4 to 8.1.5 (#3195)
Bumps [lint-staged](https://github.com/okonet/lint-staged) from 8.1.4 to 8.1.5.
- [Release notes](https://github.com/okonet/lint-staged/releases)
- [Commits](https://github.com/okonet/lint-staged/compare/v8.1.4...v8.1.5)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-11 20:26:38 +00:00
Paul Melnikow
3733de6232 Rewrite GitHub commit status (#3186)
* WIP

* Parse the error response

* Clarify

* Restore one test

* Add a schema
2019-03-10 18:43:37 -05:00
Paul Melnikow
cbcf980182 Rewrite [website]; also affects [nodeping] (#3184) 2019-03-09 17:17:59 -05:00
Paul Melnikow
3baf0a8037 Rewrite [GithubCommitActivity] (#3183) 2019-03-08 18:39:11 -06:00
Caleb Cartwright
6e84e9b317 Refactor [Codecov] (#3074)
* feat: started refactoring codecov

* tests: removed erroneous test from draft PR

* chore: prettified for prettier

* feat: more codecov updates and tests

* feat: more codecov refactor updates

* feat: added codecov redirect content

* refactor: removed legacy codecov service file

* refactor(codecov): added redirect for legacy token route path

* docs(codecov): added documentation to examples for token info

* docs(codecov): updated vcs param in example patterns

* refactor(codecov): update redirect service date

Co-Authored-By: calebcartwright <calebcartwright@users.noreply.github.com>

* refactor(codecov): various updates based on PR feedback

* chore: added comment to codecov 401 test
2019-03-07 23:11:41 -06:00
Caleb Cartwright
3f4097b355 fix(maven-metadata): update schema to support single published versions (#3182) 2019-03-07 23:08:46 -06:00
Paul Melnikow
612831a2d8 Remove legacy analytics (#3179)
We're getting good results from #3093, so there's no reason to keep maintaining this code.

Ref #1848 #2068
2019-03-08 00:05:37 -05:00
Paul Melnikow
667bbbebfa Rewrite a bunch of components as functions, with consistent func style (#3177) 2019-03-08 00:02:23 -05:00
Paul Melnikow
b288c99a29 Fix console error before applying a frontend route redirect (#3176) 2019-03-07 19:34:27 -06:00
chris48s
3fc9b81ca8 allow numeric version for NuGet v2 services (#3181) 2019-03-07 20:13:22 +00:00
Paul Melnikow
5d42fe6858 Refactor two legacy services 😉 (#3175) 2019-03-06 23:34:30 -05:00
chris48s
4f9d44c33f refactor [chromewebstore] service (#3114) 2019-03-06 23:24:35 -05:00
Paul Melnikow
946abc9ded Refactor [librariesio] (#3160)
This takes another pass over the modern services to remove unused code. I switched the shared code to use a function instead of a class and removed the indirection in the route params which led to skew between the route and examples and wasn't making things any clearer.
2019-03-06 23:21:22 -05:00
Paul Melnikow
ace2a7a695 Tweak Docker initialization (#3173)
* Tweak Docker initialization

1. Set NODE_ENV=production in Docker.
2. When NODE_ENV is production, bind to all interfaces. This seems like a
   sensible default.
3. Exclude Dockerfile from container to improve layer cacheability when
   modifying the dockerfile.

Ref #3165

* Rm obsolete comment
2019-03-06 21:15:03 -06:00
Paul Melnikow
a6d02239f7 Document queryParams + rename example module (#3170)
This file does more than transform, and `examples` seems is a bit more consistent with e.g. `trace.js` and `route.js`.
2019-03-06 21:04:08 -06:00
Paul Melnikow
a12cbb76fc Prevent queryParams from reaching handle() when no schema is defined (#3171)
I believe I’ve added all the schemas to the new-style services in #3164, so this should be purely preventive.
2019-03-06 21:26:09 -05:00
Paul Melnikow
f5306f2df4 Appveyor example: improve doc formatting and invoke render() (#3172) 2019-03-06 21:23:28 -05:00
Paul Melnikow
be95faf347 Tweak examples for observatory, azure devops (#3169) 2019-03-06 19:55:42 -06:00
Paul Melnikow
388b0eefbb Add query param validation to remaining new-style services [azuredevops appveyor npm] (#3164)
Remove now-obsolete code.

Close #2675
2019-03-06 18:13:36 -05:00
dependabot[bot]
fb290d66f6 Bump gatsby-plugin-react-helmet from 3.0.6 to 3.0.8 (#3167)
Bumps [gatsby-plugin-react-helmet](https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-plugin-react-helmet) from 3.0.6 to 3.0.8.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-react-helmet/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-react-helmet@3.0.8/packages/gatsby-plugin-react-helmet)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-06 19:34:12 +00:00
Caleb Cartwright
a41ec5a3e5 Refactor [waffle] (#3133)
* refactor(waffle)

* refactor(waffle): added joi schema

* tests(waffle): added unit tests for transform & render

* chore: added qs for waffle api call

* refactor(waffle): tweaked test names

* refactor(waffle): made label required param, added redirect for BC

* refactor(waffle): relax schema to handle missing colors and null labels

* chore: removed waffle label test no longer needed

* refactor(waffle): updated redirect service
2019-03-06 19:23:23 +00:00
chris48s
4908bc5b1a refactor [microbadger] service (#3143)
* refactor [microbadger] service

* account for missing size key
2019-03-06 09:37:24 +00:00
Paul Melnikow
4f411755da Add a stats category for static badges (#3168)
Right now they're showing up in "other," though I expect they make up
most of that category.

https://github.com/badges/shields/issues/966#issuecomment-469851361
2019-03-05 21:23:20 -06:00
Paul Melnikow
e159d90516 Reorganize a couple of the legacy helpers [npm node jenkinsplugin dynamic] (#3163) 2019-03-05 20:43:33 -06:00
Paul Melnikow
a801450dd6 Move deprecation helpers to services/ (#3162)
This is currently unused, though it seems fine to keep it around.
2019-03-05 20:32:41 -06:00
dependabot[bot]
0941b6c39c Bump gatsby-plugin-catch-links from 2.0.11 to 2.0.12 (#3151)
Bumps [gatsby-plugin-catch-links](https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-plugin-catch-links) from 2.0.11 to 2.0.12.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-catch-links/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-catch-links@2.0.12/packages/gatsby-plugin-catch-links)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-05 20:21:35 +00:00
dependabot[bot]
39d5fceaba Bump camelcase from 5.0.0 to 5.2.0 (#3166)
Bumps [camelcase](https://github.com/sindresorhus/camelcase) from 5.0.0 to 5.2.0.
- [Release notes](https://github.com/sindresorhus/camelcase/releases)
- [Commits](https://github.com/sindresorhus/camelcase/compare/v5.0.0...v5.2.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-05 20:06:57 +00:00
dependabot[bot]
767626fbd5 Bump gatsby from 2.1.17 to 2.1.19 (#3153)
Bumps [gatsby](https://github.com/gatsbyjs/gatsby) from 2.1.17 to 2.1.19.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/compare/gatsby@2.1.17...gatsby@2.1.19)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-05 20:01:03 +00:00
Paul Melnikow
b7d632c6eb Make [AmoDownloads] test more reliable (#3159)
Close #3156
2019-03-04 23:52:27 -05:00
dependabot[bot]
136e174e35 Bump @babel/plugin-proposal-object-rest-spread from 7.3.2 to 7.3.4 (#3150)
Bumps [@babel/plugin-proposal-object-rest-spread](https://github.com/babel/babel) from 7.3.2 to 7.3.4.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.3.2...v7.3.4)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-04 23:37:24 -05:00
dependabot[bot]
ce4e3281ea Bump @babel/core from 7.3.3 to 7.3.4 (#3146)
Bumps [@babel/core](https://github.com/babel/babel) from 7.3.3 to 7.3.4.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.3.3...v7.3.4)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-04 23:33:14 -05:00
dependabot[bot]
4907cea8f5 Bump js-yaml from 3.12.1 to 3.12.2 (#3154)
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 3.12.1 to 3.12.2.
- [Release notes](https://github.com/nodeca/js-yaml/releases)
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/3.12.1...3.12.2)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-04 23:28:31 -05:00
dependabot[bot]
5021bdd21d Bump sinon from 7.2.4 to 7.2.6 (#3148)
Bumps [sinon](https://github.com/sinonjs/sinon) from 7.2.4 to 7.2.6.
- [Release notes](https://github.com/sinonjs/sinon/releases)
- [Changelog](https://github.com/sinonjs/sinon/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sinonjs/sinon/compare/v7.2.4...v7.2.6)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-04 23:10:06 -05:00
Caleb Cartwright
c52ea44450 fix: GH followers example style (#3158) 2019-03-04 23:07:13 -05:00
Caleb Cartwright
33786fa891 refactor [GitHubFollowers] (#3157) 2019-03-04 22:49:55 -05:00
Ludovic Fernandez
df56ca81e2 feat: [DockerCloud] and automated. (#3139)
* feat: docker cloud build and automated.

* refactor: better title.

* refactor: better badge URL.

* refactor: applies review comments.

* Update services/docker/docker-cloud-common-fetch.js

Co-Authored-By: ldez <ldez@users.noreply.github.com>

* refactor: encode query parameters.
2019-03-04 20:05:50 -06:00
Matthew Ratzke
85658250b6 update [clojars] endpoint (#3128)
* refactor(sourceforge): ref. sourceforge and add folder test (#3127)

doc: updated tutorial links and code snippets (#3124)

Refactor [Coveralls] (#3130)

* refactor(coveralls)

* chore: added comment with link to api

* doc: updated coveralls api doc comment

* doc: updated coveralls api doc comment

update clojars endpoint

Updates clojars badge to use api endpoints

Added release endpoint which returns latest stable release

Updates version endpoint which will now also return snapshots if available or latest stable release

check for invalid version and update variable send to render

import InvalidResponse

update require

make pretty

switch to prettyMessage

remove metadata lines

initial base class

initial base class

update schema

update ClojarsDownloads base class

simplify version classes

remove transform from export

update schema

remove unused var

replace == with ===

remove extra line

fix versionColor ?

fix lint error

make pretty

refactor transform

refactor transform and update tests

add error messagest to download service

fix error messages

remove errorSchema, revert changes to tests

refactor schema

update ClojarsDownloads base class

simplify version classes

remove transform from export

remove unused var

fix lint error

make pretty

refactor transform and update tests

add error messagest to download service

fix error messages

remove errorSchema, revert changes to tests

refactor schema

* fix versionColor

* remove errorMessages

* change prettyMessge to string

* update service names and add api docs reference

* update shields url

* update service names for clarity

* rename service files for clarity

* remove transform

* remove InvalidResponse
2019-03-04 19:50:05 -06:00
Caleb Cartwright
f4b66062b4 Refactor [buildkite] (#3126) 2019-03-04 19:55:13 -05:00
dependabot[bot]
ec24efd2b1 Bump query-string from 6.2.0 to 6.3.0 (#3145)
Bumps [query-string](https://github.com/sindresorhus/query-string) from 6.2.0 to 6.3.0.
- [Release notes](https://github.com/sindresorhus/query-string/releases)
- [Commits](https://github.com/sindresorhus/query-string/compare/v6.2.0...v6.3.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-04 19:52:01 -05:00
Caleb Cartwright
879581466c Refactor [Codeship] (#3131) 2019-03-04 19:41:57 -05:00
dependabot[bot]
839d7c5825 Bump jsonpath from 1.0.0 to 1.0.1 (#3152)
Bumps [jsonpath](https://github.com/dchester/jsonpath) from 1.0.0 to 1.0.1.
- [Release notes](https://github.com/dchester/jsonpath/releases)
- [Commits](https://github.com/dchester/jsonpath/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-04 19:39:17 -05:00
Caleb Cartwright
726830f067 Add ability to transform query params in redirct service, run [Endpoint GitHubReleaseRedirect SensioLabs VSO] (#3125)
* feat(redirector): added transformQueryParams to redirector

* refactor: renamed to transformPath in redirector

* Rename targetUrl to targetPath

Co-Authored-By: calebcartwright <calebcartwright@users.noreply.github.com>

* feat(redirector): handle param conflicts
2019-03-04 18:11:37 -06:00
Paul Melnikow
c7deb5a0d1 First adoption of React hooks (#3096)
I did this as a warm-up to using [React hooks](https://reactjs.org/docs/hooks-intro.html), which provide a better way to accomplish stateful things and side effects using functional components. This allows all components to be written in the same style, improves testability, facilitates code reuse, etc.

There's [a intro here](https://reactjs.org/docs/hooks-intro.html) which links to [Dan's talk at React Conf](https://www.youtube.com/watch?time_continue=3599&v=dpw9EHDh2bM) which does a really good job of explaining why hooks are a good way to write components. He describes hooks as being the electrons and neutrons to components which are atoms. Low-level functionality which was always there in React, though not as accessibly or visibly.

This adds a lint rule that enforces "the rule of hooks" which says they have to be declared at the top level in the functional component.

I don't think this changeset does a fabulous job of showing off the improvements hooks allows, though I think it is still a good direction for this code.
2019-03-03 18:30:20 -05:00
Caleb Cartwright
1a6b32b49a Refactor [david] (#3135) 2019-03-03 20:19:27 +00:00
Caleb Cartwright
c009f3cf51 Refactor [continuousphp] (#3134) 2019-03-03 19:54:15 +00:00
chris48s
711c3044dc add schema for [bugzilla] service (#3142) 2019-03-03 19:46:25 +00:00
Caleb Cartwright
cc0f1fc6db Refactor [bundlephobia] (#3132) 2019-03-03 19:00:52 +00:00
Pierre-Yves B
eb453401e3 Updated remaining documentation (#3141) 2019-03-03 10:42:14 -06:00
Pierre-Yves B
96dfa5b085 Allowed expectBadge to be called with null color (#3137) 2019-03-02 23:26:10 +00:00
Caleb Cartwright
f6e061f150 Refactor [GitHubWatchers] (#3136) 2019-03-02 22:19:11 +00:00
Caleb Cartwright
cad3ea434f Refactor [Coveralls] (#3130)
* refactor(coveralls)

* chore: added comment with link to api

* doc: updated coveralls api doc comment

* doc: updated coveralls api doc comment
2019-03-02 10:48:38 +00:00
Caleb Cartwright
f0eac60191 doc: updated tutorial links and code snippets (#3124) 2019-03-01 16:00:18 -06:00
Caleb Cartwright
ee97de13f3 refactor(sourceforge): ref. sourceforge and add folder test (#3127) 2019-03-01 21:56:34 +00:00
Paul Melnikow
56e71d7c76 Label all deprecated services as such (#3120)
* Label all deprecated services as such

This will change

service_requests_total{category="other",family="cocoapods",service="cocoapods_apps"} 76

to

service_requests_total{category="other",family="cocoapods",service="deprecated_cocoapods_apps"} 76

* Fix tests
2019-02-28 18:22:28 -06:00
Paul Melnikow
97358c1399 Rewrite [GitHubStars] (#3119)
* Refactor [GithubStars]

* Add test of link array
2019-02-28 18:18:32 -06:00
Henry Poydar
513b69272e Update instructions for self-hosting Shields with Heroku (#3123) 2019-02-28 18:13:44 -06:00
Pierre-Yves B
1f29c22d3d Migrated most service tests to use new expectBadge (#3122) 2019-02-28 21:43:23 +00:00
XhmikosR
4e2d144f97 Fix footer links (#3121)
Fix discord footer link and remove trailing slash from repo URL
2019-02-28 11:55:38 -05:00
Paul Melnikow
b43c9c7c18 Refactor [bitrise] (#3117) 2019-02-27 23:21:11 -05:00
Paul Melnikow
fafb22efee Move "good" badge helpers from lib/ to services/ (#3101)
This moves a few helpers from `lib/` to `services/`:

build-status.js
build-status.spec.js
color-formatters.js
color-formatters.spec.js
contributor-count.js
licenses.js
licenses.spec.js
php-version.js
php-version.spec.js
text-formatters.js
text-formatters.spec.js
version.js
version.spec.js

And one from `lib/` to `core/`:

unhandled-rejection.spec.js

The diff is long, but the changes are straightforward.

Ref #2832
2019-02-27 20:47:46 -05:00
Paul Melnikow
8b2ecaefd1 Remove Heroku buildpack config; allow devDependencies to be pruned (#3115)
The buildpack config doesn't seem to be needed. This would affect review apps, staging, and self-hosting.

Also, devDependencies are installed by default during the build: https://devcenter.heroku.com/changelog-items/1376

By removing `NPM_CONFIG_PRODUCTION=false` we allow these to be pruned so they're kept out of the slug. This also has the advantage of creating a test environment in PRs where missing production dependencies will cause things to break. That'd be a good thing!
2019-02-27 19:08:19 -05:00
Paul Melnikow
dfc95ddd1a Add per-badge metrics for BaseService (#3093)
This picks up #2068 by adding per-badge stats as discussed in #966.

It ensures every service has a unique `name` property. By default this comes from the class name, and is overridden in all the various places where the class names are duplicated. (Some of those don't seem that useful, like the various download interval services, though those need to be refactored down into a single service anyway.) Tests enforce the names are unique. These are the names used by the service-test runner, so it's a good idea to make them unique anyway. (It was sort of strange before that you had to specify `nuget` instead of e.g. `resharper`.)

I've added validation to `deprecatedService` and `redirector`, and required that every `route` has a `base`, even if it's an empty string.

The name is used to generate unique metric labels, generating metrics like these:

```
service_requests_total{category="activity",family="eclipse-marketplace",service="eclipse_marketplace_update"} 2
service_requests_total{category="activity",family="npm",service="npm_collaborators"} 3
service_requests_total{category="activity",family="steam",service="steam_file_release_date"} 2
service_requests_total{category="analysis",family="ansible",service="ansible_galaxy_content_quality_score"} 2
service_requests_total{category="analysis",family="cii-best-practices",service="cii_best_practices_service"} 4
service_requests_total{category="analysis",family="cocoapods",service="cocoapods_docs"} 2
service_requests_total{category="analysis",family="codacy",service="codacy_grade"} 3
service_requests_total{category="analysis",family="coverity",service="coverity_scan"} 2
service_requests_total{category="analysis",family="coverity",service="deprecated_coverity_ondemand"} 2
service_requests_total{category="analysis",family="dependabot",service="dependabot_semver_compatibility"} 3
service_requests_total{category="analysis",family="lgtm",service="lgtm_alerts"} 2
service_requests_total{category="analysis",family="lgtm",service="lgtm_grade"} 3
service_requests_total{category="analysis",family="snyk",service="snyk_vulnerability_git_hub"} 4
service_requests_total{category="analysis",family="snyk",service="snyk_vulnerability_npm"} 5
service_requests_total{category="analysis",family="symfony",service="sensiolabs_i_redirector"} 1
service_requests_total{category="analysis",family="symfony",service="symfony_insight_grade"} 1
service_requests_total{category="build",family="appveyor",service="app_veyor_ci"} 3
service_requests_total{category="build",family="appveyor",service="app_veyor_tests"} 6
service_requests_total{category="build",family="azure-devops",service="azure_dev_ops_build"} 6
service_requests_total{category="build",family="azure-devops",service="azure_dev_ops_release"} 5
service_requests_total{category="build",family="azure-devops",service="azure_dev_ops_tests"} 6
service_requests_total{category="build",family="azure-devops",service="vso_build_redirector"} 2
service_requests_total{category="build",family="azure-devops",service="vso_release_redirector"} 1
service_requests_total{category="build",family="bitbucket",service="bitbucket_pipelines"} 5
service_requests_total{category="build",family="circleci",service="circle_ci"} 5
```

This is predicated on being able to use Prometheus's [`rate()`](https://prometheus.io/docs/prometheus/latest/querying/functions/#rate) function to visualize a counter's rate of change, as mentioned at https://github.com/badges/shields/issues/2068#issuecomment-466696561. Otherwise the stats will be disrupted every time a server restarts.

The metrics only appear on new-style services.
2019-02-27 18:58:59 -05:00
dependabot[bot]
62a89fc834 Bump react from 16.8.2 to 16.8.3 (#3102)
Bumps [react](https://github.com/facebook/react/tree/HEAD/packages/react) from 16.8.2 to 16.8.3.
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v16.8.3/packages/react)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-27 18:42:09 -05:00
dependabot[bot]
c050fc976f Bump babel-preset-gatsby from 0.1.7 to 0.1.8 (#3106)
Bumps babel-preset-gatsby from 0.1.7 to 0.1.8.

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-27 18:25:50 -05:00
dependabot[bot]
f3804a0764 Bump gatsby-plugin-page-creator from 2.0.7 to 2.0.8 (#3108)
Bumps gatsby-plugin-page-creator from 2.0.7 to 2.0.8.

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-27 18:22:32 -05:00
dependabot[bot]
94b150195e Bump mocha-env-reporter from 3.0.0 to 4.0.0 (#3078)
Bumps [mocha-env-reporter](https://github.com/wix/mocha-env-reporter) from 3.0.0 to 4.0.0.
- [Release notes](https://github.com/wix/mocha-env-reporter/releases)
- [Commits](https://github.com/wix/mocha-env-reporter/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-27 18:19:51 -05:00
Paul Melnikow
73d8156f44 Convert some format regexes to patterns (#3109) 2019-02-27 17:52:20 -05:00
Pierre-Yves B
81fbd4ed49 Introduced expectBadge helper (#3097) 2019-02-27 08:02:14 +00:00
Paul Melnikow
e4fe8c0c5f Rewrite [GithubSearch] (#3099) 2019-02-25 15:24:41 -05:00
chris48s
92039e413d add notes to logo docs about brand guidelines (#3088) 2019-02-25 20:02:07 +00:00
chris48s
c6ea546fab use caret for all gh-badges dependencies (#3110) 2019-02-25 19:56:24 +00:00
Paul Melnikow
b14fdd7fd7 Reorganize categories code (#3100)
Seems that the list of categories belongs with the services, while the
support code belongs with base service.

Ref #2832
2019-02-25 14:39:12 -05:00
Paul Melnikow
9fa9785568 Rewrite [GithubRelease] (#3098) 2019-02-25 14:33:52 -05:00
dependabot[bot]
95c11dd7ac Bump gatsby from 2.1.14 to 2.1.17 (#3105)
Bumps [gatsby](https://github.com/gatsbyjs/gatsby) from 2.1.14 to 2.1.17.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/compare/gatsby@2.1.14...gatsby@2.1.17)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-25 19:01:29 +00:00
dependabot[bot]
7217a7e3ba Bump simple-icons from 1.9.20 to 1.9.21 (#3107)
Bumps [simple-icons](https://github.com/simple-icons/simple-icons) from 1.9.20 to 1.9.21.
- [Release notes](https://github.com/simple-icons/simple-icons/releases)
- [Commits](https://github.com/simple-icons/simple-icons/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-25 18:57:24 +00:00
dependabot[bot]
781c7b941e Bump danger from 7.0.13 to 7.0.14 (#3104)
Bumps [danger](https://github.com/danger/danger-js) from 7.0.13 to 7.0.14.
- [Release notes](https://github.com/danger/danger-js/releases)
- [Changelog](https://github.com/danger/danger-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/danger/danger-js/compare/7.0.13...7.0.14)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-25 18:54:29 +00:00
Paul Melnikow
c7d707363c Refactor [luarocks] (#3094) 2019-02-24 16:11:17 -05:00
Paul Melnikow
f831fba4d4 Rewrite [GitHubLicense] (#3095) 2019-02-24 16:04:24 -05:00
Paul Melnikow
e3d115cf99 Rename maxAge to cacheSeconds (#3090)
Close #3069
2019-02-23 20:33:38 -05:00
chris48s
9ed78867f7 fix [amo] badges (#3083)
This switches to the new mozilla add-ons API.

It's not a completely like-for-like replacement. I was able to replicate the version, users and rating badges but we no longer have total download stats. We've got weekly downloads instead, so I've redirected `/d` to the new `/dw`

closes #3079
2019-02-23 20:11:11 -05:00
Paul Melnikow
8c244c2e40 Fix color overriding for legacy services (#3091)
While I was doing #3090 I realized the work in #3012 did not handle legacy services.

I tested this manually with `/librariesio/release/hex/phoenix.svg?color=blue` and it works.
2019-02-23 19:07:31 -05:00
dependabot[bot]
c3ecde05ee Bump react-dom from 16.8.2 to 16.8.3 (#3075)
Bumps [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom) from 16.8.2 to 16.8.3.
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v16.8.3/packages/react-dom)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-23 15:43:48 -05:00
Paul Melnikow
751af4bb3a Remove unused package (#3087) 2019-02-23 15:40:48 -05:00
Paul Melnikow
a40093d4a1 Named logo should override logoSvg in [endpoint]; also test [static] (#3049)
Fix #2998
2019-02-23 15:37:37 -05:00
Paul Melnikow
09e902fa38 Add frontend prop-type validation for the service definition schema (#3063)
Closes #2702
2019-02-23 15:34:49 -05:00
chris48s
7d1d74cfcf refactor [maven-metadata] service (#3085) 2019-02-23 15:29:46 -05:00
Paul Melnikow
6684f4b566 Remove unused version helper (#3086) 2019-02-23 15:20:34 -05:00
chris48s
912d2018f9 refactor chef [cookbook] service (#3084) 2019-02-23 15:12:13 -05:00
dependabot[bot]
6b7561b150 Bump gatsby from 2.1.13 to 2.1.14 (#3076)
Bumps [gatsby](https://github.com/gatsbyjs/gatsby) from 2.1.13 to 2.1.14.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/compare/gatsby@2.1.13...gatsby@2.1.14)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-22 22:07:17 +00:00
dependabot[bot]
f98484f8e7 Bump danger from 7.0.12 to 7.0.13 (#3070)
Bumps [danger](https://github.com/danger/danger-js) from 7.0.12 to 7.0.13.
- [Release notes](https://github.com/danger/danger-js/releases)
- [Changelog](https://github.com/danger/danger-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/danger/danger-js/compare/7.0.12...7.0.13)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-22 22:04:39 +00:00
dependabot[bot]
a46df6b347 Bump mocha from 6.0.0 to 6.0.1 (#3077)
Bumps [mocha](https://github.com/mochajs/mocha) from 6.0.0 to 6.0.1.
- [Release notes](https://github.com/mochajs/mocha/releases)
- [Changelog](https://github.com/mochajs/mocha/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mochajs/mocha/compare/v6.0.0...v6.0.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-22 10:57:55 -05:00
Paul Melnikow
cd49bda968 Improve coverage in frontend and remove some dead code (#3031) 2019-02-22 00:08:11 -05:00
dependabot[bot]
a9ed1e144e Bump gatsby-plugin-page-creator from 2.0.6 to 2.0.7 (#3060)
Bumps gatsby-plugin-page-creator from 2.0.6 to 2.0.7.

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-22 00:04:55 -05:00
Paul Melnikow
ab18bc0f09 Shorten [endpoint] URL (#3050)
Ref https://github.com/badges/shields/issues/2838#issuecomment-461794344
2019-02-22 00:01:56 -05:00
Paul Melnikow
4bd16f93e8 Sort imports and requires (#3056)
This will definitely save time, and ensure more uniformity.

It moves the `createServiceTester()` calls to a different place from where I'd like them, though I'm happy to have them checked by the linter.

Closes #2701
2019-02-21 22:14:40 -05:00
mbarkhau
f6628e62b7 [QueryStringStatic] service (#3024)
Ref #2673
2019-02-21 21:12:24 -05:00
Paul Melnikow
9e4a8cec09 Consolidate badge URL generation functions (#3032)
This consolidates all the badge URL generation functions into a single place, and updates the rest of the calling code to use it. It renames some things and updates labels to bring the names into alignment with the current API.

Resolve #2027
2019-02-21 21:07:27 -05:00
Danial
f550f0cc4d Update Travis logo, Reduce some duplication (#3047)
Switch Travis to use full-color logo approved at https://github.com/badges/shields/pull/1276#issuecomment-466164851
2019-02-21 20:29:23 -05:00
dependabot[bot]
41fc3bbbf8 Bump icedfrisby from 2.0.0-alpha.3 to 2.0.0-alpha.4 (#3073)
Bumps [icedfrisby](https://github.com/RobertHerhold/IcedFrisby) from 2.0.0-alpha.3 to 2.0.0-alpha.4.
- [Release notes](https://github.com/RobertHerhold/IcedFrisby/releases)
- [Changelog](https://github.com/IcedFrisby/IcedFrisby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/RobertHerhold/IcedFrisby/compare/2.0.0-alpha.3...2.0.0-alpha.4)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-21 00:45:51 -05:00
Paul Melnikow
33aefcfaf8 Minor cleanup related to colorB -> color (#3066)
As `color` is now the canonical, it makes sense to update some of these tests to say `colorB` instead.

Ref #3012
2019-02-20 23:34:22 -05:00
Paul Melnikow
2d7be31b0c Validate query params in BaseService (#3042)
This is a mid-sized PR that adds query param validation to BaseService and updates most of the services which use query param validation to use it. There are a couple minor tweaks I made along the way.

Fix #2676
2019-02-20 22:24:47 -05:00
dependabot[bot]
52a71cb327 Bump gatsby from 2.1.4 to 2.1.13 (#3067)
Bumps [gatsby](https://github.com/gatsbyjs/gatsby) from 2.1.4 to 2.1.13.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/compare/gatsby@2.1.4...gatsby@2.1.13)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-20 19:15:55 -05:00
dependabot[bot]
d49ce75fee Bump gatsby-plugin-styled-components from 3.0.5 to 3.0.6 (#3064)
Bumps [gatsby-plugin-styled-components](https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-plugin-styled-components) from 3.0.5 to 3.0.6.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-styled-components/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-styled-components@3.0.6/packages/gatsby-plugin-styled-components)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-20 19:08:09 -05:00
Paul Melnikow
5fda6ac11e Alphabetize JSX props in the frontend (#3055)
I'm game to give this a shot.

Ref #2701
2019-02-20 18:58:24 -05:00
Paul Melnikow
c770a43dd8 Move flip cache debug service into [debug] (#3057)
Close #2636
2019-02-20 18:43:27 -05:00
Caleb Cartwright
a4bd3f5fd6 Add SymfonyInsight stars badge, run [SymfonyInsight sensiolabs amo chrome-web-store redmine spigetratings vaadin-directory visualstudiomarketplacerating wordpress] (#2971)
* feat: added stars badge for symfony insight

* refactor: changed symfony star determination logic

* feat: updating symfony to handle old scan scenarios

* feat: updated symfony insight to handle older projects

* tests: removed another test for symfony insight per request
2019-02-20 17:15:31 -06:00
Caleb Cartwright
96d48dc486 chore: make mocha rc configs dotfiles (#3065)
Fixes #3054 

Apparently mocha 6's new auto-config discovery only works with dotfiles. This renames our mocha rc files accordingly: `mocharc.yml` --> `.mocharc.yml` and solely to be consistent `mocharc-frontend.yml` --> ` .mocharc-frontend.yml`

- https://github.com/mochajs/mocha/blob/master/lib/cli/config.js#L23
- https://mochajs.org/#configuring-mocha-nodejs
- https://github.com/mochajs/mocha/blob/master/CHANGELOG.md#tada-enhancements-1
2019-02-20 18:05:14 -05:00
Paul Melnikow
bc523e3aae Fix your-badge link (#3058)
Fix #1954
2019-02-20 16:34:50 -05:00
Paul Melnikow
84db9e6fe3 Remove IP filtering code for prometheus metrics (#3059)
Closes #2657
2019-02-20 18:38:16 +00:00
Pierre-Yves B
27696d4691 Require constructors to be called with new (#3052) 2019-02-20 09:49:42 +00:00
dependabot[bot]
144d1632f5 Bump icedfrisby from 2.0.0-alpha.2 to 2.0.0-alpha.3 (#3061)
Bumps [icedfrisby](https://github.com/RobertHerhold/IcedFrisby) from 2.0.0-alpha.2 to 2.0.0-alpha.3.
- [Release notes](https://github.com/RobertHerhold/IcedFrisby/releases)
- [Changelog](https://github.com/IcedFrisby/IcedFrisby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/RobertHerhold/IcedFrisby/compare/2.0.0-alpha.2...2.0.0-alpha.3)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-20 01:21:28 -05:00
dependabot[bot]
f754b1ac2e Bump @babel/plugin-proposal-class-properties from 7.3.0 to 7.3.3 (#3018)
Bumps [@babel/plugin-proposal-class-properties](https://github.com/babel/babel) from 7.3.0 to 7.3.3.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.3.0...v7.3.3)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-19 23:48:16 -05:00
dependabot[bot]
77ef526997 Bump react-select from 2.3.0 to 2.4.1 (#3043)
Bumps [react-select](https://github.com/JedWatson/react-select) from 2.3.0 to 2.4.1.
- [Release notes](https://github.com/JedWatson/react-select/releases)
- [Changelog](https://github.com/JedWatson/react-select/blob/master/.sweet-changelogs.js)
- [Commits](https://github.com/JedWatson/react-select/compare/v2.3.0...v2.4.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-19 23:45:50 -05:00
Paul Melnikow
a30c833989 Use drop-down for [jsdelivr] and make badges more consistent with other download badges (#3036)
- Move to Downloads
- Use `downloadCount`
- Remove “hits” from the message
- "package name" for better appearance in the UI
- Simplify validation
2019-02-19 23:43:29 -05:00
dependabot[bot]
049a5409df Bump @babel/core from 7.2.2 to 7.3.3 (#3021)
Bumps [@babel/core](https://github.com/babel/babel) from 7.2.2 to 7.3.3.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.2.2...v7.3.3)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-19 22:21:10 -05:00
chris48s
6d4b80f124 improve docs for simple-icons usage (#3007)
Closes #2980
2019-02-19 22:14:19 -05:00
mbarkhau
6e2992a3e3 Rename colorB -> color; colorA -> labelColor (#3012)
This makes it possible to override the parameters `color` and `labelColor`.

ref #2673
2019-02-19 22:03:45 -05:00
dependabot[bot]
f721eb7424 Bump sinon from 7.2.3 to 7.2.4 (#3044)
Bumps [sinon](https://github.com/sinonjs/sinon) from 7.2.3 to 7.2.4.
- [Release notes](https://github.com/sinonjs/sinon/releases)
- [Changelog](https://github.com/sinonjs/sinon/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sinonjs/sinon/compare/v7.2.3...v7.2.4)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-19 21:44:17 +00:00
dependabot[bot]
cc57d32227 Bump danger from 7.0.11 to 7.0.12 (#3023)
Bumps [danger](https://github.com/danger/danger-js) from 7.0.11 to 7.0.12.
- [Release notes](https://github.com/danger/danger-js/releases)
- [Changelog](https://github.com/danger/danger-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/danger/danger-js/compare/7.0.11...7.0.12)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-19 21:41:44 +00:00
dependabot[bot]
d727986f5a Bump lint-staged from 8.1.3 to 8.1.4 (#3016)
Bumps [lint-staged](https://github.com/okonet/lint-staged) from 8.1.3 to 8.1.4.
- [Release notes](https://github.com/okonet/lint-staged/releases)
- [Commits](https://github.com/okonet/lint-staged/compare/v8.1.3...v8.1.4)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-19 21:36:09 +00:00
dependabot[bot]
471e53afc9 Bump simple-icons from 1.9.19 to 1.9.20 (#3045)
Bumps [simple-icons](https://github.com/simple-icons/simple-icons) from 1.9.19 to 1.9.20.
- [Release notes](https://github.com/simple-icons/simple-icons/releases)
- [Commits](https://github.com/simple-icons/simple-icons/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-19 20:12:57 +00:00
dependabot[bot]
42683a0587 Bump enzyme from 3.8.0 to 3.9.0 (#3046)
Bumps [enzyme](https://github.com/airbnb/enzyme/tree/HEAD/packages/enzyme) from 3.8.0 to 3.9.0.
- [Release notes](https://github.com/airbnb/enzyme/releases)
- [Changelog](https://github.com/airbnb/enzyme/blob/master/CHANGELOG.md)
- [Commits](https://github.com/airbnb/enzyme/compare/enzyme@3.8.0...enzyme@3.9.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-19 09:58:26 -05:00
Ville Skyttä
4611ba155f Fall back to grabbing version from "X :: Only" PyPI classifiers (#3014)
If e.g. `3 :: Only` alone is specified in PyPI classifiers, use the `3` from it. But keep ignoring `* :: Only` when it occurs with other specified versions.
2019-02-19 09:49:53 -05:00
Danial
c2c27ea795 TypeError: s.toLowerCase is not a function (#2997)
* Update color.js

* fixup

* expand test

* expand test (again)
2019-02-19 07:52:37 +00:00
dependabot[bot]
0e56258ac0 Bump eslint from 5.13.0 to 5.14.1 (#3039)
Bumps [eslint](https://github.com/eslint/eslint) from 5.13.0 to 5.14.1.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v5.13.0...v5.14.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-18 23:09:22 -05:00
Paul Melnikow
24bc7bcfc3 Combine some badge examples using drop-downs, tweak some titles (#3037)
This updates several badges to take advantage of the change from #2882.
2019-02-18 23:04:25 -05:00
Paul Melnikow
ed7aa31808 Test transformExample directly (#3041)
These tests in `base.spec.js` are difficult to maintain.
2019-02-18 21:45:05 -05:00
Pierre-Yves B
e9f8700607 Fix [GithubManifest] and [GithubPackageJson] when static auth is not configured (#3035)
* Fixed fetchJsonFromRepo function when static auth is not configured

* Removed redundant await
2019-02-18 20:02:52 -06:00
Paul Melnikow
ad81f3c6ec Improve handling of some edge cases and get 100% coverage in generate-image-markup (#3030) 2019-02-18 19:25:02 -06:00
Paul Melnikow
1b2b556ca8 Upgrade to Mocha 6 and update configuration (#3038) 2019-02-18 19:03:49 -06:00
Paul Melnikow
0013641fdd Tweak [maintenance] badge in UI; remove caching (#3040) 2019-02-18 18:54:27 -06:00
dependabot[bot]
b1afccdce9 Bump react from 16.8.1 to 16.8.2 (#3022)
Bumps [react](https://github.com/facebook/react/tree/HEAD/packages/react) from 16.8.1 to 16.8.2.
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/compare/v16.8.1...v16.8.2)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-18 19:22:20 -05:00
dependabot[bot]
ad6f8a07f9 Bump eslint from 5.13.0 to 5.14.0 (#3020)
Bumps [eslint](https://github.com/eslint/eslint) from 5.13.0 to 5.14.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v5.13.0...v5.14.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-18 19:16:43 -05:00
dependabot[bot]
f8a48457fb Bump gatsby from 2.1.2 to 2.1.4 (#3019)
Bumps [gatsby](https://github.com/gatsbyjs/gatsby) from 2.1.2 to 2.1.4.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-18 19:14:04 -05:00
Paul Melnikow
d2861b2438 Switch to npm ci (#3034) 2019-02-18 17:28:09 -06:00
Paul Melnikow
0506a1762b Omit style=flat from generated URLs (#3025)
Fix #2953
2019-02-18 18:01:44 -05:00
dependabot[bot]
c45aa48a98 Bump react-error-overlay from 5.1.2 to 5.1.3 (#2975)
Bumps [react-error-overlay](https://github.com/facebook/create-react-app) from 5.1.2 to 5.1.3.
- [Release notes](https://github.com/facebook/create-react-app/releases)
- [Changelog](https://github.com/facebook/create-react-app/blob/master/CHANGELOG-1.x.md)
- [Commits](https://github.com/facebook/create-react-app/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-18 17:03:13 -05:00
Paul Melnikow
0f22c0af25 Store the deprecation date inline (#3029) 2019-02-18 16:59:08 -05:00
dependabot[bot]
fb21fdf8f7 Bump babel-plugin-istanbul from 5.1.0 to 5.1.1 (#3017)
Bumps [babel-plugin-istanbul](https://github.com/istanbuljs/babel-plugin-istanbul) from 5.1.0 to 5.1.1.
- [Release notes](https://github.com/istanbuljs/babel-plugin-istanbul/releases)
- [Changelog](https://github.com/istanbuljs/babel-plugin-istanbul/blob/master/CHANGELOG.md)
- [Commits](https://github.com/istanbuljs/babel-plugin-istanbul/compare/v5.1.0...v5.1.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-18 11:18:50 -05:00
Paul Melnikow
d9d8a3b227 Drop-downs for multiple choice in patterns (#2882)
You can see it in effect on the PyPI downloads and the David badges.
2019-02-18 11:15:58 -05:00
Yves M
ee1a3564f0 Add Mozilla HTTP Observatory badge [MozillaObservatory] (#2935)
* Begin adding a Mozilla Observatory badge (#2912)

* Update tests to add `_shields_test` style

* Add grade D and E tests

* Use Shields color scheme

See https://github.com/badges/shields/issues/2912#issuecomment-461692102

Resolves https://github.com/badges/shields/pull/2935#pullrequestreview-201432260

* Fix grade response validation regex

A bit related to https://github.com/badges/shields/pull/2935#pullrequestreview-201430779

* Add the host query param via `qs`

Resolves https://github.com/badges/shields/pull/2935#pullrequestreview-201431030

* Make integration test on `observatory.mozilla.org`

- Use `observatory.mozilla.org` instead of `httpforever.com` which redirects to `observatory.mozilla.org` anyway
- Use Joi to validate response

* Define label using `defaultBadgeData`

Resolves https://github.com/badges/shields/pull/2935#pullrequestreview-201431659

* Use short hand `createServiceTester` function helper in tests

Resolves https://github.com/badges/shields/pull/2935#pullrequestreview-201431898

* Make strict API response validation

See https://github.com/badges/shields/pull/2935#discussion_r255097377

* Use the `POST` API endpoint to trigger new scan

See https://github.com/badges/shields/issues/2912#issuecomment-462064216

* Handle unfinished states

See https://github.com/badges/shields/issues/2912#issuecomment-462064216

* Split in two separate badges, with and without score

See https://github.com/badges/shields/issues/2912#issuecomment-461692102

* Add a `publish` parameter to include the result in public list

See https://github.com/badges/shields/issues/2912#issuecomment-461764463

* Add documentation

* Update tester importer

* Remove redundant example keywords

Resolves https://github.com/badges/shields/pull/2935#discussion_r257086115

* Minor doc update

* Embed `which` parameter in examples

* Remove root path from pattern in examples

Resolves https://github.com/badges/shields/pull/2935#pullrequestreview-204582763 and https://github.com/badges/shields/pull/2935#pullrequestreview-204582728

* Pass missing `which` parameter to render in examples

Resolves https://github.com/badges/shields/pull/2935#discussion_r257525827
2019-02-18 10:11:44 -06:00
dependabot[bot]
c93f254315 Bump react-dom from 16.8.1 to 16.8.2 (#2999)
Bumps [react-dom](https://github.com/facebook/react) from 16.8.1 to 16.8.2.
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/compare/v16.8.1...v16.8.2)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-18 10:45:49 -05:00
chris48s
332e9fd6b7 refactor [bugzilla] service (#3008) 2019-02-17 22:55:31 -05:00
chris48s
0b73b1d734 refactor [discourse] service (#3010) 2019-02-17 21:57:44 +00:00
chris48s
0da1bb2b08 fix asciiDoc links (#3006) 2019-02-17 21:55:22 +00:00
Ville Skyttä
0d4a74bd6b Spelling fixes (#3013) 2019-02-17 14:10:06 -05:00
chris48s
21612dd003 refactor [homebrew] service (#3009) 2019-02-17 17:25:31 +00:00
dependabot[bot]
8d9fa3e121 Bump nyc from 13.2.0 to 13.3.0 (#3000)
Bumps [nyc](https://github.com/istanbuljs/nyc) from 13.2.0 to 13.3.0.
- [Release notes](https://github.com/istanbuljs/nyc/releases)
- [Changelog](https://github.com/istanbuljs/nyc/blob/master/CHANGELOG.md)
- [Commits](https://github.com/istanbuljs/nyc/compare/v13.2.0...v13.3.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-17 12:25:27 +00:00
dependabot[bot]
e6ef4c012c Bump snap-shot-it from 6.2.9 to 6.2.10 (#3002)
Bumps [snap-shot-it](https://github.com/bahmutov/snap-shot-it) from 6.2.9 to 6.2.10.
- [Release notes](https://github.com/bahmutov/snap-shot-it/releases)
- [Commits](https://github.com/bahmutov/snap-shot-it/compare/v6.2.9...v6.2.10)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-17 12:21:05 +00:00
dependabot[bot]
37ecb936fc Bump gatsby from 2.1.0 to 2.1.2 (#3001)
Bumps [gatsby](https://github.com/gatsbyjs/gatsby) from 2.1.0 to 2.1.2.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-17 12:18:02 +00:00
James Cahill
08bf7f02e4 refactor maintenance service (#3005) 2019-02-17 12:03:31 +00:00
Skyper
6bfa9b1b41 Add badges for [Keybase] (#2969)
* Add Keybase PGP badge

* Return 'not found' if the key is not present

* Change the default colour

* Add more constraints to the schema

* Render 64-bit fingerprints

* Add example

* Add a 'hex()' constraint to the fingerprint

* Improve error handling

* Add class 'KeybaseProfile'

* Add unit tests for Keybase PGP

* Add Keybase BTC

* Add unit tests for Keybase BTC

* Add Keybase ZEC

* Add unit tests for Keybase ZEC

* Add Keybase XLM

* Add unit tests for Keybase XLM

* Validate the BTC address using a regex

Regex taken from
https://mokagio.github.io/tech-journal/2014/11/21/regex-bitcoin.html.

* Exclude 'not found' from addresses' value in unit tests

* Remove useless keywords

* Add the link to the Keybase API documentation

* Move the colour into 'defaultBadgeData'

* Remove the HTTP method

'GET' is already the default one.

* Improve the error handling for Keybase BTC

* Add more constraints to the Keybase BTC schema

* Update one unit test for Keybase BTC

* Fix the error handling for Keybase BTC

* Add more unit tests for Keybase BTC

* Improve the error handling for Keybase ZEC

* Improve the error handling for Keybase PGP

* Improve the error handling for Keybase XLM

* Display a real username value in the examples

* Include the status code in the schemas

* Move the category to the base class

The same category is used by all badges.

* Add function 'transform' to the base class

The function 'transform' is used to encapsulate the error handling logic
as it is the same in each service.
2019-02-15 11:33:06 -06:00
Paul Melnikow
90f8ad5b73 Endpoint customizer (#2908)
* Endpoint page: improve formatting

Cherry-picked from #2906 (conflicts with that)

Partly addresses #2837 but does not resolve it

* Add badge customizer to the endpoint page

* Clean lint
2019-02-14 19:08:56 -06:00
dependabot[bot]
24945adfed [Security] Bump handlebars from 4.0.12 to 4.1.0 (#2992)
Bumps [handlebars](https://github.com/wycats/handlebars.js) from 4.0.12 to 4.1.0. **This update includes security fixes.**
- [Release notes](https://github.com/wycats/handlebars.js/releases)
- [Changelog](https://github.com/wycats/handlebars.js/blob/v4.1.0/release-notes.md)
- [Commits](https://github.com/wycats/handlebars.js/compare/v4.0.12...v4.1.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-14 20:36:00 +00:00
dependabot[bot]
5c44cf5d23 Bump prop-types from 15.7.1 to 15.7.2 (#2993)
Bumps [prop-types](https://github.com/facebook/prop-types) from 15.7.1 to 15.7.2.
- [Release notes](https://github.com/facebook/prop-types/releases)
- [Changelog](https://github.com/facebook/prop-types/blob/master/CHANGELOG.md)
- [Commits](https://github.com/facebook/prop-types/compare/v15.7.1...v15.7.2)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-14 20:31:35 +00:00
dependabot[bot]
74b7bba79e Bump eslint-plugin-mocha from 5.2.1 to 5.3.0 (#2994)
Bumps [eslint-plugin-mocha](https://github.com/lo1tuma/eslint-plugin-mocha) from 5.2.1 to 5.3.0.
- [Release notes](https://github.com/lo1tuma/eslint-plugin-mocha/releases)
- [Changelog](https://github.com/lo1tuma/eslint-plugin-mocha/blob/master/CHANGELOG.md)
- [Commits](https://github.com/lo1tuma/eslint-plugin-mocha/compare/5.2.1...5.3.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-14 20:24:45 +00:00
Paul Melnikow
951aa0f9ea Tweak [spiget] badges (#2989)
1. Move tested server version to platform support, tweak description
2. Make version label consistent with others
3. Avoid setting category or defaultBadgeData in abstract base class
2019-02-13 21:06:31 +00:00
dependabot[bot]
c8d49d702a Bump gatsby from 2.0.118 to 2.1.0 (#2990)
Bumps [gatsby](https://github.com/gatsbyjs/gatsby) from 2.0.118 to 2.1.0.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-13 20:59:28 +00:00
dependabot[bot]
0284697ffe Bump react-pose from 4.0.6 to 4.0.7 (#2985)
Bumps [react-pose](https://github.com/Popmotion/popmotion) from 4.0.6 to 4.0.7.
- [Release notes](https://github.com/Popmotion/popmotion/releases)
- [Commits](https://github.com/Popmotion/popmotion/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-13 20:56:16 +00:00
dependabot[bot]
3acef2fb2e Bump danger from 7.0.10 to 7.0.11 (#2984)
Bumps [danger](https://github.com/danger/danger-js) from 7.0.10 to 7.0.11.
- [Release notes](https://github.com/danger/danger-js/releases)
- [Changelog](https://github.com/danger/danger-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/danger/danger-js/compare/7.0.10...7.0.11)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-13 20:49:33 +00:00
dependabot[bot]
5d7bfe7d0b Bump gatsby-plugin-catch-links from 2.0.10 to 2.0.11 (#2983)
Bumps [gatsby-plugin-catch-links](https://github.com/gatsbyjs/gatsby) from 2.0.10 to 2.0.11.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-13 20:47:15 +00:00
Pierre-Yves B
bc96f0e25f Example keywords validation (#2956)
This pull request closes #2551: making sure that the keywords don't already appear in the example's title.

I also added validation that checks that they are at least two characters long, as this is enforced by the homepage when type your search.
2019-02-13 13:14:12 -04:00
Paul Melnikow
28948925c2 Remove unused parameter in [jsdelivr] (#2988)
`headers` is not destructured; it needs to go in `options`.

`Shields.io` is set as the `User-Agent` by code in `legacy-request-handler.js`.
2019-02-13 10:53:48 -06:00
Hugo van Rijswijk
56d374a467 Allow plus in semver [Nexus aur bintray chocolatey dubversion myget nuget powershellgallery resharper] (#2987)
* Also allow + in semver

* Add test for + in semver version

* Add more dashes to test version

* Fix tests
2019-02-13 10:50:21 -06:00
chris48s
b87d67bb18 refactor [cocoapods] service (#2977)
* refactor [cocoapods] service

* remove pointless default

* move join to render()
2019-02-12 20:14:36 -06:00
James Cahill
e1a50a7246 [jsDelivr] badges (#2970) 2019-02-12 19:45:18 +00:00
dependabot[bot]
6e36e52084 Bump danger from 7.0.9 to 7.0.10 (#2976)
Bumps [danger](https://github.com/danger/danger-js) from 7.0.9 to 7.0.10.
- [Release notes](https://github.com/danger/danger-js/releases)
- [Changelog](https://github.com/danger/danger-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/danger/danger-js/compare/7.0.9...7.0.10)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-11 20:43:46 +00:00
dependabot[bot]
969ad81e05 Bump fast-xml-parser from 3.12.12 to 3.12.13 (#2974)
Bumps [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) from 3.12.12 to 3.12.13.
- [Release notes](https://github.com/NaturalIntelligence/fast-xml-parser/releases)
- [Changelog](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md)
- [Commits](https://github.com/NaturalIntelligence/fast-xml-parser/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-11 20:41:00 +00:00
dependabot[bot]
5aa63c1f3f Bump walkdir from 0.2.0 to 0.3.2 (#2960)
Bumps [walkdir](https://github.com/soldair/node-walkdir) from 0.2.0 to 0.3.2.
- [Release notes](https://github.com/soldair/node-walkdir/releases)
- [Changelog](https://github.com/soldair/node-walkdir/blob/master/CHANGELOG.md)
- [Commits](https://github.com/soldair/node-walkdir/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-11 20:37:26 +00:00
dependabot[bot]
3cfb4b2fa8 Bump prop-types from 15.6.2 to 15.7.1 (#2973)
Bumps [prop-types](https://github.com/facebook/prop-types) from 15.6.2 to 15.7.1.
- [Release notes](https://github.com/facebook/prop-types/releases)
- [Changelog](https://github.com/facebook/prop-types/blob/master/CHANGELOG.md)
- [Commits](https://github.com/facebook/prop-types/compare/v15.6.2...v15.7.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-11 20:34:40 +00:00
chris48s
93a209f8a4 refactor [amo] service (#2972)
* refactor [amo] service

* change colour
2019-02-10 15:42:35 -06:00
Paul Melnikow
725ffca2d1 Add some more perfunctory coverage of the frontend (#2962) 2019-02-10 20:34:17 +00:00
dependabot[bot]
1379ea3980 Bump danger from 7.0.7 to 7.0.9 (#2961)
Bumps [danger](https://github.com/danger/danger-js) from 7.0.7 to 7.0.9.
- [Release notes](https://github.com/danger/danger-js/releases)
- [Changelog](https://github.com/danger/danger-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/danger/danger-js/compare/7.0.7...7.0.9)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-10 11:41:34 +00:00
Caleb Cartwright
9b4fec0d2e Restored coverity service (#2967) 2019-02-10 11:39:12 +00:00
Paul Melnikow
dfb8d0392c Update coverage ignores (#2966)
* Update coverage ignores

* Add one removed by mistake

* Clean diff

* chore: minor coverage update
2019-02-09 16:18:00 -06:00
Paul Melnikow
5f2ab77319 Add some coverage to BaseService, export directly, improve an error message (#2963) 2019-02-09 15:46:11 -06:00
Caleb Cartwright
8d94c25c8a Update build status list (#2965)
Fixes #2848 

Appveyor briefly has a status of `starting` before the job begins, so adding `starting` to the list of `otherStatuses` to prevent the Appveyor badges from showing `invalid response data` during that window
2019-02-09 15:43:08 -06:00
Paul Melnikow
dbe5eb8346 Some cleanup in [bower] (#2959)
* Some cleanup in [bower]

* More fixes
2019-02-08 17:38:13 -06:00
dependabot[bot]
e800d48e70 Bump gatsby from 2.0.115 to 2.0.116 (#2947)
* Bump gatsby from 2.0.115 to 2.0.116

Bumps [gatsby](https://github.com/gatsbyjs/gatsby) from 2.0.115 to 2.0.116.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>

* Reset package-lock

* Update lockfile

* caret to tilde for gatsby

* Why stop there

* Bump to 2.0.117

* Bump to 2.0.118 which fixes the issue
2019-02-08 13:31:43 -06:00
Owen Voke
5702ac470e Add badge for the [HSTS] preload list (#2926)
As per #2913, this PR adds a new badge for the [HSTS preload][hsts] list.

Badges will use the format `/hsts/preload/:domain.svg` (e.g. `/hsts/preload/github.com.svg`)

Closes #2913 

[hsts]: https://hstspreload.org
2019-02-08 07:59:42 -05:00
Paul Melnikow
1486fd2fca Redirect from alias to canonical URL [azuredevops vso] (#2939)
As described in #2340, this provides a way to replace an old alias with a redirect. This makes it easier to migrate our URLs over time without making our matching patterns more complicated.

The 301 redirect is sent back to the requester. If a user pastes the aliased URL into the address bar, it'll be replaced in the browser with the new URL, which gently encourages them to migrate.

Close #2340
2019-02-08 01:07:50 -05:00
Paul Melnikow
4d45fe3ea0 Make [wercker] no builds terminology consistent with other badges (#2957)
This makes the "no builds" state pass `isBuildStatus`, which is what fixes the failing tests:

https://circleci.com/gh/badges/daily-tests/138
2019-02-08 00:52:20 -05:00
Paul Melnikow
8c478d0e0a Use normalized colors to fix [dynamic matrix nexus] service tests (#2958) 2019-02-08 00:49:27 -05:00
Paul Melnikow
ae37e9b723 Add a diagnostic page for testing logos (#2890)
It can be helpful to have some diagnostic pages for development and quality control. I added one here for the logos, which renders all the named logos in ?style=flat and ?style=social.
2019-02-08 00:08:45 -05:00
Andrew Marcuse
c46d2f9dae [NodePing] support for NodePing uptime monitoring service (#2910)
* [NodePing] support for NodePing uptime monitoring service

* NodePing test tweaks
2019-02-07 20:24:40 -06:00
Paul Melnikow
2ee1327eed Refactor the NuGet v2 badges; switch Resharper to XML (#2934)
This closes #2921 by switching ReSharper to the XML API used by Powershell, and refactors the powershell code back into the common nuget v2 service class. It also removes mocked tests of the color logic, replacing them with smaller-bracket tests that accomplish the same thing more concisely.
2019-02-07 21:14:04 -05:00
dependabot[bot]
49ee68fcb3 Bump babel-preset-gatsby from 0.1.6 to 0.1.7 (#2949)
Bumps babel-preset-gatsby from 0.1.6 to 0.1.7.

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-07 20:11:04 -05:00
dependabot[bot]
310bfba542 Bump react from 16.7.0 to 16.8.1 (#2950)
* Bump react from 16.7.0 to 16.8.1

Bumps [react](https://github.com/facebook/react) from 16.7.0 to 16.8.1.
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/compare/v16.7.0...v16.8.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>

* Update lockfile
2019-02-07 19:46:10 -05:00
dependabot[bot]
f963fa4421 Bump walkdir from 0.0.12 to 0.2.0 (#2948)
Bumps [walkdir](https://github.com/soldair/node-walkdir) from 0.0.12 to 0.2.0.
- [Release notes](https://github.com/soldair/node-walkdir/releases)
- [Changelog](https://github.com/soldair/node-walkdir/blob/master/CHANGELOG.md)
- [Commits](https://github.com/soldair/node-walkdir/commits/v0.2.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-07 19:38:31 -05:00
dependabot[bot]
568d687fa6 Bump react-dom from 16.7.0 to 16.8.1 (#2946)
Bumps [react-dom](https://github.com/facebook/react) from 16.7.0 to 16.8.1.
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/compare/v16.7.0...v16.8.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-07 19:35:44 -05:00
dependabot[bot]
de916536e4 [Security] Bump lodash from 4.17.10 to 4.17.11 (#2954)
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.10 to 4.17.11. **This update includes security fixes.**
- [Release notes](https://github.com/lodash/lodash/releases)
- [Changelog](https://github.com/lodash/lodash/blob/master/CHANGELOG)
- [Commits](https://github.com/lodash/lodash/compare/4.17.10...4.17.11)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-07 19:19:08 +00:00
Owen Voke
dd6ee70802 Update from RawGit to local path (#2952) 2019-02-07 12:44:51 -05:00
Paul Melnikow
9070570a39 Update deploy script for Gatsby deploy (#2944)
Knock on wood, that deploy went remarkably well. 👔
2019-02-07 00:59:33 -05:00
Paul Melnikow
da5fd26847 Readme: Repair link to logo (#2945) 2019-02-06 19:15:16 -06:00
Paul Melnikow
d8ce045ead Adopt Gatsby (#2906)
While Next.js can handle static sites, we've had a few issues with it, notably a performance hit at runtime and some bugginess around routing and SSR. Gatsby being fully intended for high-performance static sites makes it a great technical fit for the Shields frontend. The `createPages()` API should be a really nice way to add a page for each service family, for example.

This migrates the frontend from Next.js to Gatsby. Gatsby is a powerful tool, which has a bit of downside as there's a lot to dig through. Overall I found configuration easier than Next.js. There are a lot of plugins and for the most part they worked out of the box. The documentation is good.

Links are cleaner now: there is no #. This will break old links though perhaps we could add some redirection to help with that. The only one I’m really concerned about `/#/endpoint`. I’m not sure if folks are deep-linking to the category pages.

There are a lot of enhancements we could add, in order to speed up the site even more. In particular we could think about inlining the SVGs rather than making separate requests for each one.

While Gatsby recommends GraphQL, it's not required. To keep things simple and reduce the learning curve, I did not use it here.

Close #1943 
Fix #2837 Fix #2616
2019-02-06 16:37:55 -05:00
Philip Harrison
cf7b76d5a6 Update Dependabot logo (#2931)
* Update dependabot logo
* update tests
2019-02-06 21:33:40 +00:00
chris48s
7953a97e1d refactor [jitpack] service (#2943) 2019-02-06 16:11:46 -05:00
chris48s
4a8a1f20ef refactor [pub] service (#2942) 2019-02-06 16:07:06 -05:00
dependabot[bot]
44c891a3be Bump enzyme-adapter-react-16 from 1.9.0 to 1.9.1 (#2941)
Bumps [enzyme-adapter-react-16](https://github.com/airbnb/enzyme) from 1.9.0 to 1.9.1.
- [Release notes](https://github.com/airbnb/enzyme/releases)
- [Changelog](https://github.com/airbnb/enzyme/blob/master/CHANGELOG.md)
- [Commits](https://github.com/airbnb/enzyme/compare/enzyme-adapter-utils@1.9.0...enzyme-adapter-utils@1.9.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-06 00:47:45 -05:00
Caleb Cartwright
aa105e4a6c tests: update teamcity test targets (#2940) 2019-02-05 21:39:54 -06:00
Caleb Cartwright
855c9cd261 Remove dev dep imports in production code (#2937)
Fixes #2876 with @paulmelnikow's suggestion 

Moved imports of `ServiceTester` and `createServiceTester` to a separate file so that dev dependencies are not imported by service classes.
2019-02-05 21:51:55 -05:00
Paul Melnikow
cdeba2fdf9 Fix some service tests [circle dependabot githubissues] (#2936) 2019-02-05 21:49:40 -05:00
Paul Melnikow
84e5d58d9b Add CLI for debugging badges (#2930)
Often when responding to bug reports it would be helpful to easily run an example failing badge URL. It takes a while to do that, because you have to copy and paste just the right part of the badge URL. This works on `img.shields.io` links as well as partial paths and should make this really easy. 💨
2019-02-05 21:47:30 -05:00
Paul Melnikow
e083dd3ce5 deprecatedService: rename url to route for consistency; test on [versioneye] (#2938) 2019-02-05 21:37:00 -05:00
dependabot[bot]
023588bbc2 Bump nyc from 13.1.0 to 13.2.0 (#2923)
Bumps [nyc](https://github.com/istanbuljs/nyc) from 13.1.0 to 13.2.0.
- [Release notes](https://github.com/istanbuljs/nyc/releases)
- [Changelog](https://github.com/istanbuljs/nyc/blob/master/CHANGELOG.md)
- [Commits](https://github.com/istanbuljs/nyc/compare/v13.1.0...v13.2.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-05 17:47:34 -05:00
dependabot[bot]
e383c0e36c Bump @babel/plugin-proposal-object-rest-spread from 7.3.1 to 7.3.2 (#2925)
Bumps [@babel/plugin-proposal-object-rest-spread](https://github.com/babel/babel) from 7.3.1 to 7.3.2.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.3.1...v7.3.2)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-05 17:40:08 -05:00
Pierre-Yves B
b6c2f166f5 Fixed Jacoco example (#2933)
This small pull request closes #2648. The previous project targeted by the example no longer seems to be using the Jacoco plugin, so I've hunted down another one:
https://img.shields.io/jenkins/j/https/builds.apache.org/job/Derby-JaCoCo.svg 
![](https://img.shields.io/jenkins/j/https/builds.apache.org/job/Derby-JaCoCo.svg)
2019-02-05 17:38:00 -05:00
dependabot[bot]
652e960204 Bump enzyme-adapter-react-16 from 1.8.0 to 1.9.0 (#2922)
Bumps [enzyme-adapter-react-16](https://github.com/airbnb/enzyme) from 1.8.0 to 1.9.0.
- [Release notes](https://github.com/airbnb/enzyme/releases)
- [Changelog](https://github.com/airbnb/enzyme/blob/master/CHANGELOG.md)
- [Commits](https://github.com/airbnb/enzyme/compare/enzyme-adapter-utils@1.8.0...enzyme-adapter-utils@1.9.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-05 17:31:52 -05:00
Paul Melnikow
ef5c36dcb4 Remove some obsolete .networkOff() tests (#2932) 2019-02-05 21:23:24 +00:00
dependabot[bot]
3b8fb49aac Bump nock from 11.0.0-beta.5 to 11.0.0-beta.6 (#2924)
Bumps [nock](https://github.com/nock/nock) from 11.0.0-beta.5 to 11.0.0-beta.6.
- [Release notes](https://github.com/nock/nock/releases)
- [Changelog](https://github.com/nock/nock/blob/beta/CHANGELOG.md)
- [Commits](https://github.com/nock/nock/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-05 10:08:17 -05:00
Pierre-Yves B
ea833a83c4 [GitHubCommitActivity] improvements and examples (#2920) 2019-02-04 20:27:52 -05:00
chris48s
566a8cb461 delete LGTM logo (#2919) 2019-02-04 21:13:32 +00:00
Paul Melnikow
552e5e798d Add semantic color keywords and improve formatting of color examples (#2869)
* Add semantic color keywords

This is based on the list I proposed at https://github.com/badges/shields/issues/1522#issuecomment-456455618. As I started documenting `default` I realized it didn't feel quite right. It's not semantic in relation to the content the way the others are, and it's also not the default left color. I changed it to `disabled` which isn't perfect, but seems better. I'm open to other suggestions.

I updated the documentation but the colors won't render correctly until this is deployed

Close #1522

* Reformat the aliases

* Pretty up the docs

* Reset whitespace changes

* Clean lint
2019-02-04 15:05:57 -06:00
dependabot[bot]
6179090a96 Bump lint-staged from 8.1.1 to 8.1.3 (#2918)
Bumps [lint-staged](https://github.com/okonet/lint-staged) from 8.1.1 to 8.1.3.
- [Release notes](https://github.com/okonet/lint-staged/releases)
- [Commits](https://github.com/okonet/lint-staged/compare/v8.1.1...v8.1.3)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-04 20:59:07 +00:00
dependabot[bot]
26f3881e7c Bump danger from 7.0.4 to 7.0.7 (#2917)
Bumps [danger](https://github.com/danger/danger-js) from 7.0.4 to 7.0.7.
- [Release notes](https://github.com/danger/danger-js/releases)
- [Changelog](https://github.com/danger/danger-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/danger/danger-js/compare/7.0.4...7.0.7)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-04 20:57:18 +00:00
dependabot[bot]
4d9a1967dd Bump eslint from 5.12.1 to 5.13.0 (#2914)
Bumps [eslint](https://github.com/eslint/eslint) from 5.12.1 to 5.13.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v5.12.1...v5.13.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-04 20:54:27 +00:00
dependabot[bot]
e3b6f06e08 Bump prettier from 1.16.3 to 1.16.4 (#2916)
Bumps [prettier](https://github.com/prettier/prettier) from 1.16.3 to 1.16.4.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/master/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/1.16.3...1.16.4)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-04 20:49:13 +00:00
dependabot[bot]
006cc92729 Bump simple-icons from 1.9.18 to 1.9.19 (#2915)
Bumps [simple-icons](https://github.com/simple-icons/simple-icons) from 1.9.18 to 1.9.19.
- [Release notes](https://github.com/simple-icons/simple-icons/releases)
- [Commits](https://github.com/simple-icons/simple-icons/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-04 20:16:27 +00:00
Paul Melnikow
7c3bca1ab7 Refactor endpoint functions (#2909) 2019-02-03 17:29:52 -05:00
dependabot[bot]
a72a36d1fc Bump lint-staged from 8.1.0 to 8.1.1 (#2892)
Bumps [lint-staged](https://github.com/okonet/lint-staged) from 8.1.0 to 8.1.1.
- [Release notes](https://github.com/okonet/lint-staged/releases)
- [Commits](https://github.com/okonet/lint-staged/compare/v8.1.0...v8.1.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-03 10:54:18 +00:00
dependabot[bot]
2895cf5761 Bump danger from 7.0.2 to 7.0.4 (#2884)
Bumps [danger](https://github.com/danger/danger-js) from 7.0.2 to 7.0.4.
- [Release notes](https://github.com/danger/danger-js/releases)
- [Changelog](https://github.com/danger/danger-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/danger/danger-js/compare/7.0.2...7.0.4)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-03 10:52:11 +00:00
Paul Melnikow
b01e466284 Endpoint page: improve formatting (#2907)
Partly addresses #2837 but does not resolve it
2019-02-02 14:10:52 -05:00
dependabot[bot]
89ee5d1cb1 Bump prettier from 1.16.1 to 1.16.3 (#2902)
Bumps [prettier](https://github.com/prettier/prettier) from 1.16.1 to 1.16.3.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/master/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/1.16.1...1.16.3)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-01 17:20:14 -05:00
Paul Melnikow
3a7bddbc26 Consolidate service definition schema, removing support for previewUrl (#2895)
This removes `LONG_CACHE` and its descendants, which was a feature that added `?maxAge` to the live preview badges in the frontend. Since they are all static that is no longer needed, as the static badges all have longer cache timeouts regardless.
2019-01-30 18:35:11 -06:00
Paul Melnikow
7955f460f3 Move suggest code and rewrite tests (#2886)
The suggest code was an exception to our usual organization pattern. There was a service test, but it's not a service. The code would sometimes regress because it wasn't being tested all the time.

This makes them no longer run as service tests, which is good because they run as part of every build. Some of them are smaller-bracket tests which is good too, because it will make them easier to test, especially as this code grows.

I'd have liked to keep using frisby for the ones that make requests to the server, though I ran into some issues with sequencing of setup that I think will require upstream changes.
2019-01-30 17:48:54 -06:00
Paul Melnikow
f32306d982 Update production DNS access doc (#2899)
* Update production DNS access doc

Thanks @olivierlacan!

* Add link to DNS registrar

* Updates
2019-01-30 17:41:44 -06:00
Paul Melnikow
085c43d42d Remove unused dependencies (#2900) 2019-01-30 17:38:18 -06:00
Paul Melnikow
4fc31cfff9 Add timeouts to some flaky tests (#2896)
* Add timeouts to some flaky tests

* tests: increased timeouts on snyk tests
2019-01-30 17:35:40 -06:00
Olivier Lacan
5af5c480db Fix typos and clarify non-promotional (#2898)
Just noticed this typo and that one of the essential parts of the specification 
could be worded more clearly. It seems like the hardest to enforce with SaaS 
companies, so I don't think the explicitness will hurt.
2019-01-30 16:08:50 -05:00
dependabot[bot]
1a5336385c Bump eslint-plugin-import from 2.15.0 to 2.16.0 (#2897)
Bumps [eslint-plugin-import](https://github.com/benmosher/eslint-plugin-import) from 2.15.0 to 2.16.0.
- [Release notes](https://github.com/benmosher/eslint-plugin-import/releases)
- [Changelog](https://github.com/benmosher/eslint-plugin-import/blob/master/CHANGELOG.md)
- [Commits](https://github.com/benmosher/eslint-plugin-import/compare/v2.15.0...v2.16.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-30 10:43:52 -06:00
Paul Melnikow
eef3d36f52 Convert remaining preview URLs (#2887)
Close #1961
2019-01-29 21:13:15 -06:00
dependabot[bot]
27b053284e Bump snap-shot-it from 6.2.8 to 6.2.9 (#2885)
Bumps [snap-shot-it](https://github.com/bahmutov/snap-shot-it) from 6.2.8 to 6.2.9.
- [Release notes](https://github.com/bahmutov/snap-shot-it/releases)
- [Commits](https://github.com/bahmutov/snap-shot-it/compare/v6.2.8...v6.2.9)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-29 19:37:33 -06:00
Paul Melnikow
027cb4fe31 Fix [conda] service tests and rm some obsolete tests (#2894)
Ref https://circleci.com/gh/badges/daily-tests/119
2019-01-29 19:31:45 -06:00
James Cahill
57badc337a Refactor [lgtm] to new service model and static previews (#2753) 2019-01-29 16:10:47 -06:00
chris48s
a47fb2895d update logo guidance (#2888)
Ref #2510
2019-01-29 15:29:51 -06:00
chris48s
daa06c2026 don't apply logoColor param to multi-coloured logos (#2889)
This stops us from doing this:

![](https://img.shields.io/badge/logo-npm-blue.svg?logo=npm&logoColor=green) - https://img.shields.io/badge/logo-npm-blue.svg?logo=npm&logoColor=green
but still allows us to do this
![](https://img.shields.io/badge/logo-discord-blue.svg?logo=discord&logoColor=green) - https://img.shields.io/badge/logo-discord-blue.svg?logo=discord&logoColor=green
2019-01-29 15:22:28 -06:00
dependabot[bot]
efdb9f3e51 Bump eslint-config-prettier from 3.6.0 to 4.0.0 (#2883)
Bumps [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) from 3.6.0 to 4.0.0.
- [Release notes](https://github.com/prettier/eslint-config-prettier/releases)
- [Changelog](https://github.com/prettier/eslint-config-prettier/blob/master/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-config-prettier/compare/v3.6.0...v4.0.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-29 11:54:35 -06:00
Paul Melnikow
5b122ddd73 Social badge support for static previews (#2871)
The static previews don't support the social badges. Adding that lets us remove support for `exampleUrl`. Close #2479.

This includes `style` and `namedLogo` in the service-definition export and updates the frontend to use it. To accomplish this, it passes `namedLogo` through `coalesceBadge`. After logo resolution is moved to `makeBadge` this duplication can be removed, as `logo` will no longer be needed in the result of `coalesceBadge`.
2019-01-28 22:44:25 -06:00
Paul Melnikow
e10e8b1b6d Code walkthrough (#2877)
Updated based on comments received in the Google Doc.

Close #2684
2019-01-28 15:03:05 -06:00
chris48s
a9d6809e3f refactor [liberapay] service (#2879) 2019-01-28 20:57:11 +00:00
Paul Melnikow
97e2ec1e60 Refactor [GemDownloads] for readability; improve error messages (#2870)
Close #1960
2019-01-28 11:53:53 -06:00
chris48s
212ac47ec0 refactor [hackage] service (#2878) 2019-01-27 20:32:58 -06:00
chris48s
3e34d98e41 replace telegram logo (#2880) 2019-01-27 18:29:47 +00:00
chris48s
1822a3adfb more icon changes (#2872)
* delete scrutinizer logo
* optimise superuser logo
2019-01-27 18:27:27 +00:00
chris48s
64b8f6ec15 optimise logos (#2873) 2019-01-27 12:55:03 +00:00
chris48s
29379014fe optimise discord logo, change default colour (#2874) 2019-01-26 17:53:23 +00:00
Paul Melnikow
47e8cc3de3 Refactor route functions in BaseService (#2860)
The route helper functions are fairly well isolated from the rest of BaseService, with a few convenient entry points. They are easier to test in isolation.

The way the code was written before, `pathToRegexp` was invoked once for every request, which seems inefficient.

`route` was validated when it was used, though it seems more helpful to validate it up front.

This breaks out `_makeFullUrl`, `_regex`, `_regexFromPath` into new helper functions `makeFullUrl`, `assertValidRoute`, `prepareRoute`, and `namedParamsForMatch`.

It adds validation to route, and updates the services without patterns to include one, in order to pass the new validation rules.
2019-01-26 02:38:12 -05:00
chris48s
bf5438f457 Delete some of our logos (part 1) (#2857)
Refs #2510

I'm going to delete or change some more logos in a further PR or two, but lets start off with the (hopefully) non-controversial ones. I think in all of these cases it is fairly clear-cut that we are not losing anything by removing our icon in favour of simple-icons now that we apply a sensible colour by default.
2019-01-25 12:51:41 -05:00
dependabot[bot]
8777ba1cb1 Bump enzyme-adapter-react-16 from 1.7.1 to 1.8.0 (#2864)
Bumps [enzyme-adapter-react-16](https://github.com/airbnb/enzyme) from 1.7.1 to 1.8.0.
- [Release notes](https://github.com/airbnb/enzyme/releases)
- [Changelog](https://github.com/airbnb/enzyme/blob/master/CHANGELOG.md)
- [Commits](https://github.com/airbnb/enzyme/commits/enzyme-adapter-utils@1.8.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-25 12:33:23 -05:00
dependabot[bot]
b77e2421e3 Bump nock from 11.0.0-beta.4 to 11.0.0-beta.5 (#2865)
Bumps [nock](https://github.com/nock/nock) from 11.0.0-beta.4 to 11.0.0-beta.5.
- [Release notes](https://github.com/nock/nock/releases)
- [Changelog](https://github.com/nock/nock/blob/beta/CHANGELOG.md)
- [Commits](https://github.com/nock/nock/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-25 12:12:20 -05:00
Paul Melnikow
be7cb93773 Refactor service loader (#2861)
This moves the loader code into `core/base-service`, leaving behind in `services/index.js` only the convenience imports.

Ref #2832
2019-01-24 22:55:10 -05:00
Paul Melnikow
23fe3927b2 Refactor _makeBadgeData -> coalesceBadge (#2859)
`base.js` is pretty long and `_makeBadgeData` is one of the most complex
functions in it.

It's a pure function so it's easy to test in isolation. This moves the function into its own module and reorganizes the tests in a way that makes it evaluate what it's doing, and easier to test what is and isn't covered.

Ref https://github.com/badges/shields/pull/2796#discussion_r249251008
2019-01-24 22:48:45 -05:00
dependabot[bot]
2db22abd11 Bump @babel/plugin-proposal-object-rest-spread from 7.3.0 to 7.3.1 (#2853)
Bumps [@babel/plugin-proposal-object-rest-spread](https://github.com/babel/babel) from 7.3.0 to 7.3.1.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.3.0...v7.3.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-24 20:49:58 +00:00
dependabot[bot]
e718ecaeb0 Bump bytes from 3.0.0 to 3.1.0 (#2851)
Bumps [bytes](https://github.com/visionmedia/bytes.js) from 3.0.0 to 3.1.0.
- [Release notes](https://github.com/visionmedia/bytes.js/releases)
- [Changelog](https://github.com/visionmedia/bytes.js/blob/master/History.md)
- [Commits](https://github.com/visionmedia/bytes.js/compare/3.0.0...3.1.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-24 20:46:46 +00:00
dependabot[bot]
9cb399a8dc Bump eslint-plugin-import from 2.14.0 to 2.15.0 (#2852)
Bumps [eslint-plugin-import](https://github.com/benmosher/eslint-plugin-import) from 2.14.0 to 2.15.0.
- [Release notes](https://github.com/benmosher/eslint-plugin-import/releases)
- [Changelog](https://github.com/benmosher/eslint-plugin-import/blob/master/CHANGELOG.md)
- [Commits](https://github.com/benmosher/eslint-plugin-import/compare/v2.14.0...v2.15.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-24 01:00:24 -05:00
dependabot[bot]
d03faaa7bb Bump @babel/plugin-proposal-class-properties from 7.2.3 to 7.3.0 (#2841)
Bumps [@babel/plugin-proposal-class-properties](https://github.com/babel/babel) from 7.2.3 to 7.3.0.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.2.3...v7.3.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-24 00:57:54 -05:00
dependabot[bot]
8c4c5ed6bd Bump @babel/preset-env from 7.2.3 to 7.3.1 (#2843)
Bumps [@babel/preset-env](https://github.com/babel/babel) from 7.2.3 to 7.3.1.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.2.3...v7.3.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-24 00:56:02 -05:00
dependabot[bot]
1cc7be7989 Bump moment from 2.23.0 to 2.24.0 (#2839)
Bumps [moment](https://github.com/moment/moment) from 2.23.0 to 2.24.0.
- [Release notes](https://github.com/moment/moment/releases)
- [Changelog](https://github.com/moment/moment/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/moment/moment/compare/2.23.0...2.24.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-23 21:54:48 -05:00
Caleb Cartwright
8e41e95a4e Update [VisualStudioMarketplace] download calculation for Azure DevOps Extensions (#2748)
* feat: udpate vs marketplace download counts to handle azure devops scenario

* chore: added documentation info to download badge for AzureDevOps on VS Marketplace

* refactor: updated VS Marketplace Downloads badge to better cover Azure DevOps extensions

* feat: added separate service for ADO extension install badges

* refactor: simplifying vs marketplace statistics transform

* refactor: finished refactoring VS Marketplace services

* docs: added inline comment on VS Marketplace service base

* Tweak docs

* refactor: tweaked validation for VS Marketplace response

* chore: added todo in VS Marketplace base

* Tweak comment

* refactor: VS Marketplace base validation cleanup

* refactor: moved rating precision in VS Marketplace
2019-01-23 18:14:26 -06:00
Paul Melnikow
4e9763b4c3 Provide friendlier error messages for [endpoint] (#2858)
Ref https://github.com/badges/shields/issues/2838#issuecomment-456594803
2019-01-23 18:43:38 -05:00
chris48s
a8bedce8a4 clarify cache docs for endpoint badge (#2855) 2019-01-23 22:02:43 +00:00
chris48s
7e473fe72c pre-compute the 3 most common icon styles on server init (#2856)
refs #2833 (comment)
2019-01-23 16:41:10 -05:00
chris48s
eaa64a8dab automatically show light or dark logos when using simple-icons (#2833)
closes #2431
refs #2510
2019-01-23 14:42:08 -05:00
dependabot[bot]
1ac208e656 Bump react-pose from 4.0.5 to 4.0.6 (#2850)
Bumps [react-pose](https://github.com/Popmotion/popmotion) from 4.0.5 to 4.0.6.
- [Release notes](https://github.com/Popmotion/popmotion/releases)
- [Commits](https://github.com/Popmotion/popmotion/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-23 11:01:08 -05:00
dependabot[bot]
b1b92b6654 Bump prettier from 1.16.0 to 1.16.1 (#2849)
Bumps [prettier](https://github.com/prettier/prettier) from 1.16.0 to 1.16.1.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/master/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/1.16.0...1.16.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-23 10:26:58 -05:00
Paul Melnikow
fc12b591db Reorganize BaseService-related modules (#2831)
Ref #2698
2019-01-22 23:52:13 -05:00
Paul Melnikow
bbc10c5a68 Remove unused TokenProvider code (#2844)
The TokenProvider abstraction was refactored away during #1205 and is now obsolete. Other users of token pooling should use TokenPool and TokenPersistence directly.
2019-01-22 21:39:04 -05:00
dependabot[bot]
cd89a4db9e Bump @babel/plugin-proposal-object-rest-spread from 7.2.0 to 7.3.0 (#2842)
Bumps [@babel/plugin-proposal-object-rest-spread](https://github.com/babel/babel) from 7.2.0 to 7.3.0.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.2.0...v7.3.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-22 08:46:42 -05:00
Paul Melnikow
c7844ca7bb Fix a preview badge (#2836) 2019-01-21 23:04:52 -05:00
Paul Melnikow
0fc3df84d7 [Endpoint] badge (#2473)
This reimplements the idea @bkdotcom came up with in #1519, and took a stab at in #1525. It’s a really powerful way to add all sorts of custom badges, particularly considering [tools like RunKit endpoints and Jupyter Kernel Gateway](https://github.com/badges/shields/issues/2259#issuecomment-444186589), not to mention all the other ways cloud functions can be deployed these days.
2019-01-21 22:55:24 -05:00
Paul Melnikow
6a17210850 Fix production crash (#2835)
`ShieldsRuntimeError` is in `services/errors.js` but not `services/index.js`. Oops!

Close #2834
2019-01-21 22:41:50 -05:00
Paul Melnikow
aac2a4d5ad Move legacy request helpers (#2829)
In #2698 we decided to put legacy helper functions in `core/legacy`. I think that’s a fine idea, though if we’re going to have a bunch of badge helper functions in there, it seems like it is probably better to keep these two important but esoteric helper functions with the core code to which they are most coupled. So I added `legacy-` to the name, and put them in `core/base-service`.
2019-01-21 22:14:22 -05:00
Paul Melnikow
eb390a30c9 Fix Redis integration tests in CI; change 10 to latest (#2830)
* Fix Redis integration tests in CI

* 10 to latest
2019-01-21 15:20:42 -06:00
Paul Melnikow
62810143ac Move coalesce and validate (#2828)
Ref #2698
2019-01-21 16:11:23 -05:00
Paul Melnikow
b13834037f Split integration tests into their own stage (#2825)
These tests fail more often than others, and it's inconvenient to hold up merging when the changes are unrelated.
2019-01-21 15:51:54 -05:00
Paul Melnikow
226fa67a02 Create shortcut for BaseService-related imports (#2809)
Continue to implement #2698:

- Add `core/base-service/index.js` (but hold off on moving the things it imports)
- Add shortcuts in `services/index.js` for Base*Service, errors, and deprecatedService. This file will be streamlined later to avoid cluttering it with rarely used bits.
- Apply consistent ordering of imports and use of `module.exports` in testers.
- Remove some renaming of imports.
- Remove obsolete tests here and there.
2019-01-21 15:41:24 -05:00
Paul Melnikow
8dc8afeb55 Avoid func declarations using function keyword (#2813)
We had only a few function expressions declared with the function keyword; almost everything is using function declarations.

This came up after this discussion: https://github.com/badges/shields/pull/2803#discussion_r249011621 though is actually not related ot that example.

What’s being removed is a third option, which is assigning to a variable a function expression using the `function` keyword. There’s still room for the programmer to choose between arrow function expressions and function declarations.
2019-01-21 15:33:43 -05:00
Felix Becker
18a65fc69c Add directory field to package.json (#2823)
https://github.com/npm/rfcs/blob/latest/accepted/0010-monorepo-subdirectory-declaration.md

This helps tools find this package in the repository.
2019-01-21 20:19:03 +00:00
Paul Melnikow
31f0b8e6d8 Optimize diffing in Danger (#2827) 2019-01-21 20:16:50 +00:00
Paul Melnikow
558576dfb7 Temporarily remove useless npm-install task in CI (#2808)
It still seems worth using workspace caching to properly tackle #1937, though in the meantime we're wasting time with a useless build. This should cut our total build latency roughly by half.
2019-01-21 13:02:35 -05:00
dependabot[bot]
cc2f514d05 Bump eslint-config-prettier from 3.5.0 to 3.6.0 (#2821)
Bumps [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) from 3.5.0 to 3.6.0.
- [Release notes](https://github.com/prettier/eslint-config-prettier/releases)
- [Changelog](https://github.com/prettier/eslint-config-prettier/blob/master/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-config-prettier/compare/v3.5.0...v3.6.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-21 12:49:52 -05:00
Antoine Boisadam
7face4995f Add [Ansible] quality score badge (#2620)
Adds quality score badge from Ansible, closes #2602
2019-01-21 12:32:28 -05:00
dependabot[bot]
fd41131579 Bump prettier from 1.15.3 to 1.16.0 (#2819)
Bumps [prettier](https://github.com/prettier/prettier) from 1.15.3 to 1.16.0.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/master/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/1.15.3...1.16.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-21 12:29:43 -05:00
dependabot[bot]
b7f0f2fd8e Bump nock from 11.0.0-beta.3 to 11.0.0-beta.4 (#2818)
Bumps [nock](https://github.com/nock/nock) from 11.0.0-beta.3 to 11.0.0-beta.4.
- [Release notes](https://github.com/nock/nock/releases)
- [Changelog](https://github.com/nock/nock/blob/beta/CHANGELOG.md)
- [Commits](https://github.com/nock/nock/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-21 12:23:29 -05:00
dependabot[bot]
a438ea7eee Bump sinon from 7.2.2 to 7.2.3 (#2820)
Bumps [sinon](https://github.com/sinonjs/sinon) from 7.2.2 to 7.2.3.
- [Release notes](https://github.com/sinonjs/sinon/releases)
- [Changelog](https://github.com/sinonjs/sinon/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sinonjs/sinon/compare/v7.2.2...v7.2.3)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-21 12:05:34 -05:00
dependabot[bot]
433f92fc1e Bump eslint from 5.12.0 to 5.12.1 (#2822)
Bumps [eslint](https://github.com/eslint/eslint) from 5.12.0 to 5.12.1.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v5.12.0...v5.12.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-21 12:00:55 -05:00
Jan Keromnes
36956897e9 Make code contributions easier with Gitpod (#2783)
Ref #2772
2019-01-21 11:44:53 -05:00
chris48s
fba846986a fix logo imports in [github twitter liberapay] (#2817)
this was moved in #2796 but we missed updating some of the imports
2019-01-20 23:19:12 -05:00
Paul Melnikow
26d0495ee6 Add logo support for the endpoint badge and refactor logo functions (#2796) 2019-01-20 20:22:46 +00:00
Paul Melnikow
a8e27d139d Fix Docker build (#2815)
Close #2814
2019-01-20 15:01:07 -05:00
chris48s
7789e80fe5 refactor [packagecontrol] service (#2803) 2019-01-19 14:28:14 -05:00
James Cahill
e3c8508ce4 Added various [Spiget] badges (#2745)
* Spiget Downloads badge

* Spiget Download Size badge

* Spiget Latest version badge

* Add a base class

* Spiget Rating / Stars badges

* Spiget versions badge

* remove useless regex escape

* use renderVersionBadge for rendering

* misc fixes

* use expectJSON when possible

* use the download count color formatter

* merge service classes

* add keywords

* Add tests for non-star ratings

* Add nock tests

* misc fixes

* chore: minor formatting update on spiget dl
2019-01-19 11:24:58 -06:00
Paul Melnikow
94acb92258 Rewrite test of analytics endpoint (#2810)
This test is being weirdly flaky in #2809. The problem seems to be in the test helper code, so I rewrote this using Joi.

I imagine the change has to do with a change to the test ordering. It's a bit puzzling.

However, the new test seems fine (and the endpoint is rarely used; not critical to begin with).
2019-01-18 23:51:07 -05:00
Paul Melnikow
69ced81cd1 Fix integration test pattern (#2811)
Ref #2792
2019-01-18 11:56:04 -06:00
dependabot[bot]
cd8528c30f Bump eslint-plugin-react from 7.12.3 to 7.12.4 (#2804)
Bumps [eslint-plugin-react](https://github.com/yannickcr/eslint-plugin-react) from 7.12.3 to 7.12.4.
- [Release notes](https://github.com/yannickcr/eslint-plugin-react/releases)
- [Changelog](https://github.com/yannickcr/eslint-plugin-react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/yannickcr/eslint-plugin-react/compare/v7.12.3...v7.12.4)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-18 06:46:46 -05:00
chris48s
653242d004 refactor [itunes] service (#2802) 2019-01-18 06:44:49 -05:00
dependabot[bot]
835c21faf3 Bump react-select from 2.2.0 to 2.3.0 (#2805)
Bumps [react-select](https://github.com/JedWatson/react-select) from 2.2.0 to 2.3.0.
- [Release notes](https://github.com/JedWatson/react-select/releases)
- [Changelog](https://github.com/JedWatson/react-select/blob/master/.sweet-changelogs.js)
- [Commits](https://github.com/JedWatson/react-select/compare/v2.2.0...v2.3.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-18 06:40:43 -05:00
Paul Melnikow
5ff7beb3bf Reorganize token pooling code (#2792)
Ref #2698
2019-01-18 06:18:31 -05:00
Paul Melnikow
4bfc8d3b72 Fix [static] tests (#2797) 2019-01-17 15:24:02 -05:00
Paul Melnikow
328a6b0f9d Set static previews for packagecontrol (#2799) 2019-01-17 15:18:55 -05:00
Paul Melnikow
d927df22c5 Convert more static previews (#2801) 2019-01-17 15:13:31 -05:00
dependabot[bot]
ab5fee2bfd Bump eslint-config-prettier from 3.4.0 to 3.5.0 (#2794)
Bumps [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) from 3.4.0 to 3.5.0.
- [Release notes](https://github.com/prettier/eslint-config-prettier/releases)
- [Changelog](https://github.com/prettier/eslint-config-prettier/blob/master/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-config-prettier/compare/v3.4.0...v3.5.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-17 20:02:26 +00:00
dependabot[bot]
f2a6569037 Bump got from 9.5.1 to 9.6.0 (#2795)
Bumps [got](https://github.com/sindresorhus/got) from 9.5.1 to 9.6.0.
- [Release notes](https://github.com/sindresorhus/got/releases)
- [Commits](https://github.com/sindresorhus/got/compare/v9.5.1...v9.6.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-17 19:59:28 +00:00
Paul Melnikow
3c98ad38ac test:server -> test:core (#2798)
This renames `npm run test:server` to `npm run test:core` to go along with the reorganization of #2698. `server` has been a bit imprecise, since there's a lot of stuff under test besides the server, and most of the tests don't hit the server itself.

Probably files like `luarocks.spec.js` ought to be run as part of a different target, especially if we build out a separate code-coverage metric for core. Though I'm not in a huge rush to sort that out.
2019-01-17 13:52:47 -05:00
Paul Melnikow
2ece7c4ee2 Wrap HTML in __html in service def export (#2791)
The intention of wrapping HTML in an `__html` is to avoid accidentally unsafe rendering of something that is non-html.

Including this in the definition export solves the problem, and does not seem too onerous for other possible users of that file.

Close #2725
2019-01-17 13:47:23 -05:00
Paul Melnikow
4415a3e94e Reorganize badge URL helper functions (#2790)
Ref #2698
2019-01-17 13:44:46 -05:00
Paul Melnikow
05b9dd46e8 BaseService: Minor stylistic refactor of color computation (#2793)
As I was working on refactoring the logo code, I thought of a way to compute the color in a way more befitting the declarative style of the function.
2019-01-16 23:36:06 -05:00
Caleb Cartwright
576a6c1dee Fix [AzureDevOps] branch specific badges (#2777)
* fix: updated Azure DevOps fetch function to reflect query param name change

* fix: fixed branch filter for azure devops to enable branch name usage

* fix: simplified branch pattern for azure devops badges
2019-01-16 21:16:32 -06:00
Paul Melnikow
bcc9acd18f Disallow redundant example patterns (#2787) 2019-01-16 19:47:10 -05:00
Paul Melnikow
7d4acba5c1 Validate namedParams in examples (#2786)
Fix #2784
2019-01-16 19:38:36 -05:00
Paul Melnikow
97e719f226 Make it harder to accidentally trigger all the service tests (#2789)
It’s happened twice that `[*]` has ended up in a PR title and the full test run has happened inadvertently. Once was me and once was a new contributor.

This raises the bar on doing it accidentally.
2019-01-16 16:58:17 -05:00
Paul Melnikow
18b98a30e3 Reorganize server and service test runner (#2781)
Ref #2698
2019-01-16 16:30:18 -05:00
Paul Melnikow
474b126be6 Fix color again, for legacy badges (#2782)
Ref: https://github.com/badges/shields/pull/2780#issuecomment-454873296
2019-01-16 13:37:48 -05:00
Paul Melnikow
4bf55a7826 Fix numeric colorB (#2780)
Numeric colors weren't properly being handled by `makeBadge` after #2742.

Since this function really does not need to be accepting colors as strings, rather than make the function more lenient to work with Scoutcamp, I coerced the types of the colors on the way in.

Two tests cover the functionality in the modern service. I don't feel strongly that the legacy version needs coverage at this point, though I've added one for the moment on the github languages badge where this manifested.

Fix #2778
2019-01-16 11:55:50 -05:00
Paul Melnikow
8a10279d95 Add static preview to some [GitHub] services (#2766) 2019-01-15 21:43:35 -05:00
Thomas Démoulins
678359bdd6 Fix orange statuses, run tests for [AppveyorCi AzureDevOps Bitbucket CircleCi Gitlab Readthedocs Shippable Wercker] (#2776)
* Fix orange statuses

* Add test for partially succeeded build

* Add service test for partially succeeded builds

* Add service test for partially succeeded builds
2019-01-15 18:56:42 -06:00
Paul Melnikow
4597d77015 Refactor badge color functions (#2742)
- Replace the idea of color schemes with the idea of named colors (since none of our colorschemes have used `colorA`)
- Pass through the normalized color to `_shields_test` to harmonize with BaseService and simplify testing
    - Update service tests
- Move responsibility for color generation into the npm package
- Remove several color helper functions and their tests
- Update gh-badge public API to accept `color` and `labelColor`

This is a precursor to refactoring some of the logo code for #2473.
2019-01-15 16:43:33 -05:00
Paul Melnikow
cab689706f Dynamic cache length overriding (#2755)
For the Endpoint badge: #2473.

`request-handler.js` is such a bear. I’m looking forward to being able to rewrite it when the service refactor is done.
2019-01-15 15:44:39 -05:00
Paul Melnikow
a2eec8c8ec Add more static previews (#2770) 2019-01-15 15:41:38 -05:00
Paul Melnikow
5026221e84 Provide better dev feedback by validating services when they are loaded (#2769)
It's easy to push services that don't validate, because much of the tooling, including the service test runner and the service definition generator, do not validate all the services. This leads to errors that manifest in CI. It would be more helpful to see these errors sooner.

This moves the `validateDefinition()` check to `loadServiceClasses()`, where the services are first loaded, and fixes related validation errors.
2019-01-15 15:39:13 -05:00
Paul Melnikow
a43711fca1 Use simpler regexes in [appveyortests] to address lgtm alert (#2768)
Two of these regexes have triggered a LGTM alert.

https://lgtm.com/rules/1505904457770/

I’m not terribly concerned about it given this is a test, though it’s nice to clear these up, and the new regexes are a bit easier to understand.
2019-01-15 15:36:52 -05:00
Pierre-Yves B
55ce947a35 Extended usage of build-status.js tomore services (#2763)
* Extended usage of build-status.js

* Removed remaining status arguments
2019-01-15 20:27:18 +00:00
Paul Melnikow
22e8510fc7 Remove some unused state to clear lgtm alerts (#2767)
39309c9c20/files/frontend/components/markup-modal/markup-modal-content.js (x9b1573629b59d42e):1
2019-01-15 14:59:02 -05:00
Paul Melnikow
79af2840f3 Fix overriding bind address on CLI (#2773)
This fixes e.g. `node server 8080 0.0.0.0`.

Ref #2772.
2019-01-15 14:38:55 -05:00
Paul Melnikow
a58de54281 Set static previews for [jenkins jenkinsplugin] and tweak tests (#2765) 2019-01-14 22:39:51 -05:00
Paul Melnikow
394a411127 Showcase two of our distinguishing features (#2705) 2019-01-14 18:54:42 -05:00
Paul Melnikow
9b4ff6a567 Unfork path-to-regexp (#2757)
pillarjs/path-to-regexp#176 has been released.
2019-01-14 20:41:48 +00:00
dependabot[bot]
eacb331f11 Bump fast-xml-parser from 3.12.11 to 3.12.12 (#2758)
Bumps [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) from 3.12.11 to 3.12.12.
- [Release notes](https://github.com/NaturalIntelligence/fast-xml-parser/releases)
- [Changelog](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md)
- [Commits](https://github.com/NaturalIntelligence/fast-xml-parser/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-14 20:38:34 +00:00
dependabot[bot]
be3102b08a Bump simple-icons from 1.9.17 to 1.9.18 (#2760)
Bumps [simple-icons](https://github.com/simple-icons/simple-icons) from 1.9.17 to 1.9.18.
- [Release notes](https://github.com/simple-icons/simple-icons/releases)
- [Commits](https://github.com/simple-icons/simple-icons/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-14 20:27:44 +00:00
Pierre-Yves B
3cebe3bbd4 Made tests use isBuildStatus validator from build-status.js (#2762) 2019-01-14 19:39:06 +00:00
dependabot[bot]
e999d9d018 Bump eslint-config-prettier from 3.3.0 to 3.4.0 (#2759)
Bumps [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) from 3.3.0 to 3.4.0.
- [Release notes](https://github.com/prettier/eslint-config-prettier/releases)
- [Changelog](https://github.com/prettier/eslint-config-prettier/blob/master/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-config-prettier/compare/v3.3.0...v3.4.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-14 11:24:22 -05:00
dependabot[bot]
a6f09913e7 Bump got from 9.5.0 to 9.5.1 (#2761)
Bumps [got](https://github.com/sindresorhus/got) from 9.5.0 to 9.5.1.
- [Release notes](https://github.com/sindresorhus/got/releases)
- [Commits](https://github.com/sindresorhus/got/compare/v9.5.0...v9.5.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-14 11:02:28 -05:00
Caleb Cartwright
dc0e5b3c54 Temporarily deprecate [CoverityScan] (#2756)
* feat: temp. deprecate coverity scan and update deprecated service to take custom messags

* tests: added unit tests for deprecated service definition
2019-01-13 15:50:50 -06:00
Paul Melnikow
5c25dce5fc Validate service data + support labelColor for the endpoint badge (#2740)
Ref #2473
2019-01-13 11:37:39 -05:00
chris48s
796d066930 remove asterisks from examples (#2749) 2019-01-13 12:17:39 +00:00
chris48s
65f075ba31 refactor [dub] service (#2751) 2019-01-13 12:13:00 +00:00
chris48s
0aca8e68ff Refactor [osslifecycle] (#2750)
* move files from osstracker to osslifecycle
* refactor [osslifecycle]
2019-01-13 12:10:28 +00:00
Michael Fyffe
698ff45959 Add pdk badge for puppet forge (#2256)
Closes #2255
2019-01-13 00:24:44 -05:00
James Cahill
4725a8dc13 Refactor the rest of [PyPI] to use static previews (#2752)
* Refactor the rest of [PyPI] to use static previews

* v1.0.0 -> 1.0.0 to match what's passed to render function
2019-01-12 23:13:45 -05:00
Paul Melnikow
ef18429420 Add Github package.json dependency version badge (#2709)
Close #2259 which is mostly about a `package.json` dependency badge.
2019-01-12 17:37:10 -05:00
Paul Melnikow
b985c7b180 Add an issue template for a failing service test (#2746) 2019-01-12 17:24:56 -05:00
Nathan Lowe
fc4ed938a1 [Bitbucket]: Pull Requests: Support Bitbucket Server (#2598)
* New Service: Bitbucket Server: Pull Request Count

* [Bitbucket]: Pull Requests: Add Support for bitbucket-server

* Update examples to use namedParams instead of exampleUrl

* Simplify cloud vs server check

* [Bitbucket]: Add support for bitbucket cloud private repos

* Add additional tests for bitbucket server

* [Bitbucket]: Add tests for basic auth

* [Bitbucket] Format secrets according to style guides

* [Bitbucket] Add link to server REST documentation

* Punt adding VSCode debug task to separate PR

* [Bitbucket] Remove extra truthy check on serverSecrets

* [Bitbucket] Fix credentials after rename

* [Bitbucket] Use query parameters for Bitbucket Server support

* Fix bitbucket creds in secret template

* [Bitbucket] staticExample -> staticPreview

* Remove VSCode specific gitignore entries

* [Bitbucket] Normalize pluralization of PullReqeust(s) to match file name
2019-01-12 14:11:47 -06:00
Paul Melnikow
fb8c7e920d Use create-service-tester shorthand in [EclipseMarketplace] (#2741) 2019-01-12 12:59:37 -05:00
Paul Melnikow
51a19a8ace Update [gemrank] regex to match "1st" (#2743)
See https://circleci.com/gh/badges/shields/34350
2019-01-12 12:34:05 -05:00
chris48s
697ff80dad limit the size of response we will accept (#2726)
limit the size of response we will accept
2019-01-11 21:50:49 +00:00
chris48s
e22934eab0 only display the menu once (#2727)
* only display the menu once
2019-01-11 21:28:18 +00:00
Paul Melnikow
b3606724fd Wildcard to run all service tests [*] (#2739)
Close #2685.
2019-01-11 16:11:46 -05:00
Caleb Cartwright
afcc0e3920 refactor: rename VS Marketplace to Visual Studio Marketplace (#2738) 2019-01-11 15:02:58 -06:00
Paul Melnikow
893071cf2c Add a script used for backing up the production GitHub tokens (#2737) 2019-01-11 14:39:41 -05:00
James Cahill
3f118f8442 TUTORIAL.md - use localhost instead of others (#2735)
Seeing as npm start now uses localhost instead of instead of 127.0.0.1 or [::], just updating it in the tutorial.
2019-01-11 13:57:51 -05:00
Paul Melnikow
eb7ea8499d Fix github auth again (#2736)
This code isn't being run during tests, though let's fix that later as part of #2733. Specifically:

> However _the pool itself_ could be used all the time; there's not a big advantage in turning that off when it doesn't need to be used.

Fix #2728
2019-01-11 13:50:29 -05:00
Paul Melnikow
269fbd056c Optimize [githubsearch] tests by using a smaller repo (#2734)
These seem to run in 300-900 ms.
2019-01-11 13:47:48 -05:00
Paul Melnikow
048291a024 Fix [GitHub] token handling (#2730)
Fix #2728
2019-01-11 13:16:44 -05:00
Caleb Cartwright
ae11905e8d refactor [VSMarketplace] to new service model (#2732)
* feat: refactor vs marketplace to new service model

* chore: fix for prettier

* chore: minor updates to vs marketplace services based on PR feedback
2019-01-11 11:32:43 -06:00
Paul Melnikow
c4efdc8e66 Rewrite and test Github auth logic, separating standard and search quota (#1205)
The end of an era.
2019-01-10 21:30:23 -05:00
Paul Melnikow
a27bef5aa5 Split “quality” into “code coverage” and “analysis” (#2723)
With the menu in place I think having more categories is helping that process because it's grouping more similar things together. Given #2722, improving our discoverability in the analysis area may be particularly useful to developers right now.
2019-01-10 21:18:43 -05:00
Paul Melnikow
6c2b040fa6 Better modal (#2554)
- With examples using `pattern`s, allow building the URL from its component parts, including the query string.
- Provide a button to copy the link, with an animation.

To enable this for other badges, convert them to use a `pattern`: #1961.
2019-01-10 21:04:07 -05:00
Paul Melnikow
da12f00d87 Tweak formatting of [bstats] badge (#2724)
This makes it a bit more consistent with the others.
2019-01-10 15:14:38 -05:00
James Cahill
a8629fe8bd Added [bStats] badges (#2591)
* bStats badges

* Remove inline tutorial comments

* Split tests into seperate files

* use shorthand for tester instantiation

* use Joi.number() for validation

* Misc. fixes

* update to use native api
2019-01-10 10:54:43 -06:00
Paul Melnikow
cd0ff105f6 User color should not override error color (#2693)
Fix #1446.
2019-01-09 16:32:28 -05:00
Paul Melnikow
e528c85ed4 Refactor [GithubContributors] and [NpmCollaborators] and change color (#2715)
See examples in https://github.com/badges/shields/pull/2705#issue-243107694
2019-01-09 16:29:57 -05:00
Marcin Mielnicki
372c1978a1 Unwanted title removed (#2721)
Currently HTML code of shields.io contains two `<title>` elements. This PR removes an extra title element. 

Before change:
```bash
> curl https://shields.io -s | egrep "<title.*/title>" -o 
<title class="next-head">Shields.io: Quality metadata badges for open source projects</title>
<title>My page</title>
```

After change:
```bash
> curl http://localhost:8080 -s | egrep "<title.*/title>" -o
<title class="next-head">Shields.io: Quality metadata badges for open source projects</title>
```
2019-01-09 16:21:26 -05:00
Paul Melnikow
674d9877ad Add calebcartwright to core team 💥 (#2718) 2019-01-09 15:59:12 -05:00
Paul Melnikow
0e11194de5 Validate defaultBadgeData (#2711) 2019-01-09 14:50:42 -05:00
Paul Melnikow
ad1d4ce065 Ask for a specific use case in new badge request (#2716) 2019-01-09 13:04:51 -05:00
Paul Melnikow
06c6f13770 Add category nav menu (#2682)
Adapted from @chris48s’ work from #1842.
2019-01-09 08:46:27 -05:00
dependabot[bot]
7e1b1121a4 Bump eslint-plugin-mocha from 5.2.0 to 5.2.1 (#2712)
Bumps [eslint-plugin-mocha](https://github.com/lo1tuma/eslint-plugin-mocha) from 5.2.0 to 5.2.1.
- [Release notes](https://github.com/lo1tuma/eslint-plugin-mocha/releases)
- [Changelog](https://github.com/lo1tuma/eslint-plugin-mocha/blob/master/CHANGELOG.md)
- [Commits](https://github.com/lo1tuma/eslint-plugin-mocha/compare/5.2.0...5.2.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-09 00:47:32 -05:00
Paul Melnikow
d1c5378bf0 Integrate new path-to-regexp with trailing optionals (#2644)
Fix #2497

Ref pillarjs/path-to-regexp#176
2019-01-08 18:50:47 -05:00
Maximilian Brandau
4efe8832cf Update [opencollective] error handling (#2707)
Update tests to fit new behavior of upstream API
Update by-tier service to fit new behavior
2019-01-08 17:33:46 -05:00
Maximilian Brandau
ce7bbba028 Use shields instead of open collective badges (#2708) 2019-01-08 17:04:26 -05:00
Paul Melnikow
945272db22 Rm old list of critical services (#2695)
This list was useful when we had to triage service tests, though happily that day is no longer :)
2019-01-08 15:13:47 -05:00
Pierre-Yves B
a158cf858b [Travis-Build] service rewrite, run [travis-php-version] (#2660)
* Rewrote Travis-Build service and separated tests

* Fixed property shorthand

* Strenghtened schema validation

* Implemented keyword remapping
2019-01-08 19:33:14 +00:00
Paul Melnikow
23ed74e850 Readme: Fix dev setup instructions (#2700) 2019-01-08 14:07:10 -05:00
Jan Keromnes
3ab2862922 Fix a few typos (#2697)
* Fix typos (using 'codespell -w')

* Properly capitalize Git and GitHub in TUTORIAL.md
2019-01-08 12:08:50 -05:00
chris48s
7d1a6dd627 fix [gem] rank badge (#2659)
The ranking endpoints return a value for every day. This is rare, but it looks like sometimes this can be `null` (for example if you call http://bestgems.org/api/v1/gems/rack/daily_ranking.json the rank was `null` on `2013-07-02` ) and if the rank has _ever_ been `null` for a package in the past, the schema will fail validating the response.

This modifies the schema to allow a `null` value and adds a case to handle if the rank is `null` today.

closes #2647
2019-01-08 00:36:40 -05:00
Paul Melnikow
84a6d28250 Add instructions for testing Danger locally (#2691) 2019-01-08 00:16:05 -05:00
Paul Melnikow
db365d6085 Rm unnecessary mkdir in Circle config (#2692)
See discussion in badges/daily-tests#4.
2019-01-07 22:43:09 -05:00
Paul Melnikow
ebfd6cf8ee We don't use Docker in production (#2690)
I found an old note to myself to document this.
2019-01-07 22:00:36 -05:00
Paul Melnikow
1e267f891d Document production hosting (#2661) 2019-01-07 20:55:49 -05:00
Paul Melnikow
dcbe1cf906 Prettier: Ignore a couple generated files which aren’t checked in (#2680) 2019-01-07 20:40:24 -05:00
Paul Melnikow
a018bd8475 Fix frontend start script (#2681)
Without this change none of the badges load.
2019-01-07 20:37:31 -05:00
Paul Melnikow
b82d663a6d Unflake GitHub integration test (#2683)
Hopefully this fixes #2663.
2019-01-07 20:31:26 -05:00
Paul Melnikow
8c7404a571 Run Prettier on the rest of the things (#2662) 2019-01-07 18:33:17 -05:00
Paul Melnikow
ec9de03b28 Debug GitHub integration test (#2677)
Ref #2663
2019-01-07 18:26:36 -05:00
Maximilian Brandau
9faa0088bf Replace open collective with shields rendered badges (#2672)
Closes #2498
2019-01-07 15:02:39 -05:00
Maximilian Brandau
00c193a009 Add 4 open collective badges (#2638)
- open collective backers
- open collective sponsors
- open collective backers and sponsors
- open collective members by tier
2019-01-07 13:50:45 -05:00
dependabot[bot]
8b61dc6fbb Bump danger from 7.0.1 to 7.0.2 (#2667)
Bumps [danger](https://github.com/danger/danger-js) from 7.0.1 to 7.0.2.
- [Release notes](https://github.com/danger/danger-js/releases)
- [Changelog](https://github.com/danger/danger-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/danger/danger-js/compare/7.0.1...7.0.2)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-07 18:34:45 +00:00
dependabot[bot]
12cf218d8e Bump chalk from 2.4.1 to 2.4.2 (#2665)
Bumps [chalk](https://github.com/chalk/chalk) from 2.4.1 to 2.4.2.
- [Release notes](https://github.com/chalk/chalk/releases)
- [Commits](https://github.com/chalk/chalk/compare/v2.4.1...v2.4.2)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-07 18:27:33 +00:00
dependabot[bot]
e33cd9bd7c Bump js-yaml from 3.12.0 to 3.12.1 (#2666)
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 3.12.0 to 3.12.1.
- [Release notes](https://github.com/nodeca/js-yaml/releases)
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/3.12.0...3.12.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-07 12:40:01 -05:00
dependabot[bot]
25ab3f6add Bump eslint-plugin-react from 7.12.2 to 7.12.3 (#2669)
Bumps [eslint-plugin-react](https://github.com/yannickcr/eslint-plugin-react) from 7.12.2 to 7.12.3.
- [Release notes](https://github.com/yannickcr/eslint-plugin-react/releases)
- [Changelog](https://github.com/yannickcr/eslint-plugin-react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/yannickcr/eslint-plugin-react/compare/v7.12.2...v7.12.3)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-07 11:41:32 -05:00
dependabot[bot]
e285d0737d Bump eslint from 5.11.1 to 5.12.0 (#2668)
Bumps [eslint](https://github.com/eslint/eslint) from 5.11.1 to 5.12.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v5.11.1...v5.12.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-07 11:36:30 -05:00
dependabot[bot]
85146db12a Bump eslint-plugin-node from 8.0.0 to 8.0.1 (#2664)
Bumps [eslint-plugin-node](https://github.com/mysticatea/eslint-plugin-node) from 8.0.0 to 8.0.1.
- [Release notes](https://github.com/mysticatea/eslint-plugin-node/releases)
- [Commits](https://github.com/mysticatea/eslint-plugin-node/compare/v8.0.0...v8.0.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-07 11:33:57 -05:00
Caleb Cartwright
ca487ae086 Refactor [SymfonyInsight] to new service model and rename (#2572)
Based on some discussion/feedback here, this PR now contains several changes:

* Renames the `Sensiolabs` badge/service content to `SymfonyInsight` to reflect the rebranding of that product/service
* Refactors the original service to the new service model (using `BaseXmlService`)
* Updates the color scheme of the original/initial badge type (SymfonyInsight Grade) to more closely mirror the colors used by the vendor/service provider
* Adds a new badge type (violation counts/summary) 
* Adds both mocked and live tests (there were none before) for both the grade & violation badges using the new path `symfony/i` as well as a couple tests for the old path `sensiolabs/i` to check for backwards compatibility

Refs #1358
2019-01-07 00:28:45 -05:00
Paul Melnikow
b32f6eab55 Convert some static previews (#2652) 2019-01-06 17:39:27 -05:00
Paul Melnikow
89113eee17 Migrate deprecated staticExample -> staticPreview (#2650) 2019-01-06 17:30:25 -05:00
Paul Melnikow
a614de5fc9 Deprecate [cocoapods] stats badges; split out tests (#2653)
Resolve #2651.
2019-01-06 16:26:38 -05:00
Paul Melnikow
47bb03572b Set redirectUrl for production; rely on NODE_CONFIG_ENV being set earlier (#2656) 2019-01-06 12:56:26 -05:00
Paul Melnikow
bc0be4f619 Fixes for config update (#2655)
Ref #2626 #2654
2019-01-06 12:23:58 -05:00
Paul Melnikow
fa5309400d PaaS, CI, and production-friendly config (#2626)
This implements the configuration mechanism I described in #2621. The heavy lifting is delegated to [node-config](https://github.com/lorenwest/node-config) with a minor assist from [dotenv](https://github.com/motdotla/dotenv).

`private/secret.json` has been replaced with environment variables and/or `config/local.yml`. See `doc/server-secrets.md`.
2019-01-06 10:42:09 -05:00
Paul Melnikow
3ffb3ef5b4 Remove support for exampleUrl (#2640) 2019-01-06 08:31:25 -05:00
chris48s
566b58acba refactor [bower] service (#2646) 2019-01-06 13:25:12 +00:00
chris48s
f7728cdb3c refactor [bintray] service (#2645) 2019-01-06 13:22:30 +00:00
Paul Melnikow
83044ce325 Update more exampleUrls; style tweaks (#2639) 2019-01-06 08:18:19 -05:00
Paul Melnikow
2e1ce1a4ca Fix test:services:trace (#2643) 2019-01-06 05:26:56 -05:00
Caleb Cartwright
85be66bb19 tests: change scrutinizer branch coverage test example (#2641) 2019-01-05 17:39:55 -05:00
Paul Melnikow
c4143b9c23 Convert a bunch of exampleUrls and formats (#2633) 2019-01-05 14:54:34 -05:00
Paul Melnikow
d97a5e4697 Server start time badge [debug] (#2631) 2019-01-04 17:23:30 -05:00
Paul Melnikow
5233a25ddc Remove spurious truthiness checks on serverSecrets (#2634)
`serverSecrets` is always truthy.

Close #2606
2019-01-04 12:49:48 -05:00
dependabot[bot]
9bc2e512b7 Bump nock from 11.0.0-beta.2 to 11.0.0-beta.3 (#2627)
Bumps [nock](https://github.com/nock/nock) from 11.0.0-beta.2 to 11.0.0-beta.3.
- [Release notes](https://github.com/nock/nock/releases)
- [Changelog](https://github.com/nock/nock/blob/beta/CHANGELOG.md)
- [Commits](https://github.com/nock/nock/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-04 12:06:00 -05:00
dependabot[bot]
67f6e2c490 Bump emojic from 1.1.14 to 1.1.15 (#2628)
Bumps [emojic](https://github.com/IonicaBizau/emojic) from 1.1.14 to 1.1.15.
- [Release notes](https://github.com/IonicaBizau/emojic/releases)
- [Commits](https://github.com/IonicaBizau/emojic/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-04 11:49:40 -05:00
Ang YC
f6357da8ee [Date] Relative date badge (#2244)
Close #749
2019-01-04 11:32:38 -05:00
dependabot[bot]
576f30fce5 Bump react from 16.6.3 to 16.7.0 (#2585)
* Bump react from 16.6.3 to 16.7.0

Bumps [react](https://github.com/facebook/react) from 16.6.3 to 16.7.0.
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/compare/v16.6.3...v16.7.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>

* Bump react-dom from 16.6.3 to 16.7.0

Bumps [react-dom](https://github.com/facebook/react) from 16.6.3 to 16.7.0.
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/compare/v16.6.3...v16.7.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-03 21:18:08 +00:00
dependabot[bot]
b93e3ac26f Bump @babel/polyfill from 7.0.0 to 7.2.5 (#2587)
Bumps [@babel/polyfill](https://github.com/babel/babel) from 7.0.0 to 7.2.5.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.0.0...v7.2.5)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-03 20:59:07 +00:00
dependabot[bot]
dfe2b1cd0a Bump next from 6.1.2 to 7.0.2 (#2508)
Bumps [next](https://github.com/zeit/next.js) from 6.1.2 to 7.0.2.
- [Release notes](https://github.com/zeit/next.js/releases)
- [Commits](https://github.com/zeit/next.js/compare/6.1.2...7.0.2)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-03 09:52:12 -05:00
dependabot[bot]
191f75b634 Bump eslint-plugin-react from 7.12.1 to 7.12.2 (#2624)
Bumps [eslint-plugin-react](https://github.com/yannickcr/eslint-plugin-react) from 7.12.1 to 7.12.2.
- [Release notes](https://github.com/yannickcr/eslint-plugin-react/releases)
- [Changelog](https://github.com/yannickcr/eslint-plugin-react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/yannickcr/eslint-plugin-react/compare/v7.12.1...v7.12.2)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-03 09:06:46 -05:00
dependabot[bot]
1502d1aa5b Bump rimraf from 2.6.2 to 2.6.3 (#2623)
Bumps [rimraf](https://github.com/isaacs/rimraf) from 2.6.2 to 2.6.3.
- [Release notes](https://github.com/isaacs/rimraf/releases)
- [Commits](https://github.com/isaacs/rimraf/compare/v2.6.2...v2.6.3)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-03 01:09:14 -05:00
chris48s
d96d8ae193 Document private/secret.json; affects [bower jira] (#2599)
* don't use a libraries.io token for bower integration

The libraries.io docs claim you need to be authenticated
to make any API request: https://libraries.io/api#authentication

In practice we can call https://libraries.io/api/bower/jquery
just fine with no token and based on chucking a load of
requests at it and examining the `x-ratelimit-remaining`
headers you actually seem to get a better limit with no
authentication.

All of our libraries.io badges in `services/librariesio`
seem to have been running fine with no token for some time.


* change jira auth settings to jira_user, jira_pass

All the other services use servicename_user, servicename_pass

This switches JIRA to use that convention by preference
but supports _username and _password for legacy users.


* add docs for server secrets


* add danger rule for server-secrets.md

this rule prompts users to update server-secrets.md
if 'serverSecrets' is in the diff
2019-01-02 20:49:42 +00:00
Paul Melnikow
5dc25af93c redirectUrl: Update terminology and add a test (#2617) 2019-01-02 13:48:27 -05:00
Paul Melnikow
a9ff282b74 Extend timeout on GitHub integration test (#2618) 2019-01-02 11:24:03 -05:00
Caleb Cartwright
3bbe2482bc Refactor [TeamCity] and add tests (#2601) 2019-01-02 00:19:33 -05:00
Paul Melnikow
a9839845a1 Add some test coverage in frontend/lib (#2615) 2019-01-02 00:12:51 -05:00
Paul Melnikow
7150b37831 Add test of the server entrypoint (#2613)
The server's entrypoint is an important bit of code which is not covered by our tests. This adds a test which should cover it.
2019-01-01 22:58:54 -05:00
Paul Melnikow
f297f68911 Coverage should ignore test helpers (#2614) 2019-01-01 22:49:03 -05:00
dependabot[bot]
84183a3fc9 Bump joi from 14.3.0 to 14.3.1 (#2610)
Bumps [joi](https://github.com/hapijs/joi) from 14.3.0 to 14.3.1.
- [Release notes](https://github.com/hapijs/joi/releases)
- [Changelog](https://github.com/hapijs/joi/blob/master/CHANGELOG.md)
- [Commits](https://github.com/hapijs/joi/compare/v14.3.0...v14.3.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-01 21:54:01 -05:00
dependabot[bot]
e09f5ca034 Bump styled-components from 4.1.2 to 4.1.3 (#2556)
Bumps [styled-components](https://github.com/styled-components/styled-components) from 4.1.2 to 4.1.3.
- [Release notes](https://github.com/styled-components/styled-components/releases)
- [Changelog](https://github.com/styled-components/styled-components/blob/master/CHANGELOG.md)
- [Commits](https://github.com/styled-components/styled-components/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-01 21:40:34 -05:00
dependabot[bot]
860c426a0c Bump eslint-plugin-react from 7.11.1 to 7.12.0 (#2609)
* Bump eslint-plugin-react from 7.11.1 to 7.12.0

Bumps [eslint-plugin-react](https://github.com/yannickcr/eslint-plugin-react) from 7.11.1 to 7.12.0.
- [Release notes](https://github.com/yannickcr/eslint-plugin-react/releases)
- [Changelog](https://github.com/yannickcr/eslint-plugin-react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/yannickcr/eslint-plugin-react/compare/v7.11.1...v7.12.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>

* Fix lint errors

* Better link

* Re-bump package version and remove lint disable
2019-01-01 21:22:09 -05:00
Caleb Cartwright
97cdc5762f Add timeout for server test setup/teardown (#2612) 2019-01-01 21:16:35 -05:00
dependabot[bot]
02151cb700 Bump husky from 1.2.0 to 1.3.1 (#2608)
Bumps [husky](https://github.com/typicode/husky) from 1.2.0 to 1.3.1.
- [Release notes](https://github.com/typicode/husky/releases)
- [Changelog](https://github.com/typicode/husky/blob/master/CHANGELOG.md)
- [Commits](https://github.com/typicode/husky/compare/v1.2.0...v1.3.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-01 15:54:03 +01:00
dependabot[bot]
38ede19e84 Bump danger from 6.1.12 to 7.0.1 (#2600)
Bumps [danger](https://github.com/danger/danger-js) from 6.1.12 to 7.0.1.
- [Release notes](https://github.com/danger/danger-js/releases)
- [Changelog](https://github.com/danger/danger-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/danger/danger-js/compare/6.1.12...7.0.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-30 21:44:02 +00:00
dependabot[bot]
e024020258 Bump simple-icons from 1.9.16 to 1.9.17 (#2596)
Bumps [simple-icons](https://github.com/simple-icons/simple-icons) from 1.9.16 to 1.9.17.
- [Release notes](https://github.com/simple-icons/simple-icons/releases)
- [Commits](https://github.com/simple-icons/simple-icons/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-30 21:36:43 +00:00
Caleb Cartwright
dcfd84923c fix: fix bug in server-config on allowedOrigin (#2607) 2018-12-30 21:26:41 +00:00
James Cahill
4baf16cbed Visual Studio Code gitignore + recommended extensions (#2581)
* Add vscode to gitignore

* Update gitignore and add recommended extensions
2018-12-29 12:06:01 -05:00
Paul Melnikow
ebe6da23d4 Register missing redirects [static] (#2603) 2018-12-28 14:00:07 -05:00
Paul Melnikow
16491d787c Fix [suggest] (#2604) 2018-12-28 13:51:29 -05:00
dependabot[bot]
27da1aa659 Bump eslint from 5.11.0 to 5.11.1 (#2595)
Bumps [eslint](https://github.com/eslint/eslint) from 5.11.0 to 5.11.1.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v5.11.0...v5.11.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-28 10:37:37 -05:00
dependabot[bot]
5548027f12 Bump prom-client from 11.2.0 to 11.2.1 (#2583)
Bumps [prom-client](https://github.com/siimon/prom-client) from 11.2.0 to 11.2.1.
- [Release notes](https://github.com/siimon/prom-client/releases)
- [Changelog](https://github.com/siimon/prom-client/blob/master/CHANGELOG.md)
- [Commits](https://github.com/siimon/prom-client/compare/v11.2.0...v11.2.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-26 17:15:56 -05:00
James Cahill
74faf163b7 Use cross-env for environment variables (#2589)
Fix #2580
2018-12-26 17:01:02 -05:00
Manaswini Das
d87ac49b43 Improves CONTRIBUTING.md (#2594) 2018-12-26 21:25:23 +00:00
chris48s
6c01027c63 improve setup instructions (#2592)
* improve setup instructions

* move node/npm install out to pre-requisites section
2018-12-26 21:22:56 +00:00
Caleb Cartwright
6d1c748453 Fix serverHasBeenUpSinceResourceCached test (#2593)
Fixes #2571 (Really fixed this time 😄) 

I attempted a fix in https://github.com/badges/shields/pull/2590 using fake timers but didn't realize how the timestamps being used in `cache-headers` were being created. This approach uses a dynamically generated `if-modified-since` value that will now be 30 minutes ahead of the server time stamp used in the comparison.
2018-12-25 21:07:31 -05:00
dependabot[bot]
892a54cfd5 Bump eslint from 5.10.0 to 5.11.0 (#2586)
Bumps [eslint](https://github.com/eslint/eslint) from 5.10.0 to 5.11.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v5.10.0...v5.11.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-24 19:30:56 +00:00
dependabot[bot]
c7c82e4fc9 Bump fast-xml-parser from 3.12.10 to 3.12.11 (#2582)
Bumps [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) from 3.12.10 to 3.12.11.
- [Release notes](https://github.com/NaturalIntelligence/fast-xml-parser/releases)
- [Changelog](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md)
- [Commits](https://github.com/NaturalIntelligence/fast-xml-parser/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-24 19:23:54 +00:00
dependabot[bot]
35f9d84701 Bump snap-shot-it from 6.2.7 to 6.2.8 (#2584)
Bumps [snap-shot-it](https://github.com/bahmutov/snap-shot-it) from 6.2.7 to 6.2.8.
- [Release notes](https://github.com/bahmutov/snap-shot-it/releases)
- [Commits](https://github.com/bahmutov/snap-shot-it/compare/v6.2.7...v6.2.8)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-24 19:16:59 +00:00
Caleb Cartwright
09ff426cba tests: add fake timers to cache-headers tests (#2590) 2018-12-24 19:10:11 +00:00
Paul Melnikow
ea0d2fb641 Fix frontend coverage in CI, update dev scripts, adopt npm-run-all (#2569) 2018-12-23 22:06:38 -05:00
Paul Melnikow
57f826962b Use beta release of nock (#2579) 2018-12-23 21:45:15 -05:00
Paul Melnikow
75a0c67562 Update list of prod secrets (#2573) 2018-12-23 11:33:54 -05:00
chris48s
ec3531bbde refactor [shippable] service (#2576) 2018-12-23 16:28:40 +00:00
Paul Melnikow
5c665a70da Overhaul initialization pattern for server + server tests (#2519)
Because `server.js` was long a monolith, there are a bunch of shims in place to facilitate unit testing. A few of the test suites share port 1111 which means if one of them fails to set up, the port won't be freed and other unrelated tests will fail. Some of the tests which trigger server setup include timeouts which were added to give setup code time to run. In one the test suites, we actually modify `process.argv`, which seems completely gross.

This implements a few changes which improve this:

1. Separate the server from the server startup script, splitting out `lib/server.js`.
2. Inject config into the server and validate the config schema.
3. Inject config into the service test runner.
4. Use `portfinder`, a popular utility for grabbing open ports during testing.
5. Switch more of the setup code from callbacks to async-await.

Overall it leaves everything acting more reliably and looking rather cleaner, if in a few places more verbose.

It also fixes the root cause of #1455, a `setTimeout` in `rate-limit`. Off and on during development of this changeset, Mocha would decide not to exit, and that turned out to be the culprit.

Fix #1455
2018-12-23 11:24:22 -05:00
chris48s
7dac325196 refactor [CPAN] service (#2575) 2018-12-23 15:20:50 +00:00
Paul Melnikow
4a976b52ea Fix import issue with [dynamic] badge (#2578)
Ref https://github.com/badges/shields/pull/2519#issuecomment-449511750
2018-12-23 10:13:04 -05:00
Paul Melnikow
227aaa04d8 Update maintainer list 🎉🎉🎉 (#2561)
Please join me in welcoming @calebcartwright to the maintainer team!

Caleb has been doing an incredible job rewriting services, among other things, and we're glad to have him on board!
2018-12-22 20:38:08 -05:00
dependabot[bot]
ad22dfccc5 Bump @babel/core from 7.1.6 to 7.2.2 (#2543)
* Bump @babel/core from 7.1.6 to 7.2.2

Bumps [@babel/core](https://github.com/babel/babel) from 7.1.6 to 7.2.2.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.1.6...v7.2.2)

Signed-off-by: dependabot[bot] <support@dependabot.com>

* upgrade the babel plugins
2018-12-21 20:49:05 +00:00
dependabot[bot]
65731f2255 Bump simple-icons from 1.9.15 to 1.9.16 (#2559)
Bumps [simple-icons](https://github.com/simple-icons/simple-icons) from 1.9.15 to 1.9.16.
- [Release notes](https://github.com/simple-icons/simple-icons/releases)
- [Commits](https://github.com/simple-icons/simple-icons/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-21 19:37:02 +00:00
dependabot[bot]
a0009aa8b7 Bump react-modal from 3.7.1 to 3.8.1 (#2558)
Bumps [react-modal](https://github.com/reactjs/react-modal) from 3.7.1 to 3.8.1.
- [Release notes](https://github.com/reactjs/react-modal/releases)
- [Changelog](https://github.com/reactjs/react-modal/blob/master/CHANGELOG.md)
- [Commits](https://github.com/reactjs/react-modal/compare/v3.7.1...v3.8.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-21 19:30:02 +00:00
Brendan Abolivier
da5ca7454a Improve [Matrix] badge generation (#2527)
Fixes #2524 

This PR addresses the issues expressed in #2524, in that it:

* checks if a server has advertised a FQDN it can be reached at and if that FQDN hosts Matrix's client APIs
* uses room aliases instead of room IDs, in order to avoid a badge being impossible to generate if the server that created the room leaves it

This includes a breaking change to the badge endpoint.
2018-12-20 17:00:49 -05:00
Caleb Cartwright
2fe61d2c5c Add [Snyk] badges (#2566)
Adds vulnerability badges from Snyk.io, closes #1642 

- [X] Vulnerability badge for GitHub repos
- [x] Vulnerability badge for npm package
2018-12-20 16:28:54 -05:00
Caleb Cartwright
fc41b576f3 Update [Jira] tests to include color validation (#2565)
Augmenting the tests for Jira that were added in #2541 to also validate color scheme
2018-12-20 15:55:15 -05:00
Paul Melnikow
872aede5be Add readme badges to gamify refactoring some more (#2562)
Ref https://github.com/badges/shields/issues/1358#issuecomment-448743020
2018-12-20 15:20:38 -05:00
Paul Melnikow
ebe4a12acc Convert lodash.uniq to native and remove an unused dev dep (#2564) 2018-12-20 15:15:56 -05:00
Paul Melnikow
483aa5a008 Fix frontend coverage and tweak ignores (#2563)
Since we use Babel for the frontend but not the server, I split the coverage config into two separate files, one for the frontend and the other for the server.

Refs:

- https://github.com/istanbuljs/nyc#nyc
- https://github.com/istanbuljs/babel-plugin-istanbul#mocha-on-nodejs-through-nyc

Close #2552
2018-12-19 17:46:09 -05:00
Paul Melnikow
4e5e3c8aee Split up [github] testers (#2560)
- Update github contributors badge for `create-service-tester`.
2018-12-19 17:20:15 -05:00
Paul Melnikow
382af10506 Rewrite [GithubManifest] and [GithubPackageJson] badges (#2470)
Pave the way for #2259 and rewrite #1721 along the way.

Ref: #2320
2018-12-19 16:33:20 -05:00
Caleb Cartwright
6d3798f26f Migrates [Nexus] service to new service model (#2520)
Ports the Nexus service to the new service model. Some related/relevant conversation in #2347 (and closes #2347). Also adds support for authentication which resolves #1699.
2018-12-19 15:45:22 -05:00
dependabot[bot]
63f8b256a7 Bump got from 9.4.0 to 9.5.0 (#2557)
Bumps [got](https://github.com/sindresorhus/got) from 9.4.0 to 9.5.0.
- [Release notes](https://github.com/sindresorhus/got/releases)
- [Commits](https://github.com/sindresorhus/got/compare/v9.4.0...v9.5.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-19 10:56:37 -05:00
Paul Melnikow
5c7d07f5be Rework styling using styled-components (#2517)
The CSS in the project is relatively difficult to change. While it is very DRY, it relies heavily on inheritance. It's difficult to make changes in the markup modal without it also affecting styles elsewhere.
 
[styled-components](https://www.styled-components.com/) is one of the leading CSS-in-JS libraries. By reducing dependency on global state and CSS inheritance, styles become explicit and are easier to inspect and change. It's also convenient that styles can be embedded with the components they modify.

At runtime, the library creates CSS classes, so it's pretty efficient.

We were using a little bit of [styled-jsx](https://github.com/zeit/styled-jsx) before, which ships with Next.js, though styled-components is more widely used and I've had good experiences with it all around.

In a few cases I've duplicated styles where it feels more natural to do that: for example, `text-align: center` is duplicated in `Main` and `MarkupModal`.

Much of this is a refactor, though there are a few visual changes, particularly in the markup modal and the style examples.
2018-12-18 16:44:47 -05:00
Caleb Cartwright
a1150efd25 Migrate [Coverity] to new service model (#2550)
* feat: migrate coverity to new service model
* chore: add coverity ondemand to deprecated services list
2018-12-18 21:19:50 +00:00
Paul Melnikow
b36a9040f3 Add warning banners to legacy services (#2546) 2018-12-18 20:52:17 +00:00
Caleb Cartwright
7d30d86f2b Migrate [Jira] services to new service model (#2541)
Migrates the Jira badge services to the new service model, and also adds tests for those badges. 

I did make one minor changes to the badge labels/messages when the issue or sprint cannot be found. For example: 

With the LegacyService implementation, when an issue was not found the badge would display as 'issue key | inaccessible' such as `KAFKA-2869 | inaccessible` but this changes that behavior to `jira | issue not found`. I personally find this to be a bit more informative of a message, but want to call it out as I know how important backwards compatibility is. However, at first glance I'm also not sure how we'd replicate the old behavior of using the issue key (provided by user as a param) as the badge label when an issue is not found because the API response has a status code of 404 and a different schema than what Joi is expecting/validating. 

Similarly for the sprints, the old format for a sprint not found was `completion | inaccessible` it's now `jira | sprint not found`
2018-12-17 23:30:33 -05:00
Dean Davidson
b0fbe5f76f Refactor [AzureDevOpsCoverage AzureDevOpsTests] to only report on completed builds; test all [azuredevops] (#2549)
This is in response to [this conversation](https://github.com/badges/shields/issues/2237#issuecomment-446812796). The change turned out being even easier than I had anticipated because the [API supports a buildStatus filter](https://docs.microsoft.com/en-us/rest/api/azure/devops/build/builds/list?view=azure-devops-rest-5.0#buildstatus). I did quite a bit of local testing to make sure this is solid. I also ran tests and checked coverage.
2018-12-17 23:12:52 -05:00
Caleb Cartwright
6c9fc0de79 Migrate [Codetally] to new service model (#2548) 2018-12-17 23:07:21 -05:00
dependabot[bot]
b4b29ab0f7 Bump moment from 2.22.2 to 2.23.0 (#2531)
Bumps [moment](https://github.com/moment/moment) from 2.22.2 to 2.23.0.
- [Release notes](https://github.com/moment/moment/releases)
- [Changelog](https://github.com/moment/moment/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/moment/moment/compare/2.22.2...2.23.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-17 12:49:15 -05:00
Caleb Cartwright
09e8c587d9 feat: migrate sourcegraph to new service model and fix tests (#2535) 2018-12-16 22:05:02 +00:00
chris48s
bca7416be7 couple of fixes to service test docs (#2542) 2018-12-16 20:50:07 +00:00
Paul Melnikow
2bf29f97b8 Set up CircleCI test summary [npmcollaborators] (#2526)
See https://circleci.com/docs/2.0/collect-test-data/

This provides a list of failed tests in the Circle UI and a summary of which tests have failed. It should make interpreting test results easier
2018-12-16 15:42:28 -05:00
chris48s
b5ac5d6044 [dynamicyaml f-droid] add yaml base service class (#2540) 2018-12-16 20:29:20 +00:00
chris48s
df22adfba7 remove logos for deprecated services (#2539)
* remove logos for deprecated services
* remove references to gratipay logo in tests
2018-12-16 19:33:27 +00:00
chris48s
e5cacbc73f refactor [CRAN] service (#2538) 2018-12-16 19:25:27 +00:00
Caleb Cartwright
dea35025b1 Deprecate [nsp] service (#2529)
deprecated nsp service and added doc for deprecation
2018-12-16 19:21:22 +00:00
Paul Melnikow
5e50b7bcc4 Fix [npm] badges when a dependency points to a URL (#2525)
Fix #2523
2018-12-13 14:07:33 -05:00
Paul Melnikow
ec35e8de06 Remove unused wait-promise dep (#2521) 2018-12-13 14:05:10 -05:00
dependabot[bot]
73be33226f Bump sinon from 7.2.0 to 7.2.2 (#2522)
Bumps [sinon](https://github.com/sinonjs/sinon) from 7.2.0 to 7.2.2.
- [Release notes](https://github.com/sinonjs/sinon/releases)
- [Changelog](https://github.com/sinonjs/sinon/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sinonjs/sinon/compare/v7.2.0...v7.2.2)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-13 12:37:25 -05:00
Paul Melnikow
b8461aa921 Rewrite [DynamicXml] and [DynamicYaml] badges (#2487)
- A little related cleanup in `server.js`: remove a couple import renames.
2018-12-12 16:52:47 -05:00
Paul Melnikow
a3a52524fc Add [npm] badges for collaborator count and dependency version (#2461)
This adds a badge for collaborator count. When evaluating a library, it can be useful to know that there's not a single-contributor bottleneck for publishing. Having more than one collaborator is a sign of library maturity.

It adds another badge for dependency version of published dependencies, which solves a similar problem as the node-version badge. I will find this useful for making sure dependencies are up to date in a library.
2018-12-12 15:02:37 -05:00
Paul Melnikow
38ca6fc396 Add quality category and sort a couple other badges [scrutinizer] (#2483)
Ref #1905
2018-12-12 14:59:46 -05:00
dependabot[bot]
f6da548dc3 Bump danger from 6.1.11 to 6.1.12 (#2513)
Bumps [danger](https://github.com/danger/danger-js) from 6.1.11 to 6.1.12.
- [Release notes](https://github.com/danger/danger-js/releases)
- [Changelog](https://github.com/danger/danger-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/danger/danger-js/compare/6.1.11...6.1.12)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-12 19:24:55 +00:00
Pierre-Yves B
029a14681d Improved [MicroBadger] tests speed (#2512) 2018-12-12 19:19:45 +00:00
Antão Almada
a51111e170 Add Azure DevOps logo (#2463) 2018-12-11 16:42:30 -05:00
dependabot[bot]
46064a5f9c Bump react-modal from 3.6.1 to 3.7.1 (#2507)
Bumps [react-modal](https://github.com/reactjs/react-modal) from 3.6.1 to 3.7.1.
- [Release notes](https://github.com/reactjs/react-modal/releases)
- [Changelog](https://github.com/reactjs/react-modal/blob/master/CHANGELOG.md)
- [Commits](https://github.com/reactjs/react-modal/compare/v3.6.1...v3.7.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-11 16:33:35 -05:00
Paul Melnikow
88c8b0ee3e More example urls and static examples [apm waffle] (#2478) 2018-12-11 16:31:01 -05:00
Caleb Cartwright
d74568b9c9 Minor test updates for jenkins coverage and token-pool (#2509) 2018-12-11 21:10:21 +00:00
dependabot[bot]
bd930faf24 Bump sinon from 7.1.1 to 7.2.0 (#2506)
Bumps [sinon](https://github.com/sinonjs/sinon) from 7.1.1 to 7.2.0.
- [Release notes](https://github.com/sinonjs/sinon/releases)
- [Changelog](https://github.com/sinonjs/sinon/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sinonjs/sinon/compare/v7.1.1...v7.2.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-11 15:58:01 -05:00
dependabot[bot]
965816f363 Bump got from 9.3.2 to 9.4.0 (#2503)
Bumps [got](https://github.com/sindresorhus/got) from 9.3.2 to 9.4.0.
- [Release notes](https://github.com/sindresorhus/got/releases)
- [Commits](https://github.com/sindresorhus/got/compare/v9.3.2...v9.4.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-11 15:55:43 -05:00
dependabot[bot]
47d56de160 Bump enzyme-adapter-react-16 from 1.7.0 to 1.7.1 (#2504)
Bumps [enzyme-adapter-react-16](https://github.com/airbnb/enzyme) from 1.7.0 to 1.7.1.
- [Release notes](https://github.com/airbnb/enzyme/releases)
- [Changelog](https://github.com/airbnb/enzyme/blob/master/CHANGELOG.md)
- [Commits](https://github.com/airbnb/enzyme/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-11 15:52:15 -05:00
Caleb Cartwright
43faea4561 Add new service for CII Best Practices badges [CIIBestPractices] (#2477) 2018-12-11 19:20:51 +00:00
dependabot[bot]
40ddc26f9b Bump enzyme from 3.7.0 to 3.8.0 (#2505)
Bumps [enzyme](https://github.com/airbnb/enzyme) from 3.7.0 to 3.8.0.
- [Release notes](https://github.com/airbnb/enzyme/releases)
- [Changelog](https://github.com/airbnb/enzyme/blob/master/CHANGELOG.md)
- [Commits](https://github.com/airbnb/enzyme/compare/enzyme@3.7.0...enzyme@3.8.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-11 10:38:43 -05:00
Paul Melnikow
a677c5bbef Add some basic frontend tests (#2490)
The frontend has a few tests in `lib/` but not all of that is covered. The components are not covered at all. It's difficult to make changes to the frontend because you have to manually test that things haven't broken.

This PR uses [Enzyme](https://airbnb.io/enzyme/) to add some [shallow-rendering tests](https://github.com/airbnb/enzyme/blob/master/docs/api/shallow.md), which are essentially unit tests of the components.

This should pave the way for functional tests of the more complex components.
2018-12-10 17:20:01 -05:00
chris48s
0a98bd3121 refactor [dependabot] semver stability service (#2494) 2018-12-10 21:24:18 +00:00
chris48s
9189438a91 refactor [bountysource] service (#2492) 2018-12-10 21:21:39 +00:00
chris48s
b74fe4ed6f refactor [redmine] plugin rating services (#2491) 2018-12-10 20:02:38 +00:00
chris48s
66623644c3 make 'donate' call to action clearer (#2493) 2018-12-10 20:00:16 +00:00
dependabot[bot]
11e9e75e45 Bump danger from 6.1.9 to 6.1.11 (#2501)
Bumps [danger](https://github.com/danger/danger-js) from 6.1.9 to 6.1.11.
- [Release notes](https://github.com/danger/danger-js/releases)
- [Changelog](https://github.com/danger/danger-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/danger/danger-js/compare/6.1.9...6.1.11)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-10 18:55:12 +00:00
Pierre-Yves B
c89396088d [Wheelmap] service rewrite and tests (#2486) 2018-12-10 18:44:47 +00:00
Paul Melnikow
1649a42a4a Fix whitespace in Codetally test (#2488)
This was caused by #2475 and fixes the mocked test. It's not related to #2480 which is causing the other one to fail.
2018-12-09 16:41:21 -05:00
dependabot[bot]
b08a941490 Bump eslint from 5.9.0 to 5.10.0 (#2484)
Bumps [eslint](https://github.com/eslint/eslint) from 5.9.0 to 5.10.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v5.9.0...v5.10.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-08 17:33:46 -05:00
dependabot[bot]
0e02f8d05e Bump nock from 10.0.3 to 10.0.4 (#2485)
Bumps [nock](https://github.com/nock/nock) from 10.0.3 to 10.0.4.
- [Release notes](https://github.com/nock/nock/releases)
- [Changelog](https://github.com/nock/nock/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nock/nock/compare/v10.0.3...v10.0.4)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-08 21:55:28 +00:00
dependabot[bot]
d0bbd1977f Bump icedfrisby-nock from 1.0.0 to 1.1.0 (#2482)
Bumps [icedfrisby-nock](https://github.com/paulmelnikow/icedfrisby-nock) from 1.0.0 to 1.1.0.
- [Release notes](https://github.com/paulmelnikow/icedfrisby-nock/releases)
- [Changelog](https://github.com/paulmelnikow/icedfrisby-nock/blob/master/CHANGELOG.md)
- [Commits](https://github.com/paulmelnikow/icedfrisby-nock/compare/1.0.0...1.1.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-08 21:32:27 +00:00
Paul Melnikow
58b276539a Refactor frontend main page and badge-example code (#2441)
- The goal of this PR is:
    - Consume the new service-definition format. (#2397)
    - Make the frontend more readable.
- Behavior changes:
    - I changed the **Image** field in the markup modal to show only the path.
    - I added another click-to-select field below that shows the complete URL.
    - This made it easier to suppress the live badge preview while it contains placeholders like `:user` or `:gem`, a minor tweak discussed at https://github.com/badges/shields/issues/2427#issuecomment-442972100.
    - The search box now searches all categories, regardless of the current page. (This is an improvement, I would say.)
- I did not deliberately address performance, though I ripped out a bunch of anonymous functions and avoided re-filtering all the examples by category on every render, which I expect will not hurt. I haven't really tested this on a mobile connection and it'd be worth doing that.
- It would be great to have some tests of the components, though getting started with that seemed like a big project and I did not want to make this any larger than it already is.

It's a medium-sized refactor:

1. Replace `BadgeExamples`, `Category` and `Badge` component with a completely rewritten `BadgeExamples` component which renders a table of badges, and `CategoryHeading` and `CategoryHeadings` components.
2. Refactor `ExamplesPage` and `SearchResults` components into a new `Main` component.
3. Rewrite the data flow for `MarkupModal`. Rather than rely on unmounting and remounting the component to copy the badge URL into state, employ the `getDerivedStateFromProps` lifecycle method.
4. Remove `prepareExamples` and `all-badge-examples`.
5. Rewrite the `$suggest` schema to harmonize with the service definition format. It's not backward-compatible which means at deploy time there probably will be 10–20 minutes of downtime on that feature, between the first server deploy and the final gh-pages deploy.  🤷‍♂️ (We could leave the old version in place if it seems worth it.)
6. Added two new functions in `make-badge-url` with tests. I removed _most_ of the uses of the old functions, but there are some in parts of the frontend I didn't touch like the static and dynamic badge generators, and again I didn't want to make this any larger than it already is.
7. Fix a couple bugs in the service-definition export.
2018-12-08 15:26:13 -05:00
Paul Melnikow
8a8311d931 Unify and minimize tester boilerplate (#2472)
I started using this one-line boilerplate a while back and it seems to tidy things up a bit.
2018-12-08 13:15:24 -05:00
Paul Melnikow
3f9ef53899 Prevent bad letter spacing when whitespace surrounds badge text (#2475)
This is a little fix I’ve been meaning to make for a while. Normally it manifests in the codetally badge, but that badge isn’t working right now.

Here’s a static example, where the right text is wrapped in spaces:

https://img.shields.io/badge/foo-%20bar%20-blue.svg

The spaces get included in width computation, though I suppose ignored when the svg renders, resulting in bad letter spacing.

With this fix, it renders the same as

https://img.shields.io/badge/foo-bar-blue.svg
2018-12-08 13:12:02 -05:00
chris48s
2a545b9853 fix swagger example (#2476) 2018-12-07 20:55:17 +00:00
Paul Melnikow
b26ebeb6b2 Modernize chrome web store examples; PR check state -> build (#2474)
`/users` and `/d` are the same so I dropped `/d` and updated `/users`.
2018-12-07 15:39:06 -05:00
Caleb Cartwright
88ca8ca3b5 tests: added some base class override tests (#2471) 2018-12-07 20:03:10 +00:00
Camilo QS
5b5ec38337 Improve [F-droid] support to .yml metadata format (#2377)
closes: #2083
2018-12-07 00:45:19 -05:00
dependabot[bot]
d0c9da03c8 Bump simple-icons from 1.9.14 to 1.9.15 (#2464)
Bumps [simple-icons](https://github.com/simple-icons/simple-icons) from 1.9.14 to 1.9.15.
- [Release notes](https://github.com/simple-icons/simple-icons/releases)
- [Commits](https://github.com/simple-icons/simple-icons/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-06 22:16:19 +00:00
dependabot[bot]
ac330af883 Bump danger from 6.1.8 to 6.1.9 (#2460)
Bumps [danger](https://github.com/danger/danger-js) from 6.1.8 to 6.1.9.
- [Release notes](https://github.com/danger/danger-js/releases)
- [Changelog](https://github.com/danger/danger-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/danger/danger-js/compare/6.1.8...6.1.9)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-06 22:11:20 +00:00
Caleb Cartwright
a5bbe9a8fa Fix Jenkins Cobertura badge and tests (#2468) 2018-12-06 22:07:27 +00:00
Pierre-Yves B
e9b19416e2 Updated Danger server guideline (#2467) 2018-12-06 22:04:15 +00:00
Paul Melnikow
6a737b7b38 Rewrite the DynamicJson badge (#2399)
This starts the rewrite of the dynamic badges. I've pulled into BaseService an initial version of the query param validation from #2325.

I've extended from BaseJsonService to avoid duplicating the deserialization logic, though it means there is a bit of duplicated code among the three dynamic services. The way to unravel this would be to move the logic from `_requestJson` and friends from the base classes into functions so DynamicJson can inherit from BaseDynamic. Would that be worth it?

This introduces a regression of #1446 for this badge.

Close #2345
2018-12-06 16:45:40 -05:00
Caleb Cartwright
b2d5d3ecca Add Leanpub Book Summary Badges [LeanpubBookSummary] (#2458)
* feat: adds LeanPub book summary badges
2018-12-06 21:19:41 +00:00
chris48s
8070f0bef9 add tests for rust [crates] and refactor (#2462)
* add tests for rust [crates] and refactor
2018-12-06 20:24:46 +00:00
M C
9e95020b18 Add [Matrix] Badge (#2417)
* Added matrix badge

* decreased the size of the matrix logo by more than 50%

* returning the size in fetch() instead of an object

* found another way to register a throwaway account (guest account). this one actually works on matrix.org, but I kept the old way as a backup method. also changed the POST from /members to /state because guest accounts didn't work with /members

* updated logo to a recolored version of the official logo

* Removed unnecessary comments.
Added documentation on how to create the badge URL.
Added a test that hits a real room to test for API compliance.
URLs are now obtained from getter functions.
Added JSON schema for the /state API request.
Improved state response filter.
Replaced example URL room ID to a dedicated testing room.
Made some error messages more helpful.

* correctly implemented requested changes

* changed color hex codes to constants
2018-12-06 19:25:59 +00:00
Tyler James Leonhardt
499ea363e0 Add PowerShell Gallery platform support (#2465)
Now that we have [PowerShell Core](https://github.com/powershell/powershell) the cross-plat version of PowerShell... it'd be really cool to have a badge that shows the OS's that your module works on.

On the PowerShell Gallery, users can do this by using the tags `Windows` `MacOS` `Linux`. In this PR, I use the PowerShell Gallery API to grab the tags from that package and display `windows` `macos` `linux` if they exist.

The result is:
![](https://i.imgur.com/auXUkJJ.png)

which aligns with Conda and Cocoapods
2018-12-06 13:23:40 -05:00
Paul Melnikow
daa47f88a6 Fix doc: trailing, not leading (#2459) 2018-12-05 16:42:02 -05:00
Paul Melnikow
477d357286 Sort some badges; add an Activity category (#2448) 2018-12-05 14:17:37 -05:00
Mehmet Seçkin
54569e9668 [AzureDevOpsTests] Refactor unit tests to improve stability (#2454)
* Correct regex generation logic

* Refactor variable name

* Mock Azure DevOps test result summary API

* Add live tests

Updated mocked tests to use expected values for assertion. Added live
tests to test the API. Added `no tests` as an acceptable result for live
tests.

* Declare common nock setup functions to avoid repetition
2018-12-05 11:04:15 -05:00
Paul Melnikow
16c798a65c Fix [travis] php-v tests (#2457)
See failures: https://circleci.com/gh/badges/shields/26998

It looks like the bug is in the original regex: #1372.
2018-12-04 19:37:18 -05:00
chris48s
37d27a8e6a couples of fixes to docs on porting legacy services (#2456)
- use the right issue no and link to it
- fix the trace command example
2018-12-04 22:17:42 +00:00
Paul Melnikow
a35e877391 Modernize some examples teamcity azuredevops travis [uptimerobot vaadin vscode-marketplace] (#2444)
Ref #1961
2018-12-04 16:44:30 -05:00
Paul Melnikow
986d215c18 Modernize some more examples (#2447)
Ref #1961
2018-12-04 16:23:13 -05:00
chris48s
bca9df2560 don't run service tests on master (#2392) 2018-12-04 19:43:17 +00:00
dependabot[bot]
7c0df62706 Bump nock from 10.0.2 to 10.0.3 (#2450)
Bumps [nock](https://github.com/nock/nock) from 10.0.2 to 10.0.3.
- [Release notes](https://github.com/nock/nock/releases)
- [Changelog](https://github.com/nock/nock/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nock/nock/compare/v10.0.2...v10.0.3)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-04 19:40:54 +00:00
Monica Bui
ec07f23942 Add [StackExchange] monthly questions badge service (#2432)
- Badge shows number of questions for a given library for the previous month (not current month because its in progress)
- Service works for not just the StackOverflow site but for other StackExchange sites also

Close #2378
2018-12-03 20:12:44 -05:00
Paul Melnikow
99e846d2ab Link together some of the documentation (#2446) 2018-12-03 18:05:34 -05:00
Paul Melnikow
809ecf73b9 Examples: Drop deprecated aliases query, urlPattern (#2443) 2018-12-03 16:30:12 -05:00
dependabot[bot]
4f83015732 Bump fast-xml-parser from 3.12.9 to 3.12.10 (#2442)
Bumps [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) from 3.12.9 to 3.12.10.
- [Release notes](https://github.com/NaturalIntelligence/fast-xml-parser/releases)
- [Changelog](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md)
- [Commits](https://github.com/NaturalIntelligence/fast-xml-parser/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-03 21:01:04 +00:00
Paul Melnikow
07d8572ffe Add static examples for [Node] (#2409)
Ref #1961
2018-12-03 15:55:26 -05:00
Paul Melnikow
919eed6c0f Remove longCache from static examples (#2440)
- `longCache` should not be appearing in the displayed URLs for the usage examples.
- `maxAge` is ignored for static badges.
2018-12-03 15:41:44 -05:00
Mehmet Seçkin
e8c411b6f9 Add Azure DevOps tests service (#2412)
Added a test results badge service for an Azure Pipelines build using the ResultSummaryByBuild endpoint. Added basic unit tests for the service.

Close #2411
2018-12-03 08:58:37 -05:00
Paul Melnikow
e3ad57d8fe Add tips for rewriting legacy services (#2429) 2018-12-03 00:27:12 -05:00
Pierre-Yves B
0a6afb4478 Added tests for Sourcegraph service (#2439) 2018-12-02 17:41:01 +00:00
Paul Melnikow
59fdd8a5b0 TokenPool: Add debug logging helper + return correct error (#2400)
Slice another sliver from #1205.
2018-12-02 11:28:21 -05:00
Tair Assimov
88294563cc Deprecate dockbit service - discontinued (#2410)
Ref: #2344
2018-12-02 11:26:10 -05:00
Paul Melnikow
2045489019 Service definition export format (#2397)
Three main goals:

1. In the front end:
      a. Show form fields and automatically assemble badge URLs (#701)
      c. Group together examples for the same service
      b. Show deprecated services
2. Make it easy to changing the schema of `examples`, thanks to 100% validation. One challenge with frameworks is that when there are typos things fail silently which is pretty unfriendly to developers. The validation should really help with that. (This caught one bug in AUR, though I fixed it in #2405 which landed first.)
3. Produce a service definition export for external tool builders. (#776)
4. Build toward harmony between the front-end data structure and the `examples` key in the service classes. I aliased `staticPreview` to `staticExample` which starts this process.

The old format:

- Lacked a consistent machine-readable representation of the fields.
- Flattened multiple examples for the same service were flattened.
- Excluded deprecated services.

The new format improves a few things, too:

- It cleans up the naming. Since this file evolved over time, the names were a bit muddled (i.e. what was an example vs a preview).
- It duplicated information (like `.svg`). (I can imagine dropping the `.svg` from our badge URLs someday, which would make the URLs easier to read and maintain.)
- For a human reading the YAML file, providing the static example as a deconstructed object is more readable.

Here are a couple snippets:

```yml
  - category: build
    name: AppVeyorCi
    isDeprecated: false
    route:
      format: '([^/]+/[^/]+)(?:/(.+))?'
      queryParams: []
    examples:
      - title: AppVeyor
        example: {path: /appveyor/ci/gruntjs/grunt, queryParams: {}}
        preview: {label: build, message: passing, color: brightgreen}
        keywords: []
      - title: AppVeyor branch
        example: {path: /appveyor/ci/gruntjs/grunt/master, queryParams: {}}
        preview: {label: build, message: passing, color: brightgreen}
        keywords: []
  - category: downloads
    name: AmoDownloads
    isDeprecated: false
    examples:
      - title: Mozilla Add-on
        example: {path: /amo/d/dustman, queryParams: {}}
        preview: {path: /amo/d/dustman, queryParams: {}}
        keywords: [amo, firefox]
```
2018-12-02 11:21:30 -05:00
Pierre-Yves B
658086bc46 Tests for [Pub] service (#2436) 2018-12-02 10:08:21 +00:00
Paul Melnikow
74aef34b77 Modernize [AzureDevops] examples (#2406) 2018-12-01 18:01:19 -05:00
chris48s
e20c7c8b14 show dynamic badge examples with a base (#2438)
this makes them a bit nicer to copy & paste
2018-12-01 21:55:18 +00:00
Paul Melnikow
2ec2c00787 Fix [LibrariesioDependencies] for project names containing dots (#2434)
Close #2424
2018-12-01 16:05:54 -05:00
Paul Melnikow
0aee712738 Fix crash in legacy service (#2437)
Bug in #2360
2018-12-01 15:10:32 -05:00
Paul Melnikow
54a36e9474 Refactor cache-header handling and config, create NonMemoryCachingBaseService, rewrite [flip] (#2360)
There's a lot going on in this PR, though it's all interdependent, so the only way I can see to break it up into smaller pieces would be serially.

1. I completely refactored the functions for managing cache headers. These have been added to `services/cache-headers.js`, and in some ways set the stage for the rest of this PR.

    - There are ample higher-level test of the functionality via `request-handler`. Refactoring these tests was deferred. Cache headers were previously dealt with in three places:
        - `request-handler.js`, for the dynamic badges. This function now calls `setCacheHeaders`.
        - `base-static.js`, for the static badges. This method now calls the wordy `serverHasBeenUpSinceResourceCached` and `setCacheHeadersForStaticResource`.
        - The bitFlip badge in `server.js`. 👈 This is what set all this in motion. This badge has been refactored to a new-style service based on a new `NoncachingBaseService` which does not use the Shields in-memory cache that the dynamic badges user.
    - I'm open to clearer names for `NoncachingBaseService`, which is kind of terrible. Absent alternatives, I wrote a short essay of clarification in the docstring. 😝 

2. In the process of writing `NoncachingBaseService`, I discovered it takes several lines of code to instantiate and invoke a service. These would be duplicated in three or four places in production code, and in lots and lots of tests. I kept the line that goes from regex to namedParams (for reasons) and moved the rest into a static method called `invoke()`, which instantiates and invokes the service. This _replaced_ the instance method `invokeHandler`.
    - I gently reworked the unit tests to use `invoke` instead of `invokeHandler`– generally for the better.
    - I made a small change to `BaseStatic`. Now it invokes `handle()` async as the dynamic badges do. This way it could use `BaseService.invoke()`.

3. There was logic in `request-handler` for processing environment variables, validating them, and setting defaults. This could have been lifted whole-hog to `services/cache-headers.js`, though I didn't do that. Instead I moved it to `server-config.js`. Ideally `server-config` is the only module that should access `process.env`. This puts the defaults and config validation in one place, decouples the config schema from the entire rest of the application, and significantly simplifies our ability to test different configs, particularly on small units of code. (We were doing this well enough before in `request-handler.spec`, though it required mutating the environment, which was kludgy.) Some of the `request-handler` tests could be rewritten at a higher level, with lower-level data-driven tests directly against `cache-headers`.
2018-12-01 13:57:34 -05:00
Paul Melnikow
17e57b4155 Add static examples to a few legacy services [travis david coveralls amo] (#2407)
It seems useful to accelerate #1961 even as the badge rewrites are still underway. This introduces a small amount of technical debt by hard-coding the static example, though continuing this work could allow us to eliminate the old ways of specifying examples. It seems like a decent tradeoff.
2018-12-01 13:52:49 -05:00
dependabot[bot]
18b95cba5a Bump snap-shot-it from 6.2.5 to 6.2.7 (#2421)
Bumps [snap-shot-it](https://github.com/bahmutov/snap-shot-it) from 6.2.5 to 6.2.7.
- [Release notes](https://github.com/bahmutov/snap-shot-it/releases)
- [Commits](https://github.com/bahmutov/snap-shot-it/compare/v6.2.5...v6.2.7)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-01 14:50:09 +00:00
dependabot[bot]
41b05b3320 Bump prettier from 1.15.2 to 1.15.3 (#2433)
Bumps [prettier](https://github.com/prettier/prettier) from 1.15.2 to 1.15.3.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/master/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/1.15.2...1.15.3)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-01 14:40:30 +00:00
anatoly techtonik
07063fd1be TUTORIAL.md: Service handles requests to external APIs (#2422) 2018-11-29 20:08:20 -05:00
Monica Bui
3b3dd9fb1b Fix URL pattern for [StackExchange] Questions and Reputation per PR #2418 (#2430)
* Fix URL pattern for StackExchange Questions and Reputation per #2418

Url patterns have been changed back to their older legacy format.
Tests now run properly with this URL in addition to the examples
showing up on local.

* Make changes per review comments. Also change "q" to "t" parameter to match legacy url for questions
2018-11-29 19:07:31 -05:00
Paul Melnikow
bff4f83818 Rewrite [ElmPackage] (#2403)
Ref #1358
2018-11-29 17:38:49 -05:00
dependabot[bot]
24c0b9c7e7 Bump danger from 6.1.5 to 6.1.8 (#2416)
Bumps [danger](https://github.com/danger/danger-js) from 6.1.5 to 6.1.8.
- [Release notes](https://github.com/danger/danger-js/releases)
- [Changelog](https://github.com/danger/danger-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/danger/danger-js/compare/6.1.5...6.1.8)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-11-29 22:29:31 +00:00
dependabot[bot]
4da2fa3aa9 Bump fast-xml-parser from 3.12.8 to 3.12.9 (#2395)
Bumps [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) from 3.12.8 to 3.12.9.
- [Release notes](https://github.com/NaturalIntelligence/fast-xml-parser/releases)
- [Changelog](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md)
- [Commits](https://github.com/NaturalIntelligence/fast-xml-parser/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-11-29 22:26:51 +00:00
Paul Melnikow
8d19f78363 Rewrite + tweak [Beerpay] (#2404)
Ref #1358
2018-11-29 17:24:29 -05:00
anatoly techtonik
1144dba14a TUTORIAL.md: Mention URL mapping upfront and clarify static meaning (#2425)
* TUTORIAL.md: Mention URL mapping upfront and clarify static meaning

* Be more specific that route is URL

* Explain async without reference to prior knowledge

* Use the same example URL to explain the directory layout

* Clean diff

* `route()` + `static`

- The route includes the base URL, so try to clarify that
- Add some more information about `static`
2018-11-29 14:46:42 -05:00
Monica Bui
9713964812 Port [StackExchange] from legacy to BaseJsonService (#2418)
Per part of issue #2378, convert StackExchange service to the newer
BaseJson class. Refactor also to seperate StackExchange reputation and
questions tag info into new StackExchange subservice files
as the legacy class contained both which may be difficult to keep track
of in the future as the service continues to grow.
More tests have been added to make sure other StackExchange sites besides
StackOverflow will still work with the new badge setup.
2018-11-28 21:40:12 -05:00
Paul Melnikow
43d99f96e6 Fix failing service tests for [bintray npmlicense github crates] (#2401)
Closes #2343 #2348 #2402

Ref: #2345 #1359
2018-11-28 18:54:04 -05:00
Paul Melnikow
77ff19903d Test the notfound routes in server.js (#2398) 2018-11-27 16:36:20 -05:00
Paul Melnikow
c678ca2abd Tweak [AUR] and add static examples (#2405) 2018-11-27 16:34:02 -05:00
Monica Bui
11493d6ab9 Add tests for [StackExchange] (#2414) 2018-11-27 15:55:05 -05:00
dependabot[bot]
1cebdd4bb1 Bump sinon-chai from 3.2.0 to 3.3.0 (#2408)
Bumps [sinon-chai](https://github.com/domenic/sinon-chai) from 3.2.0 to 3.3.0.
- [Release notes](https://github.com/domenic/sinon-chai/releases)
- [Commits](https://github.com/domenic/sinon-chai/compare/v3.2.0...3.3.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-11-27 10:44:35 -05:00
dependabot[bot]
a524658e74 Bump lint-staged from 8.0.5 to 8.1.0 (#2384)
Bumps [lint-staged](https://github.com/okonet/lint-staged) from 8.0.5 to 8.1.0.
- [Release notes](https://github.com/okonet/lint-staged/releases)
- [Commits](https://github.com/okonet/lint-staged/compare/v8.0.5...v8.1.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-11-25 21:29:04 +00:00
dependabot[bot]
aed2320d5a Bump joi from 14.0.6 to 14.3.0 (#2393)
Bumps [joi](https://github.com/hapijs/joi) from 14.0.6 to 14.3.0.
- [Release notes](https://github.com/hapijs/joi/releases)
- [Changelog](https://github.com/hapijs/joi/blob/master/CHANGELOG.md)
- [Commits](https://github.com/hapijs/joi/compare/v14.0.6...v14.3.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-11-25 21:20:47 +00:00
dependabot[bot]
08546544c8 Bump husky from 1.1.4 to 1.2.0 (#2381)
Bumps [husky](https://github.com/typicode/husky) from 1.1.4 to 1.2.0.
- [Release notes](https://github.com/typicode/husky/releases)
- [Changelog](https://github.com/typicode/husky/blob/master/CHANGELOG.md)
- [Commits](https://github.com/typicode/husky/compare/v1.1.4...v1.2.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-11-25 21:14:10 +00:00
Marcin Mielnicki
c72e366895 Run service tests on a given (remote) instance; test on [jetbrains] (#2195)
* Allow to run service tests for remote shields instance

* Allow to run service tests for remote shields instance - doc

* Load testedServerUrl from env variable

* Load 'skipIntercepted' flag from env variable
2018-11-25 15:51:57 +01:00
Pierre-Yves B
72955abac7 Added tests for Package Control service (#2390) 2018-11-25 14:33:05 +00:00
Paul Melnikow
b600bde44e The last of the badge examples (#2389)
* Move PowerShell

* Move Choco + Resharper

* Move MyGet and Nuget
2018-11-25 09:14:54 -05:00
Pierre-Yves B
b9f89d63d8 Added tests for OSS Lifecycle service (#2386) 2018-11-24 19:33:21 +00:00
dependabot[bot]
abec14812c Bump react-dom from 16.6.1 to 16.6.3 (#2374)
Bumps [react-dom](https://github.com/facebook/react) from 16.6.1 to 16.6.3.
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/compare/v16.6.1...v16.6.3)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-11-24 13:18:26 -05:00
dependabot[bot]
1a75790078 Bump fast-xml-parser from 3.12.7 to 3.12.8 (#2385)
Bumps [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) from 3.12.7 to 3.12.8.
- [Release notes](https://github.com/NaturalIntelligence/fast-xml-parser/releases)
- [Changelog](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md)
- [Commits](https://github.com/NaturalIntelligence/fast-xml-parser/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-11-24 09:40:42 +00:00
dependabot[bot]
a35d528395 Bump danger from 6.1.4 to 6.1.5 (#2380)
Bumps [danger](https://github.com/danger/danger-js) from 6.1.4 to 6.1.5.
- [Release notes](https://github.com/danger/danger-js/releases)
- [Changelog](https://github.com/danger/danger-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/danger/danger-js/compare/6.1.4...6.1.5)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-11-24 09:35:53 +00:00
dependabot[bot]
bef82d092f Bump simple-icons from 1.9.13 to 1.9.14 (#2383)
Bumps [simple-icons](https://github.com/simple-icons/simple-icons) from 1.9.13 to 1.9.14.
- [Release notes](https://github.com/simple-icons/simple-icons/releases)
- [Commits](https://github.com/simple-icons/simple-icons/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-11-23 12:19:46 +13:00
Paul Melnikow
da0bf8c57c Remove unused chai-as-promised dependency (#2359) 2018-11-21 17:10:09 -05:00
Paul Melnikow
5c577bf8b7 Circle: Remove obsolete check (#2371)
As discussed at #2314.
2018-11-21 17:07:54 -05:00
Paul Melnikow
705d3dba9d Readme: Update badge label (#2372)
I think this better captures the meaning of this badge, especially from an outsider perspective.
2018-11-21 17:05:37 -05:00
Haythem Tlili
f076b46da8 CircleCI token documentation (#2379) 2018-11-21 10:42:26 -06:00
Haythem Tlili
ce0b492029 Fix CircleCI token example (#2373)
The CircleCI token example contains a redundant fragment `/circleci/circleci/:token`.
2018-11-20 15:35:44 -06:00
dependabot[bot]
5a367efe11 Bump eslint-plugin-node from 7.0.1 to 8.0.0 (#2225)
* Bump eslint-plugin-node from 7.0.1 to 8.0.0

Bumps [eslint-plugin-node](https://github.com/mysticatea/eslint-plugin-node) from 7.0.1 to 8.0.0.
- [Release notes](https://github.com/mysticatea/eslint-plugin-node/releases)
- [Commits](https://github.com/mysticatea/eslint-plugin-node/compare/v7.0.1...v8.0.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>

* Update lockfile

* Temporarily ignore…
2018-11-19 16:15:47 -05:00
dependabot[bot]
7fa8f9dbca Bump react from 16.5.2 to 16.6.3 (#2319)
* Bump react from 16.5.2 to 16.6.3

Bumps [react](https://github.com/facebook/react) from 16.5.2 to 16.6.3.
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/compare/v16.5.2...v16.6.3)

Signed-off-by: dependabot[bot] <support@dependabot.com>

* Bump react-dom from 16.5.2 to 16.6.1

Bumps [react-dom](https://github.com/facebook/react) from 16.5.2 to 16.6.1.
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/compare/v16.5.2...v16.6.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-11-19 16:11:10 -05:00
dependabot[bot]
fcd33fec1e Bump @babel/core from 7.1.2 to 7.1.6 (#2318)
Bumps [@babel/core](https://github.com/babel/babel) from 7.1.2 to 7.1.6.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.1.2...v7.1.6)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-11-19 16:05:00 -05:00
dependabot[bot]
d9f132d865 Bump @babel/preset-env from 7.1.0 to 7.1.6 (#2315)
* Bump @babel/preset-env from 7.1.0 to 7.1.6

Bumps [@babel/preset-env](https://github.com/babel/babel) from 7.1.0 to 7.1.6.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.1.0...v7.1.6)

Signed-off-by: dependabot[bot] <support@dependabot.com>

* Update lockfile
2018-11-19 16:02:45 -05:00
Mehmet Seçkin
6b0977be9d Add support for JaCoCo style line coverage (#2369)
JaCoCo uses "Line" as the type name for line coverage metric counter.
Added a condition to accept "Line" as a valid coverage stat label to
support JaCoCo style coverage reports.

See https://www.jacoco.org/jacoco/trunk/coverage/report.dtd for details
2018-11-19 20:47:36 +00:00
Paul Melnikow
ccfac2eab3 Move remaining badge examples into services/ [cpan] (#2349)
Except NuGet; leaving those for the last pass.
2018-11-19 15:25:34 -05:00
dependabot[bot]
c9057266ea Bump concurrently from 4.0.1 to 4.1.0 (#2365)
Bumps [concurrently](https://github.com/kimmobrunfeldt/concurrently) from 4.0.1 to 4.1.0.
- [Release notes](https://github.com/kimmobrunfeldt/concurrently/releases)
- [Commits](https://github.com/kimmobrunfeldt/concurrently/compare/v4.0.1...v4.1.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-11-19 19:35:23 +00:00
dependabot[bot]
5bbac67869 Bump lint-staged from 7.3.0 to 8.0.5 (#2363)
Bumps [lint-staged](https://github.com/okonet/lint-staged) from 7.3.0 to 8.0.5.
- [Release notes](https://github.com/okonet/lint-staged/releases)
- [Commits](https://github.com/okonet/lint-staged/compare/v7.3.0...v8.0.5)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-11-19 19:27:27 +00:00
dependabot[bot]
c4076063d3 Bump joi from 14.0.4 to 14.0.6 (#2361)
Bumps [joi](https://github.com/hapijs/joi) from 14.0.4 to 14.0.6.
- [Release notes](https://github.com/hapijs/joi/releases)
- [Changelog](https://github.com/hapijs/joi/blob/master/CHANGELOG.md)
- [Commits](https://github.com/hapijs/joi/compare/v14.0.4...v14.0.6)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-11-19 19:22:16 +00:00
chris48s
762245a547 refactor [conda] service (#2353) 2018-11-19 19:11:41 +00:00
Paul Melnikow
b922fca982 Fix regression with double-dash escaping in [StaticBadge] (#2367)
Fix #2366
2018-11-19 06:31:41 -05:00
dependabot[bot]
6305c59a25 Bump snap-shot-it from 6.2.3 to 6.2.5 (#2364)
Bumps [snap-shot-it](https://github.com/bahmutov/snap-shot-it) from 6.2.3 to 6.2.5.
- [Release notes](https://github.com/bahmutov/snap-shot-it/releases)
- [Commits](https://github.com/bahmutov/snap-shot-it/compare/v6.2.3...v6.2.5)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-11-19 00:48:07 -05:00
dependabot[bot]
cd856ef1e2 Bump husky from 1.1.3 to 1.1.4 (#2362)
Bumps [husky](https://github.com/typicode/husky) from 1.1.3 to 1.1.4.
- [Release notes](https://github.com/typicode/husky/releases)
- [Changelog](https://github.com/typicode/husky/blob/master/CHANGELOG.md)
- [Commits](https://github.com/typicode/husky/compare/v1.1.3...v1.1.4)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-11-19 00:35:34 -05:00
Paul Melnikow
842f545207 Coverage: ignore next.config (#2358)
It does not make sense to check coverage for `next.config.js`. This file is run by the frontend build, which seems sufficient.

If that file has logic in it that is complex enough to warrant testing, it should be broken out into a separate file.
2018-11-18 14:26:25 -05:00
Paul Melnikow
a6a1aaeb70 Friendlier test failures when services won’t register (#2350)
Avoids crashes in `server.spec.js` accompanied by this cryptic message:

```
Error: listen EADDRINUSE :::1111
  at Object._errnoException (util.js:1022:11)
  at _exceptionWithHostPort (util.js:1044:20)
  at Camp.setupListenHandle [as _listen2] (net.js:1367:14)
  at listenInCluster (net.js:1408:12)
  at doListen (net.js:1517:7)
  at _combinedTickCallback (internal/process/next_tick.js:141:11)
  at process._tickDomainCallback (internal/process/next_tick.js:218:9)
```

e.g. https://circleci.com/gh/badges/shields/24094
2018-11-18 13:20:08 -05:00
Paul Melnikow
40728f67b3 Examples: Fix queryParams with namedParams (#2339)
These tests clearly should be refactored, though I’d like to get this fix in, in advance of a more involved refactor that shifts most of the responsibility away from this function. Maybe we can even eliminate at least one of these cases in the meantime.
2018-11-18 13:14:38 -05:00
Pierre-Yves B
5ed0f67640 Deprecate [ImageLayers] service (#2352) 2018-11-18 18:08:47 +00:00
Pierre-Yves B
060d7dd484 Moved hhvm tests to right folder (#2351) 2018-11-18 18:05:25 +00:00
1105 changed files with 60932 additions and 30237 deletions

View File

@@ -1,2 +0,0 @@
https://github.com/mojodna/heroku-buildpack-cairo.git
https://github.com/heroku/heroku-buildpack-nodejs.git

View File

@@ -1,5 +1,177 @@
version: 2
main_steps: &main_steps
steps:
- checkout
- restore_cache:
keys:
- v2-dependencies-{{ checksum "package-lock.json" }}
# https://github.com/badges/shields/issues/1937
- v2-dependencies-
- run:
name: Install dependencies
command: npm ci
- save_cache:
paths:
- node_modules
key: v2-dependencies-{{ checksum "package-lock.json" }}
- run:
name: Linter
when: always
command: npm run lint
- run:
name: Core tests
when: always
environment:
mocha_reporter: mocha-junit-reporter
MOCHA_FILE: junit/core/results.xml
command: npm run test:core
- run:
name: Entrypoint tests
when: always
environment:
mocha_reporter: mocha-junit-reporter
MOCHA_FILE: junit/entrypoint/results.xml
command: npm run test:entrypoint
- store_test_results:
path: junit
- run:
name: 'Prettier check (quick fix: `npm run prettier`)'
when: always
command: npm run prettier:check
integration_steps: &integration_steps
steps:
- checkout
- restore_cache:
keys:
- v2-dependencies-{{ checksum "package-lock.json" }}
# https://github.com/badges/shields/issues/1937
- v2-dependencies-
- run:
name: Install dependencies
command: npm ci
- run:
name: Integration tests
when: always
environment:
mocha_reporter: mocha-junit-reporter
MOCHA_FILE: junit/integration/results.xml
command: npm run test:integration
- store_test_results:
path: junit
services_steps: &services_steps
steps:
- checkout
- restore_cache:
keys:
- v2-dependencies-{{ checksum "package-lock.json" }}
# https://github.com/badges/shields/issues/1937
- v2-dependencies-
- run:
name: Install dependencies
command: npm ci
- run:
name: Identify services tagged in the PR title
command: npm run test:services:pr:prepare
- run:
name: Run tests for tagged services
environment:
mocha_reporter: mocha-junit-reporter
MOCHA_FILE: junit/services/results.xml
command: npm run test:services:pr:run
- store_test_results:
path: junit
run_package_tests: &run_package_tests
when: always
command: |
# https://discuss.circleci.com/t/switch-nodejs-version-on-machine-executor-solved/26675/3
set +e
export NVM_DIR="/opt/circleci/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
nvm install $NODE_VERSION
nvm use $NODE_VERSION
node --version
npm run test:package
package_steps: &package_steps
steps:
- checkout
- restore_cache:
keys:
- v2-dependencies-{{ checksum "package-lock.json" }}
# https://github.com/badges/shields/issues/1937
- v2-dependencies-
- run:
name: Install dependencies
command: |
set +e
export NVM_DIR="/opt/circleci/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
nvm install v12
nvm use v12
npm install -g npm
npm ci
# Run the package tests on each currently supported node version. See:
# https://github.com/badges/shields/blob/master/gh-badges/README.md#node-version-support
- run:
<<: *run_package_tests
environment:
mocha_reporter: mocha-junit-reporter
MOCHA_FILE: junit/gh-badges/v8/results.xml
NODE_VERSION: v8
name: Run package tests on Node 8
- run:
<<: *run_package_tests
environment:
mocha_reporter: mocha-junit-reporter
MOCHA_FILE: junit/gh-badges/v10/results.xml
NODE_VERSION: v10
name: Run package tests on Node 10
- run:
<<: *run_package_tests
environment:
mocha_reporter: mocha-junit-reporter
MOCHA_FILE: junit/gh-badges/v11/results.xml
NODE_VERSION: v11
name: Run package tests on Node 11
- run:
<<: *run_package_tests
environment:
mocha_reporter: mocha-junit-reporter
MOCHA_FILE: junit/gh-badges/v12/results.xml
NODE_VERSION: v12
name: Run package tests on Node 12
- store_test_results:
path: junit
jobs:
npm-install:
docker:
@@ -9,100 +181,44 @@ jobs:
- restore_cache:
keys:
- v2-dependencies-{{ checksum "package.json" }}
# fallback to using the latest cache if no exact match is found
- v2-dependencies-
- v2-dependencies-{{ checksum "package-lock.json" }}
# fallback to using the latest cache if no exact match is found
- v2-dependencies-
- run:
name: Install dependencies
command: npm install
command: npm ci
- save_cache:
paths:
- node_modules
key: v2-dependencies-{{ checksum "package.json" }}
key: v2-dependencies-{{ checksum "package-lock.json" }}
main:
docker:
- image: circleci/node:8
- image: redis
steps:
- checkout
- restore_cache:
key: v2-dependencies-{{ checksum "package.json" }}
# https://github.com/badges/shields/issues/1937
key: v2-dependencies-
- run:
name: Install dependencies
command: npm install
- run:
name: Linter
when: always
command: npm run lint
- run:
name: Server unit tests
when: always
command: npm run test:js:server
- run:
name: Integration tests
when: always
command: npm run test:integration
- run:
name: Tests for gh-badges package
when: always
command: npm run test:js:package
- run:
name: 'Prettier check (quick fix: `npm run prettier`)'
when: always
command: npm run prettier-check
<<: *main_steps
main@node-latest:
docker:
- image: circleci/node:latest
<<: *main_steps
integration:
docker:
- image: circleci/node:8
- image: redis
steps:
- checkout
- restore_cache:
key: v2-dependencies-{{ checksum "package.json" }}
# https://github.com/badges/shields/issues/1937
key: v2-dependencies-
<<: *integration_steps
- run:
name: Install dependencies
command: npm install
integration@node-latest:
docker:
- image: circleci/node:latest
- image: redis
- run:
name: Linter
when: always
command: npm run lint
- run:
name: Server unit tests
when: always
command: npm run test:js:server
- run:
name: Integration tests
when: always
command: npm run test:integration
- run:
name: Tests for gh-badges package
when: always
command: npm run test:js:package
- run:
name: 'Prettier check (quick fix: `npm run prettier`)'
when: always
command: npm run prettier-check
<<: *integration_steps
danger:
docker:
@@ -111,17 +227,21 @@ jobs:
- checkout
- restore_cache:
key: v2-dependencies-{{ checksum "package.json" }}
# https://github.com/badges/shields/issues/1937
key: v2-dependencies-
keys:
- v2-dependencies-{{ checksum "package-lock.json" }}
# https://github.com/badges/shields/issues/1937
- v2-dependencies-
- run:
name: Install dependencies
command: npm install
command: npm ci
- run:
name: Danger
when: always
environment:
# https://github.com/gatsbyjs/gatsby/pull/11555
NODE_ENV: test
command: npm run danger ci
frontend:
@@ -131,129 +251,165 @@ jobs:
- checkout
- restore_cache:
key: v2-dependencies-{{ checksum "package.json" }}
# https://github.com/badges/shields/issues/1937
key: v2-dependencies-
keys:
- v2-dependencies-{{ checksum "package-lock.json" }}
# https://github.com/badges/shields/issues/1937
- v2-dependencies-
- run:
name: Install dependencies
command: npm install
command: npm ci
- run:
name: Prepare frontend tests
command: npm run defs && npm run features
- run:
name: Frontend unit tests
when: always
command: npm run test:js:frontend
environment:
mocha_reporter: mocha-junit-reporter
MOCHA_FILE: junit/frontend/results.xml
command: npm run test:frontend
- store_test_results:
path: junit
- run:
name: Frontend build completes successfully
when: always
command: npm run build
package:
machine: true
<<: *package_steps
services:
docker:
- image: circleci/node:8
steps:
- checkout
- run:
name: Prepare service tests
command: |
mkdir private
echo "{\"gh_token\":\"$GITHUB_TOKEN\"}" > private/secret.json
- restore_cache:
key: v2-dependencies-{{ checksum "package.json" }}
# https://github.com/badges/shields/issues/1937
key: v2-dependencies-
- run:
name: Install dependencies
command: npm install
- run:
name: Identify services tagged in the PR title
command: |
if [[ ! -z $CI_PULL_REQUEST ]]; then
npm run test:services:pr:prepare
else
echo 'This is not a pull request. Skipping.'
fi
- run:
name: Run tests for tagged services
command: |
if [[ ! -z $CI_PULL_REQUEST ]]; then
npm run test:services:pr:run
else
echo 'This is not a pull request. Skipping.'
fi
<<: *services_steps
services@node-latest:
docker:
- image: circleci/node:latest
<<: *services_steps
e2e:
docker:
- image: cypress/base:8
steps:
- checkout
- run:
name: Prepare service tests
command: |
mkdir private
echo "{\"gh_token\":\"$GITHUB_TOKEN\"}" > private/secret.json
- restore_cache:
key: v2-dependencies-{{ checksum "package.json" }}
# https://github.com/badges/shields/issues/1937
key: v2-dependencies-
keys:
- v2-dependencies-{{ checksum "package-lock.json" }}
# https://github.com/badges/shields/issues/1937
- v2-dependencies-
- run:
name: Install dependencies
command: npm install
command: npm ci
- run:
name: Identify services tagged in the PR title
command: |
if [[ ! -z $CI_PULL_REQUEST ]]; then
npm run test:services:pr:prepare
else
echo 'This is not a pull request. Skipping.'
fi
name: Frontend build
command: GATSBY_BASE_URL=http://localhost:8080 npm run build
- run:
name: Run tests for tagged services
command: |
if [[ ! -z $CI_PULL_REQUEST ]]; then
npm run test:services:pr:run
else
echo 'This is not a pull request. Skipping.'
fi
name: Run tests
environment:
CYPRESS_REPORTER: junit
MOCHA_FILE: junit/e2e/results.xml
command: npm run e2e-on-build
- store_test_results:
path: junit
- store_artifacts:
path: cypress/videos
- store_artifacts:
path: cypress/screenshots
workflows:
version: 2
on-commit:
jobs:
- npm-install:
- main:
filters:
branches:
ignore: gh-pages
- main:
requires:
- npm-install
- main@node-latest:
requires:
- npm-install
- frontend:
requires:
- npm-install
- services:
requires:
- npm-install
- services@node-latest:
requires:
- npm-install
- danger:
requires:
- npm-install
filters:
branches:
ignore: /dependabot\/.*/
ignore: gh-pages
- integration@node-latest:
filters:
branches:
ignore: gh-pages
- frontend:
filters:
branches:
ignore: gh-pages
- package:
filters:
branches:
ignore: gh-pages
- services:
filters:
branches:
ignore:
- master
- gh-pages
- services@node-latest:
filters:
branches:
ignore:
- master
- gh-pages
- danger:
filters:
branches:
ignore:
- master
- gh-pages
- /dependabot\/.*/
- e2e:
filters:
branches:
ignore: gh-pages
# on-commit-with-cache:
# jobs:
# - npm-install:
# filters:
# branches:
# ignore: gh-pages
# - main:
# requires:
# - npm-install
# - main@node-latest:
# requires:
# - npm-install
# - frontend:
# requires:
# - npm-install
# - services:
# requires:
# - npm-install
# filters:
# branches:
# ignore: master
# - services@node-latest:
# requires:
# - npm-install
# filters:
# branches:
# ignore: master
# - danger:
# requires:
# - npm-install
# filters:
# branches:
# ignore: /dependabot\/.*/

11
.dependabot/config.yml Normal file
View File

@@ -0,0 +1,11 @@
version: 1
update_configs:
# shields.io dependencies
- package_manager: 'javascript'
directory: '/'
update_schedule: 'weekly'
# gh-badges package dependencies
- package_manager: 'javascript'
directory: '/gh-badges'
update_schedule: 'weekly'

View File

@@ -2,3 +2,7 @@ node_modules/
shields.env
.git/
.gitignore
.vscode/
# Improve layer cacheability.
Dockerfile

View File

@@ -1,3 +1,5 @@
/build
/coverage
/__snapshots__
/public
gh-badges/node_modules/

View File

@@ -3,22 +3,26 @@ env:
plugins:
- import
- react-hooks
parser: "babel-eslint"
parser: 'babel-eslint'
parserOptions:
sourceType: "module"
sourceType: 'module'
extends:
- "standard-jsx"
- "standard-react"
- "./.eslintrc.yml"
- 'standard-jsx'
- 'standard-react'
- './.eslintrc.yml'
settings:
react:
version: "16.4"
version: '16.4'
rules:
no-console: "error"
no-console: 'error'
import/extensions: ["error", "never", { "json": "always" }]
import/extensions: ['error', 'never', { 'json': 'always', 'yml': 'always' }]
react/jsx-sort-props: 'error'
react-hooks/rules-of-hooks: 'error'
react-hooks/exhaustive-deps: 'error'

View File

@@ -9,41 +9,76 @@ env:
parserOptions:
# Override eslint-config-standard, which incorrectly sets this to "module",
# though that setting is only for ES6 modules, not CommonJS modules.
sourceType: "script"
sourceType: 'script'
overrides:
- files:
- gatsby-browser.js
parserOptions:
sourceType: 'module'
- files:
- 'core/base-service/**/*.js'
- 'services/**/*.js'
rules:
sort-class-members/sort-class-members:
[
'error',
{
order:
[
'name',
'category',
'isDeprecated',
'route',
'examples',
'_cacheLength',
'defaultBadgeData',
'render',
'constructor',
'fetch',
'transform',
'handle',
],
},
]
plugins:
- mocha
- no-extension-in-require
- "chai-friendly"
- chai-friendly
- sort-class-members
rules:
# Disable some rules from eslint:recommended.
no-console: "off"
no-empty: ["error", { "allowEmptyCatch": true }]
no-console: 'off'
no-empty: ['error', { 'allowEmptyCatch': true }]
# Allow unused parameters. In callbacks, removing them seems to obscure
# what the functions are doing.
no-unused-vars: ["error", {"args": "none"}]
no-unused-vars: ['error', { 'args': 'none' }]
# These should be disabled by eslint-config-prettier, but are not.
spaced-comment: "off"
standard/object-curly-even-spacing: "off"
one-var: "off"
spaced-comment: 'off'
standard/object-curly-even-spacing: 'off'
one-var: 'off'
# Shields additions.
no-var: "error"
prefer-const: "error"
strict: "error"
arrow-body-style: ["error", "as-needed"]
no-extension-in-require/main: "error"
object-shorthand: ["error", "properties"]
prefer-template: "error"
promise/prefer-await-to-then: "error"
no-var: 'error'
prefer-const: 'error'
strict: 'error'
arrow-body-style: ['error', 'as-needed']
no-extension-in-require/main: 'error'
object-shorthand: ['error', 'properties']
prefer-template: 'error'
promise/prefer-await-to-then: 'error'
func-style: ['error', 'declaration', { 'allowArrowFunctions': true }]
new-cap: ['error', { 'capIsNew': true }]
import/order: ['error', { 'newlines-between': 'never' }]
# Mocha-related.
mocha/no-exclusive-tests: "error"
mocha/no-mocha-arrows: "error"
mocha/prefer-arrow-callback: "error"
mocha/no-exclusive-tests: 'error'
mocha/no-mocha-arrows: 'error'
mocha/prefer-arrow-callback: 'error'
# Chai friendly.
no-unused-expressions: "off"
chai-friendly/no-unused-expressions: "error"
no-unused-expressions: 'off'
chai-friendly/no-unused-expressions: 'error'

1
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1 @@
open_collective: shields

View File

@@ -1,26 +1,28 @@
---
name: 🐛 Bug Report
about: Report errors and problems
---
Are you experiencing an issue with...
- [ ] [shields.io](https://shields.io/#/)
- [ ] My own instance
- [ ] [gh-badges NPM package](https://www.npmjs.com/package/gh-badges)
- [ ] [shields.io](https://shields.io/#/)
- [ ] My own instance
- [ ] [gh-badges NPM package](https://www.npmjs.com/package/gh-badges)
:beetle: **Description**
<!-- A clear and concise description of the problem. -->
:link: **Link to the badge**
<!--
If you are reporting a problem with a specific badge on shields.io,
provide a link to a badge demonstrating the error
-->
:bulb: **Possible Solution**
<!--- Optional: only if you have suggestions on a fix/reason for the bug -->
<!--- Optional: only if you have suggestions on a fix/reason for the bug -->
<!-- Love Shields? Please consider donating $10 to sustain our activities:
👉 https://opencollective.com/shields -->

View File

@@ -0,0 +1,35 @@
---
name: 💚 Failing service test
about: Note failing service tests
---
:clock11: **When did the problem start?**
<!-- Indicate when the problem started -->
:camera: **Live badge**
<!-- Provide a link to the live badge in plain text and markdown. -->
![]( url goes here )
:wrench: **Is the live badge working?**
<!-- Indicate whether or not the live badge is working. -->
:link: **CircleCI link**
<!-- Provide a link to the failing test in CircleCI. -->
:beetle: **Stack trace**
```
<!-- Provide the complete stack trace from the CircleCI test summary. -->
```
:bulb: **Possible solution**
<!--- Optional: only if you have suggestions on a fix/reason for the bug -->
<!-- Love Shields? Please consider donating $10 to sustain our activities:
👉 https://opencollective.com/shields -->

View File

@@ -1,10 +1,10 @@
---
name: 💡 Badge Request
about: Ideas for new badges
---
:clipboard: **Description**
<!--
A clear and concise description of the new badge.
@@ -15,6 +15,7 @@ A clear and concise description of the new badge.
-->
:link: **Data**
<!--
Where can we get the data from?
@@ -23,6 +24,13 @@ Where can we get the data from?
- Link to the API documentation.
-->
:microphone: **Motivation**
<!--
Please explain why this feature should be implemented and how it would be used.
- What is the specific use case?
-->
<!-- Love Shields? Please consider donating $10 to sustain our activities:
👉 https://opencollective.com/shields -->

View File

@@ -1,12 +1,11 @@
---
name: 💡 Feature Request
about: Ideas for other new features or improvements
---
:clipboard: **Description**
<!-- A clear and concise description of the new feature. -->
<!-- A clear and concise description of the new feature. -->
<!-- Love Shields? Please consider donating $10 to sustain our activities:
👉 https://opencollective.com/shields -->

View File

@@ -1,10 +1,10 @@
---
name: ❓ Support Question
about: Ask a question about shields.io
---
:question: **Question**
<!--
Ask your question clearly and concisely.
@@ -12,6 +12,5 @@ Ask your question clearly and concisely.
is also a great place to ask questions and get help
-->
<!-- Love Shields? Please consider donating $10 to sustain our activities:
👉 https://opencollective.com/shields -->

18
.gitignore vendored
View File

@@ -17,6 +17,9 @@ Desktop.ini
._*
Thumbs.db
# Visual Studio Code User Settings
.vscode/settings.json
# eclipse
.project
.settings
@@ -92,3 +95,18 @@ typings/
.next
badge-examples.json
supported-features.json
service-definitions.yml
# Local runtime configuration.
/config/local*.yml
# Template for the local runtime configuration.
!/config/local*.template.yml
# Gatsby
/.cache
/public
# Cypress
/cypress/videos/
/cypress/screenshots/

5
.gitpod.yml Normal file
View File

@@ -0,0 +1,5 @@
ports:
- port: 8080
tasks:
- init: npm ci && npm run build
command: node server 8080 0.0.0.0

6
.mocharc-frontend.yml Normal file
View File

@@ -0,0 +1,6 @@
reporter: mocha-env-reporter
require:
- '@babel/polyfill'
- '@babel/register'
- mocha-yaml-loader
- frontend/mocha-ignore-pngs

1
.mocharc.yml Normal file
View File

@@ -0,0 +1 @@
reporter: mocha-env-reporter

30
.nowignore Normal file
View File

@@ -0,0 +1,30 @@
*
!frontend/
!gh-badges/
!lib/
!core/
!logo/
!pages/
!public/
!templates/
!services/
!package-lock.json
!/*.js
!scripts/export-*.js
!config/
config/local*.yml
*.spec.js
*~
.env
.circleci
.github
.vscode
__snapshots__
.buildpacks
.eslint*
.editorconfig
.nycrc*
.gitpod*
.prettier*
CONTRIBUTING.md
Dockerfile

10
.nycrc-frontend.json Normal file
View File

@@ -0,0 +1,10 @@
{
"reporter": ["lcov"],
"all": false,
"silent": true,
"clean": false,
"sourceMap": false,
"instrument": false,
"include": ["frontend/**/*.js"],
"exclude": ["**/*.spec.js", "**/mocha-*.js"]
}

View File

@@ -1,16 +1,24 @@
{
"reporter": ["lcov"],
"all": true,
"silent": true,
"clean": false,
"exclude": [
"**/*.spec.js",
"**/*.integration.js",
"**/test-helpers.js",
"**/*-test-helpers.js",
"**/*-fixtures.js",
"dangerfile.js",
"gatsby-*.js",
"core/service-test-runner",
"services/**/*.tester.js",
"test-fixtures",
"services/test-validators.js",
"services/tester.js",
"core/base-service/loader-test-fixtures",
"scripts",
"coverage",
"build"
],
"silent": true,
"clean": false
"build",
".github"
]
}

View File

@@ -2,7 +2,13 @@ package.json
package-lock.json
/__snapshots__
/.next
/.cache
/build
/public
/coverage
**/*.md
private/*.json
/.nyc_output
analytics.json
gh-badges/templates/default-template.json
supported-features.json
service-definitions.yml

View File

@@ -2,3 +2,4 @@ semi: false
singleQuote: true
trailingComma: es5
bracketSpacing: true
endOfLine: lf

7
.vscode/extensions.json vendored Normal file
View File

@@ -0,0 +1,7 @@
{
"recommendations": [
"esbenp.prettier-vscode",
"EditorConfig.EditorConfig",
"dbaeumer.vscode-eslint"
]
}

13
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,13 @@
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "attach",
"name": "Node: Nodemon",
"processId": "${command:PickProcess}",
"restart": true,
"protocol": "inspector"
}
]
}

View File

@@ -1,12 +1,9 @@
Contributing to Shields
=======================
# Contributing to Shields
Shields is a community project. We invite your participation through
financial contributions, issues, and pull requests!
Ways you can help
-----------------
## Ways you can help
### Financial contributions
@@ -38,7 +35,7 @@ wonderful side effect of making the code more readable and therefore more
approachable. It's also a great way to teach and learn. Feel free to jump in!
Be welcoming, appreciative, and helpful. You can perform first reviews of
simple changes, like badge additions. These are usually tagged with
[service badge][service badge PR tag].
[service badge][service badge pr tag].
Please review [these impeccable guidelines][code review guidelines].
@@ -48,8 +45,8 @@ have questions about contributing to Shields, or using it for their projects.
Feel free to reach out to one of the [maintainers][]
if you need help getting started.
[service badge PR tag]: https://github.com/badges/shields/pulls?q=is%3Apr+is%3Aopen+label%3Aservice-badge
[code review guidelines]: http://amyciavolino.com/assets/MindfulCommunicationInCodeReviews.pdf
[service badge pr tag]: https://github.com/badges/shields/pulls?q=is%3Apr+is%3Aopen+label%3Aservice-badge
[code review guidelines]: https://kickstarter.engineering/a-guide-to-mindful-communication-in-code-reviews-48aab5282e5e
[issues]: https://github.com/badges/shields/issues
[chat room]: https://discordapp.com/invite/HjJCwm5
[maintainers]: https://github.com/badges/shields#project-leaders
@@ -72,10 +69,9 @@ don't see it, feel free to [open a new issue][open an issue].
Feel free to star the repository. This will help increase the visibility of the project, therefore attracting more users and contributors to Shields!
We're also asking for [one-time $10 donations](https://opencollective.com/shields) from developers who use and love Shields, please spread the word!
We're also asking for [one-time \$10 donations](https://opencollective.com/shields) from developers who use and love Shields, please spread the word!
Getting help
------------
## Getting help
There are three places to get help:
@@ -87,21 +83,16 @@ There are three places to get help:
[tutorial]: doc/TUTORIAL.md
Badge guidelines
----------------
## Badge guidelines
- Shields.io hosts integrations for services which are primarily
used by developers or which are widely used by developers
- The left-hand side of a badge should not advertise. It should be a lowercase *noun*
- The left-hand side of a badge should not advertise. It should be a lowercase _noun_
succinctly describing the meaning of the right-hand side.
- Query parameters must be *declared by the service*. See `request-handler.js`.
- Except for badges using the `social` style, logos should be *turned off by
default*.
- Except for badges using the `social` style, logos should be _turned off by
default_.
Badge URLs
----------
## Badge URLs
- The format of new badges should be of the form
`/SERVICE/NOUN/PARAMETERS/QUALIFIERS.format`. For instance,
@@ -111,14 +102,12 @@ Badge URLs
`/SERVICE/SCHEME/HOST/NOUN/PARAMETERS/QUALIFIERS.format`. For instance,
`/discourse/https/discourse.example.com/topics.svg`.
Coding guidelines
-----------------
## Coding guidelines
### Prettier
This project formats its source code using Prettier. The most enjoyable way to
use Prettier is to let is format code for you when you save. You can [integrate
use Prettier is to let it format code for you when you save. You can [integrate
it into your editor][integrate prettier].
Whether you integrate it into your editor or not, a pre-commit hook will run
@@ -145,21 +134,8 @@ start the server automatically.
### Code organization
Function declarations are placed in `lib/`, not directly in `server.js`.
There is a [High-level code walkthrough](doc/code-walkthrough.md) describing the layout of the project.
### Logos
Logos
-----
We support a wide range of logos via [SimpleIcons][] and encourage you to [contribute logos to that project][simple-icons github].
We also accept logos directly. In general, we do this only when we have a corresponding badge on the homepage, (e.g. the Eclipse logo because we support service badges for the Eclipse Marketplace). We may also approve logos for tools widely used by developers (e.g. our Slack logo). We will happily consider all requests, but don't expect systematic approval, it's at the discretion of the maintainers.
Please minimize checked-in SVG files through [SVGO][]. You can use [svgomg][].
If you want to use a logo that does not meet our guidelines, a custom logo can be passed in a URL parameter by base64 encoding it. For example this badge ![](https://img.shields.io/badge/play-station-blue.svg?logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEiIHdpZHRoPSI2MDAiIGhlaWdodD0iNjAwIj48cGF0aCBkPSJNMTI5IDExMWMtNTUgNC05MyA2Ni05MyA3OEwwIDM5OGMtMiA3MCAzNiA5MiA2OSA5MWgxYzc5IDAgODctNTcgMTMwLTEyOGgyMDFjNDMgNzEgNTAgMTI4IDEyOSAxMjhoMWMzMyAxIDcxLTIxIDY5LTkxbC0zNi0yMDljMC0xMi00MC03OC05OC03OGgtMTBjLTYzIDAtOTIgMzUtOTIgNDJIMjM2YzAtNy0yOS00Mi05Mi00MmgtMTV6IiBmaWxsPSIjZmZmIi8+PC9zdmc+) could be generated by calling: https://img.shields.io/badge/play-station-blue.svg?logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEiIHdpZHRoPSI2MDAiIGhlaWdodD0iNjAwIj48cGF0aCBkPSJNMTI5IDExMWMtNTUgNC05MyA2Ni05MyA3OEwwIDM5OGMtMiA3MCAzNiA5MiA2OSA5MWgxYzc5IDAgODctNTcgMTMwLTEyOGgyMDFjNDMgNzEgNTAgMTI4IDEyOSAxMjhoMWMzMyAxIDcxLTIxIDY5LTkxbC0zNi0yMDljMC0xMi00MC03OC05OC03OGgtMTBjLTYzIDAtOTIgMzUtOTIgNDJIMjM2YzAtNy0yOS00Mi05Mi00MmgtMTV6IiBmaWxsPSIjZmZmIi8+PC9zdmc+
[simpleicons]: https://simpleicons.org/
[simple-icons github]: https://github.com/simple-icons/simple-icons
[SVGO]: https://github.com/svg/svgo
[svgomg]: https://jakearchibald.github.io/svgomg/
We have [documentation for logo usage](doc/logos.md) which includes [contribution guidance](doc/logos.md#contributing-logos)

View File

@@ -1,4 +1,4 @@
FROM node:8.9.4-alpine
FROM node:8-alpine
RUN apk add --no-cache gettext imagemagick librsvg git
@@ -6,16 +6,21 @@ RUN mkdir -p /usr/src/app
RUN mkdir /usr/src/app/private
WORKDIR /usr/src/app
ARG NODE_ENV
ENV NODE_ENV $NODE_ENV
COPY package.json /usr/src/app/
RUN npm install
COPY package.json package-lock.json /usr/src/app/
# Without the gh-badges package.json and CLI script in place, `npm ci` will fail.
COPY gh-badges /usr/src/app/gh-badges/
# We need dev deps to build the front end.
RUN NODE_ENV=development npm ci
COPY . /usr/src/app
RUN npm run build
RUN npm prune --production
RUN npm cache clean --force
CMD envsubst < secret.tpl.json > ./private/secret.json \
&& node server
# Run the server using production configs.
ENV NODE_ENV production
CMD node server
EXPOSE 80

View File

@@ -8,10 +8,7 @@ FRONTEND_TMP=${TMPDIR}shields-frontend-deploy
# pushing secrets to GitHub, this branch is configured to reject pushes.
WORKING_BRANCH=server-deploy-working-branch
all: website test
website:
LONG_CACHE=false npm run build
all: test
deploy: deploy-s0 deploy-s1 deploy-s2 clean-server-deploy deploy-gh-pages deploy-gh-pages-clean
@@ -19,18 +16,19 @@ deploy-s0: prepare-server-deploy push-s0
deploy-s1: prepare-server-deploy push-s1
deploy-s2: prepare-server-deploy push-s2
prepare-server-deploy: website
prepare-server-deploy:
# Ship a copy of the front end to each server for debugging.
# https://github.com/badges/shields/issues/1220
INCLUDE_DEV_PAGES=false \
npm run build
rm -rf ${SERVER_TMP}
git worktree prune
git worktree add -B ${WORKING_BRANCH} ${SERVER_TMP}
cp -r build ${SERVER_TMP}
git -C ${SERVER_TMP} add -f build/
cp -r public ${SERVER_TMP}
git -C ${SERVER_TMP} add -f public/
git -C ${SERVER_TMP} commit --no-verify -m '[DEPLOY] Add frontend for debugging'
mkdir -p ${SERVER_TMP}/private
cp private/secret-production.json ${SERVER_TMP}/private/secret.json
git -C ${SERVER_TMP} add -f private/secret.json
cp config/local-shields-io-production.yml ${SERVER_TMP}/config/
git -C ${SERVER_TMP} add -f config/local-shields-io-production.yml
git -C ${SERVER_TMP} commit --no-verify -m '[DEPLOY] MUST NOT BE ON GITHUB'
clean-server-deploy:
@@ -49,15 +47,13 @@ push-s2:
deploy-gh-pages:
rm -rf ${FRONTEND_TMP}
git worktree prune
LONG_CACHE=true \
BASE_URL=https://img.shields.io \
NEXT_ASSET_PREFIX=https://shields.io \
GATSBY_BASE_URL=https://img.shields.io \
INCLUDE_DEV_PAGES=false \
npm run build
git worktree add -B gh-pages ${FRONTEND_TMP}
git -C ${FRONTEND_TMP} ls-files | xargs git -C ${FRONTEND_TMP} rm
git -C ${FRONTEND_TMP} commit --no-verify -m '[DEPLOY] Completely clean the index'
cp -r build/* ${FRONTEND_TMP}
cp favicon.png ${FRONTEND_TMP}
cp -r public/* ${FRONTEND_TMP}
echo shields.io > ${FRONTEND_TMP}/CNAME
touch ${FRONTEND_TMP}/.nojekyll
git -C ${FRONTEND_TMP} add .
@@ -68,17 +64,7 @@ deploy-gh-pages-clean:
rm -rf ${FRONTEND_TMP}
git worktree prune
deploy-heroku:
git add -f private/secret.json build/
git commit --no-verify -m'MUST NOT BE ON GITHUB'
git push -f heroku HEAD:master
git reset HEAD~1
(git checkout -B gh-pages && \
git merge master && \
git push -f origin gh-pages:gh-pages) || git checkout master
git checkout master
test:
npm test
.PHONY: all website deploy prepare-server-deploy clean-server-deploy deploy-s0 deploy-s1 deploy-s2 push-s0 push-s1 push-s2 deploy-gh-pages deploy-gh-pages-clean deploy-heroku setup redis test
.PHONY: all deploy prepare-server-deploy clean-server-deploy deploy-s0 deploy-s1 deploy-s2 push-s0 push-s1 push-s2 deploy-gh-pages deploy-gh-pages-clean deploy-heroku setup redis test

View File

@@ -1 +1 @@
web: node server
web: npm run start:server:prod

151
README.md
View File

@@ -1,27 +1,30 @@
<p align="center">
<img src="https://rawgit.com/badges/shields/master/static/logo.svg"
<img src="./frontend/images/logo.svg"
height="130">
</p>
<p align="center">
<a href="https://github.com/badges/shields/graphs/contributors" alt="Contributors">
<img src="https://img.shields.io/github/contributors/badges/shields.svg" /></a>
<a href="#backers" alt="Backers on Open Collective">
<img src="https://opencollective.com/shields/backers/badge.svg" /></a>
<img src="https://img.shields.io/opencollective/backers/shields.svg" /></a>
<a href="#sponsors" alt="Sponsors on Open Collective">
<img src="https://opencollective.com/shields/sponsors/badge.svg" /></a>
<img src="https://img.shields.io/opencollective/sponsors/shields.svg" /></a>
<a href="https://github.com/badges/shields/pulse" alt="Activity">
<img src="https://img.shields.io/github/commit-activity/m/badges/shields.svg" /></a>
<a href="https://circleci.com/gh/badges/shields/tree/master">
<img src="https://img.shields.io/circleci/project/github/badges/shields/master.svg"
alt="build status"></a>
<img src="https://img.shields.io/circleci/project/github/badges/shields/master.svg" alt="build status"></a>
<a href="https://circleci.com/gh/badges/daily-tests">
<img src="https://img.shields.io/circleci/project/github/badges/daily-tests.svg?label=daily%20tests"
alt="daily build status"></a>
<img src="https://img.shields.io/circleci/project/github/badges/daily-tests.svg?label=service%20tests"
alt="service-test status"></a>
<a href="https://coveralls.io/github/badges/shields">
<img src="https://img.shields.io/coveralls/github/badges/shields.svg"
alt="coverage"></a>
<a href="https://lgtm.com/projects/g/badges/shields/alerts/">
<img src="https://img.shields.io/lgtm/alerts/g/badges/shields.svg"
alt="Total alerts"/></a>
<a href="https://github.com/badges/shields/compare/gh-pages...master">
<img src="https://img.shields.io/github/commits-since/badges/shields/gh-pages.svg?label=commits%20to%20be%20deployed"
alt="commits to be deployed"></a>
<a href="https://lgtm.com/projects/g/badges/shields/alerts/">
<img src="https://img.shields.io/lgtm/alerts/g/badges/shields.svg?logo=lgtm&logoWidth=18"
alt="Total alerts"/></a>
<a href="https://discord.gg/HjJCwm5">
<img src="https://img.shields.io/discord/308323056592486420.svg?logo=discord"
alt="chat on Discord"></a>
@@ -39,12 +42,11 @@ Every month it serves over 470 million images.
This repo hosts:
* The [Shields.io][shields.io] frontend and server code
* An [NPM library for generating badges][gh-badges]
* [documentation][gh-badges-docs]
* [changelog][gh-badges-changelog]
* The [badge design specification][badge-spec]
- The [Shields.io][shields.io] frontend and server code
- An [NPM library for generating badges][gh-badges]
- [documentation][gh-badges-docs]
- [changelog][gh-badges-changelog]
- The [badge design specification][badge-spec]
[shields.io]: https://shields.io/
[gh-badges]: https://www.npmjs.com/package/gh-badges
@@ -52,20 +54,18 @@ This repo hosts:
[gh-badges-docs]: https://github.com/badges/shields/tree/master/gh-badges/README.md
[gh-badges-changelog]: https://github.com/badges/shields/tree/master/gh-badges/CHANGELOG.md
## Examples
Examples
--------
* code coverage percentage: ![coverage](https://img.shields.io/badge/coverage-80%25-yellowgreen.svg?maxAge=2592000)
* stable release version: ![version](https://img.shields.io/badge/version-1.2.3-blue.svg?maxAge=2592000)
* package manager release: ![gem](https://img.shields.io/badge/gem-2.2.0-blue.svg?maxAge=2592000)
* status of third-party dependencies: ![dependencies](https://img.shields.io/badge/dependencies-out%20of%20date-orange.svg?maxAge=2592000)
* static code analysis grade: ![codacy](https://img.shields.io/badge/codacy-B-green.svg?maxAge=2592000)
* [SemVer](https://semver.org/) version observance: ![semver](https://img.shields.io/badge/semver-2.0.0-blue.svg?maxAge=2592000)
* amount of [Liberapay](https://liberapay.com/) donations per week: ![receives](https://img.shields.io/badge/receives-2.00%20USD%2Fweek-yellow.svg?maxAge=2592000)
* Python package downloads: ![downloads](https://img.shields.io/badge/downloads-13k%2Fmonth-brightgreen.svg?maxAge=2592000)
* Chrome Web Store extension rating: ![rating](https://img.shields.io/badge/rating-★★★★☆-brightgreen.svg?maxAge=2592000)
* [Uptime Robot](https://uptimerobot.com) percentage: ![uptime](https://img.shields.io/badge/uptime-100%25-brightgreen.svg?maxAge=2592000)
- code coverage percentage: ![coverage](https://img.shields.io/badge/coverage-80%25-yellowgreen.svg?cacheSeconds=2592000)
- stable release version: ![version](https://img.shields.io/badge/version-1.2.3-blue.svg?cacheSeconds=2592000)
- package manager release: ![gem](https://img.shields.io/badge/gem-2.2.0-blue.svg?cacheSeconds=2592000)
- status of third-party dependencies: ![dependencies](https://img.shields.io/badge/dependencies-out%20of%20date-orange.svg?cacheSeconds=2592000)
- static code analysis grade: ![codacy](https://img.shields.io/badge/codacy-B-green.svg?cacheSeconds=2592000)
- [SemVer](https://semver.org/) version observance: ![semver](https://img.shields.io/badge/semver-2.0.0-blue.svg?cacheSeconds=2592000)
- amount of [Liberapay](https://liberapay.com/) donations per week: ![receives](https://img.shields.io/badge/receives-2.00%20USD%2Fweek-yellow.svg?cacheSeconds=2592000)
- Python package downloads: ![downloads](https://img.shields.io/badge/downloads-13k%2Fmonth-brightgreen.svg?cacheSeconds=2592000)
- Chrome Web Store extension rating: ![rating](https://img.shields.io/badge/rating-★★★★☆-brightgreen.svg?cacheSeconds=2592000)
- [Uptime Robot](https://uptimerobot.com) percentage: ![uptime](https://img.shields.io/badge/uptime-100%25-brightgreen.svg?cacheSeconds=2592000)
[Make your own badges!][custom badges]
(Quick example: `https://img.shields.io/badge/left-right-f39f37.svg`)
@@ -74,9 +74,7 @@ Browse a [complete list of badges][shields.io].
[custom badges]: http://shields.io/#your-badge
Contributing
------------
## Contributing
Shields is a community project. We invite your participation through issues
and pull requests! You can peruse the [contributing guidelines][contributing].
@@ -94,23 +92,35 @@ You can read a [tutorial on how to add a badge][tutorial].
[tutorial]: doc/TUTORIAL.md
[contributing]: CONTRIBUTING.md
Development
-----------
## Development
1. Install Node 8 or later. You can use the [package manager][] of your choice.
Tests need to pass in Node 8 and 9.
Tests need to pass in Node 8 and 10.
2. Clone this repository.
3. Run `npm install` to install the dependencies.
4. Run `npm run build` to build the frontend.
5. Run `npm start` to start the server.
6. Open `http://[::]:8080/` to view the home page.
3. Run `npm ci` to install the dependencies.
4. Run `npm start` to start the badge server and the frontend dev server.
5. Open `http://localhost:3000/` to view the frontend.
To generate the frontend using production cache settings &ndash; that is,
badge preview URIs with `maxAge` &ndash; run `LONG_CACHE=true npm run build`.
When server source files change, the badge server should automatically restart
itself (using [nodemon][]). When the frontend files change, the frontend dev
server (`gatsby dev`) should also automatically reload. However the badge
definitions are built only before the server first starts. To regenerate those,
either run `npm run defs` or manually restart the server.
To analyze the frontend bundle, run `npm install webpack-bundle-analyzer` and
then `ANALYZE=true npm start`.
To debug a badge from the command line, run `npm run badge -- /npm/v/nock.svg`.
It also works with full URLs like
`npm run badge -- https://img.shields.io/npm/v/nock.svg`.
Use `npm run debug:server` to start server in debug mode.
[This recipe][nodemon debug] shows how to debug Node.js application in [VS Code][].
Shields has experimental support for [Gitpod Beta][gitpod], a pre-configured development
environment that runs in your browser. To use Gitpod, click the button below and
sign in with GitHub. Gitpod also offers a browser add-on, though it is not required.
Please report any Gitpod bugs, questions, or suggestions in issue
[#2772](https://github.com/badges/shields/issues/2772).
[![Edit with Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/badges/shields)
[Snapshot tests][] ensure we don't inadvertently make changes that affect the
SVG or JSON output. When deliberately changing the output, run
@@ -122,23 +132,24 @@ The server can be configured to use [Sentry][] ([configuration][sentry configura
Daily tests, including a full run of the service tests and overall code coverage, are run via [badges/daily-tests][daily-tests].
[package manager]: https://nodejs.org/en/download/package-manager/
[gitpod]: https://www.gitpod.io/
[snapshot tests]: https://glebbahmutov.com/blog/snapshot-testing/
[Prometheus]: https://prometheus.io/
[prometheus]: https://prometheus.io/
[prometheus configuration]: doc/self-hosting.md#prometheus
[Sentry]: https://sentry.io/
[sentry]: https://sentry.io/
[sentry configuration]: doc/self-hosting.md#sentry
[daily-tests]: https://github.com/badges/daily-tests
[nodemon]: https://nodemon.io/
[nodemon debug]: https://github.com/Microsoft/vscode-recipes/tree/master/nodemon
[vs code]: https://code.visualstudio.com/
Hosting your own server
-----------------------
## Hosting your own server
There is documentation about [hosting your own server][self-hosting].
[self-hosting]: doc/self-hosting.md
History
-------
## History
b.adge.me was the original website for this service. Heroku back then had a
thing which made it hard to use a toplevel domain with it, hence the odd
@@ -165,26 +176,29 @@ You can read more about [the project's inception][thread],
[spec]: spec/SPECIFICATION.md
[thread]: https://github.com/h5bp/lazyweb-requests/issues/150
## Project leaders
Project leaders
---------------
Maintainers:
[espadrine](https://github.com/espadrine) is the sysadmin.
- [calebcartwright](https://github.com/calebcartwright) (core team)
- [chris48s](https://github.com/chris48s) (core team)
- [Daniel15](https://github.com/Daniel15) (core team)
- [espadrine](https://github.com/espadrine) (core team)
- [paulmelnikow](https://github.com/paulmelnikow) (core team)
- [platan](https://github.com/platan) (core team)
- [PyvesB](https://github.com/PyvesB) (core team)
- [RedSparr0w](https://github.com/RedSparr0w) (core team)
These contributors donate time on a consistent basis to help guide and
maintain the project:
Operations:
* [chris48s](https://github.com/chris48s)
* [Daniel15](https://github.com/Daniel15)
* [espadrine](https://github.com/espadrine)
* [paulmelnikow](https://github.com/paulmelnikow)
* [platan](https://github.com/platan)
* [PyvesB](https://github.com/PyvesB)
* [RedSparr0w](https://github.com/RedSparr0w)
- [espadrine](https://github.com/espadrine) (sysadmin)
- [paulmelnikow](https://github.com/paulmelnikow) (limited access)
Alumni:
Related projects
----------------
- [olivierlacan](https://github.com/olivierlacan)
## Related projects
- [badgerbadgerbadger gem][gem]
- [pybadges python library][pybadges]
@@ -192,8 +206,7 @@ Related projects
[gem]: https://github.com/badges/badgerbadgerbadger
[pybadges]: https://github.com/google/pybadges
License
-------
## License
All assets and code are under the [CC0 LICENSE](LICENSE) and in the public
domain unless specified otherwise.
@@ -206,14 +219,12 @@ under their terms and license.
This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].
<a href="https://github.com/badges/shields/graphs/contributors"><img src="https://opencollective.com/shields/contributors.svg?width=890" /></a>
## Backers
Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/shields#backer)]
<a href="https://opencollective.com/shields#backers" target="_blank"><img src="https://opencollective.com/shields/backers.svg?width=890"></a>
## Sponsors
Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/shields#sponsor)]
@@ -228,5 +239,3 @@ Support this project by becoming a sponsor. Your logo will show up here with a l
<a href="https://opencollective.com/shields/sponsor/7/website" target="_blank"><img src="https://opencollective.com/shields/sponsor/7/avatar.svg"></a>
<a href="https://opencollective.com/shields/sponsor/8/website" target="_blank"><img src="https://opencollective.com/shields/sponsor/8/avatar.svg"></a>
<a href="https://opencollective.com/shields/sponsor/9/website" target="_blank"><img src="https://opencollective.com/shields/sponsor/9/avatar.svg"></a>

View File

@@ -2,25 +2,18 @@ exports['The badge generator SVG should always produce the same SVG (unless we h
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="90" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="a"><rect width="90" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#a)"><path fill="#555" d="M0 0h45v20H0z"/><path fill="#4c1" d="M45 0h45v20H45z"/><path fill="url(#b)" d="M0 0h90v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110"> <text x="235" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="350">cactus</text><text x="235" y="140" transform="scale(.1)" textLength="350">cactus</text><text x="665" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="350">grown</text><text x="665" y="140" transform="scale(.1)" textLength="350">grown</text></g> </svg>
`
exports['The badge generator JSON should always produce the same JSON (unless we have changed something!) 1'] = `
{
"name": "cactus",
"value": "grown"
}
`
exports['The badge generator badges with logos should always produce the same badge shields GitHub logo default color (#333333) 1'] = `
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="113" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="a"><rect width="113" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#a)"><path fill="#555" d="M0 0h54v20H0z"/><path fill="#4c1" d="M54 0h59v20H54z"/><path fill="url(#b)" d="M0 0h113v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110"><image x="5" y="3" width="14" height="14" xlink:href="github"/> <text x="365" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="270">label</text><text x="365" y="140" transform="scale(.1)" textLength="270">label</text><text x="825" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="490">message</text><text x="825" y="140" transform="scale(.1)" textLength="490">message</text></g> </svg>
`
exports['The badge generator badges with logos should always produce the same badge shields GitHub logo custom color (whitesmoke) 1'] = `
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="113" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="a"><rect width="113" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#a)"><path fill="#555" d="M0 0h54v20H0z"/><path fill="#4c1" d="M54 0h59v20H54z"/><path fill="url(#b)" d="M0 0h113v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110"><image x="5" y="3" width="14" height="14" xlink:href="github"/> <text x="365" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="270">label</text><text x="365" y="140" transform="scale(.1)" textLength="270">label</text><text x="825" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="490">message</text><text x="825" y="140" transform="scale(.1)" textLength="490">message</text></g> </svg>
`
exports['The badge generator badges with logos should always produce the same badge simple-icons javascript logo default color (#F7DF1E) 1'] = `
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="113" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="a"><rect width="113" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#a)"><path fill="#555" d="M0 0h54v20H0z"/><path fill="#4c1" d="M54 0h59v20H54z"/><path fill="url(#b)" d="M0 0h113v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110"><image x="5" y="3" width="14" height="14" xlink:href="javascript"/> <text x="365" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="270">label</text><text x="365" y="140" transform="scale(.1)" textLength="270">label</text><text x="825" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="490">message</text><text x="825" y="140" transform="scale(.1)" textLength="490">message</text></g> </svg>
exports['The badge generator badges with logos should always produce the same badge shields GitHub logo default color (#333333) 1'] = `
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="113" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="a"><rect width="113" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#a)"><path fill="#555" d="M0 0h54v20H0z"/><path fill="#4c1" d="M54 0h59v20H54z"/><path fill="url(#b)" d="M0 0h113v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110"><image x="5" y="3" width="14" height="14" xlink:href="github"/> <text x="365" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="270">label</text><text x="365" y="140" transform="scale(.1)" textLength="270">label</text><text x="825" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="490">message</text><text x="825" y="140" transform="scale(.1)" textLength="490">message</text></g> </svg>
`
exports['The badge generator badges with logos should always produce the same badge simple-icons javascript logo custom color (rgba(46,204,113,0.8)) 1'] = `
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="113" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="a"><rect width="113" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#a)"><path fill="#555" d="M0 0h54v20H0z"/><path fill="#4c1" d="M54 0h59v20H54z"/><path fill="url(#b)" d="M0 0h113v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110"><image x="5" y="3" width="14" height="14" xlink:href="javascript"/> <text x="365" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="270">label</text><text x="365" y="140" transform="scale(.1)" textLength="270">label</text><text x="825" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="490">message</text><text x="825" y="140" transform="scale(.1)" textLength="490">message</text></g> </svg>
`
exports['The badge generator badges with logos should always produce the same badge simple-icons javascript logo default color (#F7DF1E) 1'] = `
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="113" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="a"><rect width="113" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#a)"><path fill="#555" d="M0 0h54v20H0z"/><path fill="#4c1" d="M54 0h59v20H54z"/><path fill="url(#b)" d="M0 0h113v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110"><image x="5" y="3" width="14" height="14" xlink:href="javascript"/> <text x="365" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="270">label</text><text x="365" y="140" transform="scale(.1)" textLength="270">label</text><text x="825" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="490">message</text><text x="825" y="140" transform="scale(.1)" textLength="490">message</text></g> </svg>
`

View File

@@ -1,19 +1,18 @@
{
"name": "Shields",
"description": "Concise, consistent, and legible badges in SVG and raster format.",
"keywords": [
"badge",
"github",
"svg",
"status"
],
"keywords": ["badge", "github", "svg", "status"],
"website": "https://shields.io/",
"repository": "https://github.com/badges/shields",
"logo": "http://shields.io/favicon.png",
"env": {
"NPM_CONFIG_PRODUCTION": {
"description": "Configure whether devDependencies are installed (they are needed for the build).",
"value": "false"
"WHEELMAP_TOKEN": {
"description": "Configure the token to be used for the Wheelmap service.",
"required": false
},
"GH_TOKEN": {
"description": "Configure the token to be used for the GitHub services.",
"required": false
}
},
"formation": {

View File

@@ -0,0 +1,64 @@
public:
bind:
address: 'BIND_ADDRESS'
port: 'PORT'
metrics:
prometheus:
enabled: 'METRICS_PROMETHEUS_ENABLED'
ssl:
isSecure: 'HTTPS'
key: 'HTTPS_KEY'
cert: 'HTTPS_CRT'
redirectUri: 'REDIRECT_URI'
cors:
allowedOrigin:
__name: 'ALLOWED_ORIGIN'
__format: 'json'
persistence:
dir: 'PERSISTENCE_DIR'
redisUrl: 'REDIS_URL'
services:
github:
baseUri: 'GITHUB_URL'
debug:
enabled: 'GITHUB_DEBUG_ENABLED'
intervalSeconds: 'GITHUB_DEBUG_INTERVAL_SECONDS'
trace: 'TRACE_SERVICES'
profiling:
makeBadge: 'PROFILE_MAKE_BADGE'
cacheHeaders:
defaultCacheLengthSeconds: 'BADGE_MAX_AGE_SECONDS'
rateLimit: 'RATE_LIMIT'
fetchLimit: 'FETCH_LIMIT'
private:
azure_devops_token: 'AZURE_DEVOPS_TOKEN'
bintray_user: 'BINTRAY_USER'
bintray_apikey: 'BINTRAY_API_KEY'
drone_token: 'DRONE_TOKEN'
gh_client_id: 'GH_CLIENT_ID'
gh_client_secret: 'GH_CLIENT_SECRET'
gh_token: 'GH_TOKEN'
jenkins_user: 'JENKINS_USER'
jenkins_pass: 'JENKINS_PASS'
jira_user: 'JIRA_USER'
jira_pass: 'JIRA_PASS'
nexus_user: 'NEXUS_USER'
nexus_pass: 'NEXUS_PASS'
npm_token: 'NPM_TOKEN'
sentry_dsn: 'SENTRY_DSN'
shields_secret: 'SHIELDS_SECRET'
sl_insight_userUuid: 'SL_INSIGHT_USER_UUID'
sl_insight_apiToken: 'SL_INSIGHT_API_TOKEN'
sonarqube_token: 'SONARQUBE_TOKEN'
wheelmap_token: 'WHEELMAP_TOKEN'

38
config/default.yml Normal file
View File

@@ -0,0 +1,38 @@
public:
bind:
address: '::'
metrics:
prometheus:
enabled: false
ssl:
isSecure: false
cors:
allowedOrigin: []
persistence:
dir: './private'
services:
github:
baseUri: 'https://api.github.com/'
debug:
enabled: false
intervalSeconds: 200
trace: false
profiling:
makeBadge: false
cacheHeaders:
defaultCacheLengthSeconds: 120
rateLimit: true
handleInternalErrors: true
fetchLimit: '10MB'
private: {}

10
config/development.yml Normal file
View File

@@ -0,0 +1,10 @@
public:
bind:
address: 'localhost'
cors:
allowedOrigin: ['http://localhost:3000']
rateLimit: false
handleInternalErrors: false

View File

@@ -0,0 +1,10 @@
private:
bintray_user: ...
bintray_apikey: ...
gh_client_id: ...
gh_client_secret: ...
sentry_dsn: ...
shields_secret: ...
sl_insight_userUuid: ...
sl_insight_apiToken: ...
wheelmap_token: ...

View File

@@ -0,0 +1,8 @@
# Copy this file to `config/local.yml` and fill it in! It will be gitignored.
private:
# The possible values are documented in `doc/server-secrets.md`. Note that
# you can also set these values through environment variables, which may be
# preferable for self hosting.
gh_token: '...'
wheelmap_token: '...'

3
config/production.yml Normal file
View File

@@ -0,0 +1,3 @@
public:
bind:
address: '0.0.0.0'

View File

@@ -0,0 +1,16 @@
public:
metrics:
prometheus:
enabled: true
ssl:
isSecure: true
cors:
allowedOrigin: ['http://shields.io', 'https://shields.io']
redirectUrl: 'https://shields.io/'
private:
# These are not really private; they should be moved to `public`.
shields_ips: ['192.99.59.72', '51.254.114.150', '149.56.96.133']

10
config/test.yml Normal file
View File

@@ -0,0 +1,10 @@
public:
bind:
address: 'localhost'
port: 1111
rateLimit: false
redirectUrl: 'http://badge-server.example.com'
handleInternalErrors: false

View File

@@ -0,0 +1,144 @@
'use strict'
const queryString = require('query-string')
const pathToRegexp = require('path-to-regexp')
function badgeUrlFromPath({
baseUrl = '',
path,
queryParams,
style,
format = 'svg',
longCache = false,
}) {
const outExt = format.length ? `.${format}` : ''
const outQueryString = queryString.stringify({
cacheSeconds: longCache ? '2592000' : undefined,
style,
...queryParams,
})
const suffix = outQueryString ? `?${outQueryString}` : ''
return `${baseUrl}${path}${outExt}${suffix}`
}
function badgeUrlFromPattern({
baseUrl = '',
pattern,
namedParams,
queryParams,
style,
format = 'svg',
longCache = false,
}) {
const toPath = pathToRegexp.compile(pattern, {
strict: true,
sensitive: true,
})
const path = toPath(namedParams)
return badgeUrlFromPath({
baseUrl,
path,
queryParams,
style,
format,
longCache,
})
}
function encodeField(s) {
return encodeURIComponent(s.replace(/-/g, '--').replace(/_/g, '__'))
}
function staticBadgeUrl({
baseUrl = '',
label,
message,
color = 'lightgray',
style,
namedLogo,
format = 'svg',
}) {
const path = [label, message, color].map(encodeField).join('-')
const outQueryString = queryString.stringify({
style,
logo: namedLogo,
})
const suffix = outQueryString ? `?${outQueryString}` : ''
return `${baseUrl}/badge/${path}.${format}${suffix}`
}
function queryStringStaticBadgeUrl({
baseUrl = '',
label,
message,
color,
labelColor,
style,
namedLogo,
logoColor,
logoWidth,
logoPosition,
format = 'svg',
}) {
// schemaVersion could be a parameter if we iterate on it,
// for now it's hardcoded to the only supported version.
const schemaVersion = '1'
const suffix = `?${queryString.stringify({
label,
message,
color,
labelColor,
style,
logo: namedLogo,
logoColor,
logoWidth,
logoPosition,
})}`
return `${baseUrl}/static/v${schemaVersion}.${format}${suffix}`
}
function dynamicBadgeUrl({
baseUrl,
datatype,
label,
dataUrl,
query,
prefix,
suffix,
color,
style,
format = 'svg',
}) {
const queryParams = {
label,
url: dataUrl,
query,
style,
}
if (color) {
queryParams.color = color
}
if (prefix) {
queryParams.prefix = prefix
}
if (suffix) {
queryParams.suffix = suffix
}
const outQueryString = queryString.stringify(queryParams)
return `${baseUrl}/badge/dynamic/${datatype}.${format}?${outQueryString}`
}
module.exports = {
badgeUrlFromPath,
badgeUrlFromPattern,
encodeField,
staticBadgeUrl,
queryStringStaticBadgeUrl,
dynamicBadgeUrl,
}

View File

@@ -0,0 +1,159 @@
'use strict'
const { test, given } = require('sazerac')
const {
badgeUrlFromPath,
badgeUrlFromPattern,
encodeField,
staticBadgeUrl,
queryStringStaticBadgeUrl,
dynamicBadgeUrl,
} = require('./make-badge-url')
describe('Badge URL generation functions', function() {
test(badgeUrlFromPath, () => {
given({
baseUrl: 'http://example.com',
path: '/npm/v/gh-badges',
style: 'flat-square',
longCache: true,
}).expect(
'http://example.com/npm/v/gh-badges.svg?cacheSeconds=2592000&style=flat-square'
)
})
test(badgeUrlFromPattern, () => {
given({
baseUrl: 'http://example.com',
pattern: '/npm/v/:packageName',
namedParams: { packageName: 'gh-badges' },
style: 'flat-square',
longCache: true,
}).expect(
'http://example.com/npm/v/gh-badges.svg?cacheSeconds=2592000&style=flat-square'
)
})
test(encodeField, () => {
given('foo').expect('foo')
given('').expect('')
given('happy go lucky').expect('happy%20go%20lucky')
given('do-right').expect('do--right')
given('it_is_a_snake').expect('it__is__a__snake')
})
test(staticBadgeUrl, () => {
given({
label: 'foo',
message: 'bar',
color: 'blue',
style: 'flat-square',
}).expect('/badge/foo-bar-blue.svg?style=flat-square')
given({
label: 'foo',
message: 'bar',
color: 'blue',
style: 'flat-square',
format: 'png',
namedLogo: 'github',
}).expect('/badge/foo-bar-blue.png?logo=github&style=flat-square')
given({
label: 'Hello World',
message: 'Привет Мир',
color: '#aabbcc',
}).expect(
'/badge/Hello%20World-%D0%9F%D1%80%D0%B8%D0%B2%D0%B5%D1%82%20%D0%9C%D0%B8%D1%80-%23aabbcc.svg'
)
given({
label: '123-123',
message: 'abc-abc',
color: 'blue',
}).expect('/badge/123--123-abc--abc-blue.svg')
given({
label: '123-123',
message: '',
color: 'blue',
style: 'social',
}).expect('/badge/123--123--blue.svg?style=social')
given({
label: '',
message: 'blue',
color: 'blue',
}).expect('/badge/-blue-blue.svg')
})
test(queryStringStaticBadgeUrl, () => {
// the query-string library sorts parameters by name
given({
label: 'foo',
message: 'bar',
color: 'blue',
style: 'flat-square',
}).expect(
'/static/v1.svg?color=blue&label=foo&message=bar&style=flat-square'
)
given({
label: 'foo Bar',
message: 'bar Baz',
color: 'blue',
style: 'flat-square',
format: 'png',
namedLogo: 'github',
}).expect(
'/static/v1.png?color=blue&label=foo%20Bar&logo=github&message=bar%20Baz&style=flat-square'
)
given({
label: 'Hello World',
message: 'Привет Мир',
color: '#aabbcc',
}).expect(
'/static/v1.svg?color=%23aabbcc&label=Hello%20World&message=%D0%9F%D1%80%D0%B8%D0%B2%D0%B5%D1%82%20%D0%9C%D0%B8%D1%80'
)
})
test(dynamicBadgeUrl, () => {
const dataUrl = 'http://example.com/foo.json'
const query = '$.bar'
const prefix = 'value: '
given({
baseUrl: 'http://img.example.com',
datatype: 'json',
label: 'foo',
dataUrl,
query,
prefix,
style: 'plastic',
}).expect(
[
'http://img.example.com/badge/dynamic/json.svg',
'?label=foo',
`&prefix=${encodeURIComponent(prefix)}`,
`&query=${encodeURIComponent(query)}`,
'&style=plastic',
`&url=${encodeURIComponent(dataUrl)}`,
].join('')
)
const suffix = '<- value'
const color = 'blue'
given({
baseUrl: 'http://img.example.com',
datatype: 'json',
label: 'foo',
dataUrl,
query,
suffix,
color,
style: 'plastic',
}).expect(
[
'http://img.example.com/badge/dynamic/json.svg',
'?color=blue',
'&label=foo',
`&query=${encodeURIComponent(query)}`,
'&style=plastic',
`&suffix=${encodeURIComponent(suffix)}`,
`&url=${encodeURIComponent(dataUrl)}`,
].join('')
)
})
})

View File

@@ -16,15 +16,6 @@ function escapeFormat(t) {
)
}
function escapeFormatSlashes(t) {
return (
escapeFormat(t)
// Double slash
.replace(/\/\//g, '/')
)
}
module.exports = {
escapeFormat,
escapeFormatSlashes,
}

View File

@@ -7,8 +7,25 @@ const trace = require('./trace')
const { InvalidResponse } = require('./errors')
class BaseJsonService extends BaseService {
async _requestJson({ schema, url, options = {}, errorMessages = {} }) {
_parseJson(buffer) {
const logTrace = (...args) => trace.logTrace('fetch', ...args)
let json
try {
json = JSON.parse(buffer)
} catch (err) {
logTrace(emojic.dart, 'Response JSON (unparseable)', buffer)
throw new InvalidResponse({
prettyMessage: 'unparseable json response',
underlyingError: err,
})
}
logTrace(emojic.dart, 'Response JSON (before validation)', json, {
deep: true,
})
return json
}
async _requestJson({ schema, url, options = {}, errorMessages = {} }) {
const mergedOptions = {
...{ headers: { Accept: 'application/json' } },
...options,
@@ -18,19 +35,7 @@ class BaseJsonService extends BaseService {
options: mergedOptions,
errorMessages,
})
let json
try {
json = JSON.parse(buffer)
} catch (err) {
logTrace(emojic.dart, 'Response JSON (unparseable)', json)
throw new InvalidResponse({
prettyMessage: 'unparseable json response',
underlyingError: err,
})
}
logTrace(emojic.dart, 'Response JSON (before validation)', json, {
deep: true,
})
const json = this._parseJson(buffer)
return this.constructor._validate(json, schema)
}
}

View File

@@ -1,14 +1,10 @@
'use strict'
const Joi = require('joi')
const chai = require('chai')
const { expect } = chai
const { expect } = require('chai')
const sinon = require('sinon')
const BaseJsonService = require('./base-json')
chai.use(require('chai-as-promised'))
const dummySchema = Joi.object({
requiredString: Joi.string().required(),
}).required()
@@ -35,7 +31,7 @@ class DummyJsonService extends BaseJsonService {
describe('BaseJsonService', function() {
describe('Making requests', function() {
let sendAndCacheRequest, serviceInstance
let sendAndCacheRequest
beforeEach(function() {
sendAndCacheRequest = sinon.stub().returns(
Promise.resolve({
@@ -43,25 +39,22 @@ describe('BaseJsonService', function() {
res: { statusCode: 200 },
})
)
serviceInstance = new DummyJsonService(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
})
it('invokes _sendAndCacheRequest', async function() {
await serviceInstance.invokeHandler({}, {})
await DummyJsonService.invoke(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
expect(sendAndCacheRequest).to.have.been.calledOnceWith(
'http://example.com/foo.json',
{
headers: { Accept: 'application/json' },
}
{ headers: { Accept: 'application/json' } }
)
})
it('forwards options to _sendAndCacheRequest', async function() {
Object.assign(serviceInstance, {
class WithOptions extends DummyJsonService {
async handle() {
const { value } = await this._requestJson({
schema: dummySchema,
@@ -69,10 +62,13 @@ describe('BaseJsonService', function() {
options: { method: 'POST', qs: { queryParam: 123 } },
})
return { message: value }
},
})
}
}
await serviceInstance.invokeHandler({}, {})
await WithOptions.invoke(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
expect(sendAndCacheRequest).to.have.been.calledOnceWith(
'http://example.com/foo.json',
@@ -91,12 +87,12 @@ describe('BaseJsonService', function() {
buffer: '{"requiredString": "some-string"}',
res: { statusCode: 200 },
})
const serviceInstance = new DummyJsonService(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
const serviceData = await serviceInstance.invokeHandler({}, {})
expect(serviceData).to.deep.equal({
expect(
await DummyJsonService.invoke(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
).to.deep.equal({
message: 'some-string',
})
})
@@ -106,12 +102,13 @@ describe('BaseJsonService', function() {
buffer: '{"unexpectedKey": "some-string"}',
res: { statusCode: 200 },
})
const serviceInstance = new DummyJsonService(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
const serviceData = await serviceInstance.invokeHandler({}, {})
expect(serviceData).to.deep.equal({
expect(
await DummyJsonService.invoke(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
).to.deep.equal({
isError: true,
color: 'lightgray',
message: 'invalid response data',
})
@@ -122,12 +119,13 @@ describe('BaseJsonService', function() {
buffer: 'not json',
res: { statusCode: 200 },
})
const serviceInstance = new DummyJsonService(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
const serviceData = await serviceInstance.invokeHandler({}, {})
expect(serviceData).to.deep.equal({
expect(
await DummyJsonService.invoke(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
).to.deep.equal({
isError: true,
color: 'lightgray',
message: 'unparseable json response',
})

View File

@@ -0,0 +1,70 @@
'use strict'
const makeBadge = require('../../gh-badges/lib/make-badge')
const BaseService = require('./base')
const { setCacheHeaders } = require('./cache-headers')
const { makeSend } = require('./legacy-result-sender')
const coalesceBadge = require('./coalesce-badge')
const { prepareRoute, namedParamsForMatch } = require('./route')
// Badges are subject to two independent types of caching: in-memory and
// downstream.
//
// Services deriving from `NonMemoryCachingBaseService` are not cached in
// memory on the server. This means that each request that hits the server
// triggers another call to the handler. When using badges for server
// diagnostics, that's useful!
//
// In contrast, The `handle()` function of most other `BaseService`
// subclasses is wrapped in onboard, in-memory caching. See `lib /request-
// handler.js` and `BaseService.prototype.register()`.
//
// All services, including those extending NonMemoryCachingBaseServices, may
// be cached _downstream_. This is governed by cache headers, which are
// configured by the service, the user's request, and the server's default
// cache length.
module.exports = class NonMemoryCachingBaseService extends BaseService {
static register({ camp, requestCounter }, serviceConfig) {
const { cacheHeaders: cacheHeaderConfig } = serviceConfig
const { _cacheLength: serviceDefaultCacheLengthSeconds } = this
const { regex, captureNames } = prepareRoute(this.route)
const serviceRequestCounter = this._createServiceRequestCounter({
requestCounter,
})
camp.route(regex, async (queryParams, match, end, ask) => {
const namedParams = namedParamsForMatch(captureNames, match, this)
const serviceData = await this.invoke(
{},
serviceConfig,
namedParams,
queryParams
)
const badgeData = coalesceBadge(
queryParams,
serviceData,
this.defaultBadgeData,
this
)
// The final capture group is the extension.
const format = match.slice(-1)[0]
badgeData.format = format
const svg = makeBadge(badgeData)
setCacheHeaders({
cacheHeaderConfig,
serviceDefaultCacheLengthSeconds,
queryParams,
res: ask.res,
})
makeSend(format, ask.res, end)(svg)
serviceRequestCounter.inc()
})
}
}

View File

@@ -0,0 +1,66 @@
'use strict'
const makeBadge = require('../../gh-badges/lib/make-badge')
const BaseService = require('./base')
const {
serverHasBeenUpSinceResourceCached,
setCacheHeadersForStaticResource,
} = require('./cache-headers')
const { makeSend } = require('./legacy-result-sender')
const coalesceBadge = require('./coalesce-badge')
const { prepareRoute, namedParamsForMatch } = require('./route')
module.exports = class BaseStaticService extends BaseService {
static register({ camp, requestCounter }, serviceConfig) {
const {
profiling: { makeBadge: shouldProfileMakeBadge },
} = serviceConfig
const { regex, captureNames } = prepareRoute(this.route)
const serviceRequestCounter = this._createServiceRequestCounter({
requestCounter,
})
camp.route(regex, async (queryParams, match, end, ask) => {
if (serverHasBeenUpSinceResourceCached(ask.req)) {
// Send Not Modified.
ask.res.statusCode = 304
ask.res.end()
return
}
const namedParams = namedParamsForMatch(captureNames, match, this)
const serviceData = await this.invoke(
{},
serviceConfig,
namedParams,
queryParams
)
const badgeData = coalesceBadge(
queryParams,
serviceData,
this.defaultBadgeData,
this
)
// The final capture group is the extension.
const format = match.slice(-1)[0]
badgeData.format = format
if (shouldProfileMakeBadge) {
console.time('makeBadge total')
}
const svg = makeBadge(badgeData)
if (shouldProfileMakeBadge) {
console.timeEnd('makeBadge total')
}
setCacheHeadersForStaticResource(ask.res)
makeSend(format, ask.res, end)(svg)
serviceRequestCounter.inc()
})
}
}

View File

@@ -12,7 +12,7 @@ const leadingWhitespace = /(?:\r\n\s*|\r\s*|\n\s*)/g
class BaseSvgScrapingService extends BaseService {
static valueFromSvgBadge(svg, valueMatcher = defaultValueMatcher) {
if (typeof svg !== 'string') {
throw TypeError('Parameter should be a string')
throw new TypeError('Parameter should be a string')
}
const stripped = svg.replace(leadingWhitespace, '')
const match = valueMatcher.exec(stripped)

View File

@@ -1,19 +1,13 @@
'use strict'
const chai = require('chai')
const { expect } = require('chai')
const sinon = require('sinon')
const Joi = require('joi')
const { makeBadgeData } = require('../lib/badge-data')
const makeBadge = require('../gh-badges/lib/make-badge')
const makeBadge = require('../../gh-badges/lib/make-badge')
const BaseSvgScrapingService = require('./base-svg-scraping')
chai.use(require('chai-as-promised'))
function makeExampleSvg({ label, message }) {
const badgeData = makeBadgeData('this is the label', {})
badgeData.text[1] = 'this is the result!'
return makeBadge(badgeData)
return makeBadge({ text: ['this is the label', 'this is the result!'] })
}
const schema = Joi.object({
@@ -56,7 +50,7 @@ describe('BaseSvgScrapingService', function() {
})
describe('Making requests', function() {
let sendAndCacheRequest, serviceInstance
let sendAndCacheRequest
beforeEach(function() {
sendAndCacheRequest = sinon.stub().returns(
Promise.resolve({
@@ -64,27 +58,24 @@ describe('BaseSvgScrapingService', function() {
res: { statusCode: 200 },
})
)
serviceInstance = new DummySvgScrapingService(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
})
it('invokes _sendAndCacheRequest with the expected header', async function() {
await serviceInstance.invokeHandler({}, {})
await DummySvgScrapingService.invoke(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
expect(sendAndCacheRequest).to.have.been.calledOnceWith(
'http://example.com/foo.svg',
{
headers: { Accept: 'image/svg+xml' },
}
{ headers: { Accept: 'image/svg+xml' } }
)
})
it('forwards options to _sendAndCacheRequest', async function() {
Object.assign(serviceInstance, {
class WithCustomOptions extends DummySvgScrapingService {
async handle() {
const { value } = await this._requestSvg({
const { message } = await this._requestSvg({
schema,
url: 'http://example.com/foo.svg',
options: {
@@ -92,11 +83,14 @@ describe('BaseSvgScrapingService', function() {
qs: { queryParam: 123 },
},
})
return { message: value }
},
})
return { message }
}
}
await serviceInstance.invokeHandler({}, {})
await WithCustomOptions.invoke(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
expect(sendAndCacheRequest).to.have.been.calledOnceWith(
'http://example.com/foo.svg',
@@ -115,36 +109,40 @@ describe('BaseSvgScrapingService', function() {
buffer: exampleSvg,
res: { statusCode: 200 },
})
const serviceInstance = new DummySvgScrapingService(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
const serviceData = await serviceInstance.invokeHandler({}, {})
expect(serviceData).to.deep.equal({
expect(
await DummySvgScrapingService.invoke(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
).to.deep.equal({
message: exampleMessage,
})
})
it('allows overriding the valueMatcher', async function() {
const sendAndCacheRequest = async () => ({
buffer: '<desc>a different message</desc>',
res: { statusCode: 200 },
})
const serviceInstance = new DummySvgScrapingService(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
Object.assign(serviceInstance, {
class WithValueMatcher extends BaseSvgScrapingService {
static get route() {
return {}
}
async handle() {
return this._requestSvg({
schema,
valueMatcher: />([^<>]+)<\/desc>/,
url: 'http://example.com/foo.svg',
})
},
}
}
const sendAndCacheRequest = async () => ({
buffer: '<desc>a different message</desc>',
res: { statusCode: 200 },
})
const serviceData = await serviceInstance.invokeHandler({}, {})
expect(serviceData).to.deep.equal({
expect(
await WithValueMatcher.invoke(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
).to.deep.equal({
message: 'a different message',
})
})
@@ -154,12 +152,13 @@ describe('BaseSvgScrapingService', function() {
buffer: 'not svg yo',
res: { statusCode: 200 },
})
const serviceInstance = new DummySvgScrapingService(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
const serviceData = await serviceInstance.invokeHandler({}, {})
expect(serviceData).to.deep.equal({
expect(
await DummySvgScrapingService.invoke(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
).to.deep.equal({
isError: true,
color: 'lightgray',
message: 'unparseable svg response',
})

View File

@@ -1,14 +1,10 @@
'use strict'
const Joi = require('joi')
const chai = require('chai')
const { expect } = chai
const { expect } = require('chai')
const sinon = require('sinon')
const BaseXmlService = require('./base-xml')
chai.use(require('chai-as-promised'))
const dummySchema = Joi.object({
requiredString: Joi.string().required(),
}).required()
@@ -35,7 +31,7 @@ class DummyXmlService extends BaseXmlService {
describe('BaseXmlService', function() {
describe('Making requests', function() {
let sendAndCacheRequest, serviceInstance
let sendAndCacheRequest
beforeEach(function() {
sendAndCacheRequest = sinon.stub().returns(
Promise.resolve({
@@ -43,36 +39,40 @@ describe('BaseXmlService', function() {
res: { statusCode: 200 },
})
)
serviceInstance = new DummyXmlService(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
})
it('invokes _sendAndCacheRequest', async function() {
await serviceInstance.invokeHandler({}, {})
await DummyXmlService.invoke(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
expect(sendAndCacheRequest).to.have.been.calledOnceWith(
'http://example.com/foo.xml',
{
headers: { Accept: 'application/xml, text/xml' },
}
{ headers: { Accept: 'application/xml, text/xml' } }
)
})
it('forwards options to _sendAndCacheRequest', async function() {
Object.assign(serviceInstance, {
class WithCustomOptions extends BaseXmlService {
static get route() {
return {}
}
async handle() {
const { value } = await this._requestXml({
const { requiredString } = await this._requestXml({
schema: dummySchema,
url: 'http://example.com/foo.xml',
options: { method: 'POST', qs: { queryParam: 123 } },
})
return { message: value }
},
})
return { message: requiredString }
}
}
await serviceInstance.invokeHandler({}, {})
await WithCustomOptions.invoke(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
expect(sendAndCacheRequest).to.have.been.calledOnceWith(
'http://example.com/foo.xml',
@@ -91,12 +91,12 @@ describe('BaseXmlService', function() {
buffer: '<requiredString>some-string</requiredString>',
res: { statusCode: 200 },
})
const serviceInstance = new DummyXmlService(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
const serviceData = await serviceInstance.invokeHandler({}, {})
expect(serviceData).to.deep.equal({
expect(
await DummyXmlService.invoke(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
).to.deep.equal({
message: 'some-string',
})
})
@@ -118,14 +118,12 @@ describe('BaseXmlService', function() {
'<requiredString>some-string with trailing whitespace </requiredString>',
res: { statusCode: 200 },
})
const serviceInstance = new DummyXmlServiceWithParserOption(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
const serviceData = await serviceInstance.invokeHandler({}, {})
expect(serviceData).to.deep.equal({
expect(
await DummyXmlServiceWithParserOption.invoke(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
).to.deep.equal({
message: 'some-string with trailing whitespace ',
})
})
@@ -135,12 +133,13 @@ describe('BaseXmlService', function() {
buffer: '<unexpectedAttribute>some-string</unexpectedAttribute>',
res: { statusCode: 200 },
})
const serviceInstance = new DummyXmlService(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
const serviceData = await serviceInstance.invokeHandler({}, {})
expect(serviceData).to.deep.equal({
expect(
await DummyXmlService.invoke(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
).to.deep.equal({
isError: true,
color: 'lightgray',
message: 'invalid response data',
})
@@ -151,12 +150,13 @@ describe('BaseXmlService', function() {
buffer: 'not xml',
res: { statusCode: 200 },
})
const serviceInstance = new DummyXmlService(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
const serviceData = await serviceInstance.invokeHandler({}, {})
expect(serviceData).to.deep.equal({
expect(
await DummyXmlService.invoke(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
).to.deep.equal({
isError: true,
color: 'lightgray',
message: 'unparseable xml response',
})

View File

@@ -0,0 +1,49 @@
'use strict'
const emojic = require('emojic')
const yaml = require('js-yaml')
const BaseService = require('./base')
const { InvalidResponse } = require('./errors')
const trace = require('./trace')
class BaseYamlService extends BaseService {
async _requestYaml({
schema,
url,
options = {},
errorMessages = {},
encoding = 'utf8',
}) {
const logTrace = (...args) => trace.logTrace('fetch', ...args)
const mergedOptions = {
...{
headers: {
Accept:
'text/x-yaml, text/yaml, application/x-yaml, application/yaml, text/plain',
},
},
...options,
}
const { buffer } = await this._request({
url,
options: mergedOptions,
errorMessages,
})
let parsed
try {
parsed = yaml.safeLoad(buffer.toString(), encoding)
} catch (err) {
logTrace(emojic.dart, 'Response YAML (unparseable)', buffer)
throw new InvalidResponse({
prettyMessage: 'unparseable yaml response',
underlyingError: err,
})
}
logTrace(emojic.dart, 'Response YAML (before validation)', parsed, {
deep: true,
})
return this.constructor._validate(parsed, schema)
}
}
module.exports = BaseYamlService

View File

@@ -0,0 +1,158 @@
'use strict'
const Joi = require('joi')
const { expect } = require('chai')
const sinon = require('sinon')
const BaseYamlService = require('./base-yaml')
const dummySchema = Joi.object({
requiredString: Joi.string().required(),
}).required()
class DummyYamlService extends BaseYamlService {
static get category() {
return 'cat'
}
static get route() {
return {
base: 'foo',
}
}
async handle() {
const { requiredString } = await this._requestYaml({
schema: dummySchema,
url: 'http://example.com/foo.yaml',
})
return { message: requiredString }
}
}
const expectedYaml = `
---
requiredString: some-string
`
const unexpectedYaml = `
---
unexpectedKey: some-string
`
const invalidYaml = `
---
foo: bar
foo: baz
`
describe('BaseYamlService', function() {
describe('Making requests', function() {
let sendAndCacheRequest
beforeEach(function() {
sendAndCacheRequest = sinon.stub().returns(
Promise.resolve({
buffer: expectedYaml,
res: { statusCode: 200 },
})
)
})
it('invokes _sendAndCacheRequest', async function() {
await DummyYamlService.invoke(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
expect(sendAndCacheRequest).to.have.been.calledOnceWith(
'http://example.com/foo.yaml',
{
headers: {
Accept:
'text/x-yaml, text/yaml, application/x-yaml, application/yaml, text/plain',
},
}
)
})
it('forwards options to _sendAndCacheRequest', async function() {
class WithOptions extends DummyYamlService {
async handle() {
const { requiredString } = await this._requestYaml({
schema: dummySchema,
url: 'http://example.com/foo.yaml',
options: { method: 'POST', qs: { queryParam: 123 } },
})
return { message: requiredString }
}
}
await WithOptions.invoke(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
expect(sendAndCacheRequest).to.have.been.calledOnceWith(
'http://example.com/foo.yaml',
{
headers: {
Accept:
'text/x-yaml, text/yaml, application/x-yaml, application/yaml, text/plain',
},
method: 'POST',
qs: { queryParam: 123 },
}
)
})
})
describe('Making badges', function() {
it('handles valid yaml responses', async function() {
const sendAndCacheRequest = async () => ({
buffer: expectedYaml,
res: { statusCode: 200 },
})
expect(
await DummyYamlService.invoke(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
).to.deep.equal({
message: 'some-string',
})
})
it('handles yaml responses which do not match the schema', async function() {
const sendAndCacheRequest = async () => ({
buffer: unexpectedYaml,
res: { statusCode: 200 },
})
expect(
await DummyYamlService.invoke(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
).to.deep.equal({
isError: true,
color: 'lightgray',
message: 'invalid response data',
})
})
it('handles unparseable yaml responses', async function() {
const sendAndCacheRequest = async () => ({
buffer: invalidYaml,
res: { statusCode: 200 },
})
expect(
await DummyYamlService.invoke(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
).to.deep.equal({
isError: true,
color: 'lightgray',
message: 'unparseable yaml response',
})
})
})
})

424
core/base-service/base.js Normal file
View File

@@ -0,0 +1,424 @@
'use strict'
const decamelize = require('decamelize')
// See available emoji at http://emoji.muan.co/
const emojic = require('emojic')
const Joi = require('joi')
const { assertValidCategory } = require('./categories')
const checkErrorResponse = require('./check-error-response')
const coalesceBadge = require('./coalesce-badge')
const {
NotFound,
InvalidResponse,
Inaccessible,
InvalidParameter,
Deprecated,
} = require('./errors')
const { validateExample, transformExample } = require('./examples')
const {
makeFullUrl,
assertValidRoute,
prepareRoute,
namedParamsForMatch,
getQueryParamNames,
} = require('./route')
const { assertValidServiceDefinition } = require('./service-definitions')
const trace = require('./trace')
const validate = require('./validate')
const defaultBadgeDataSchema = Joi.object({
label: Joi.string(),
color: Joi.string(),
labelColor: Joi.string(),
namedLogo: Joi.string(),
}).required()
const optionalStringWhenNamedLogoPrsent = Joi.alternatives().when('namedLogo', {
is: Joi.string().required(),
then: Joi.string(),
})
const optionalNumberWhenAnyLogoPresent = Joi.alternatives()
.when('namedLogo', { is: Joi.string().required(), then: Joi.number() })
.when('logoSvg', { is: Joi.string().required(), then: Joi.number() })
const serviceDataSchema = Joi.object({
isError: Joi.boolean(),
label: Joi.string().allow(''),
// While a number of badges pass a number here, in the long run we may want
// `render()` to always return a string.
message: Joi.alternatives(Joi.string().allow(''), Joi.number()).required(),
color: Joi.string(),
link: Joi.array()
.items(Joi.string().uri())
.single()
.max(2),
// Generally services should not use these options, which are provided to
// support the Endpoint badge.
labelColor: Joi.string(),
namedLogo: Joi.string(),
logoSvg: Joi.string(),
logoColor: optionalStringWhenNamedLogoPrsent,
logoWidth: optionalNumberWhenAnyLogoPresent,
logoPosition: optionalNumberWhenAnyLogoPresent,
cacheSeconds: Joi.number()
.integer()
.min(0),
style: Joi.string(),
})
.oxor('namedLogo', 'logoSvg')
.required()
module.exports = class BaseService {
/**
* Name of the category to sort this badge into (eg. "build"). Used to sort
* the badges on the main shields.io website.
*/
static get category() {
throw new Error(`Category not set for ${this.name}`)
}
static get isDeprecated() {
return false
}
/**
* Returns an object:
* - base: (Optional) The base path of the routes for this service. This is
* used as a prefix.
* - format: Regular expression to use for routes for this service's badges
* - capture: Array of names for the capture groups in the regular
* expression. The handler will be passed an object containing
* the matches.
* - queryParamSchema: (Optional) A Joi schema (`Joi.object({ ... }).required()`)
* for the query param object. If you know a parameter
* will never receive a numeric string, you can use
* `Joi.string()`. Because of quirks in Scoutcamp and Joi,
* alphanumeric strings should be declared using
* `Joi.alternatives().try(Joi.string(), Joi.number())`,
* otherwise a value like `?success_color=999` will fail.
* A parameter requiring a numeric string can use
* `Joi.number()`. A parameter that receives only non-numeric
* strings can use `Joi.string()`. A parameter that never
* receives numeric can use `Joi.string()`. A boolean
* parameter should use `Joi.equal('')` and will receive an
* empty string on e.g. `?compact_message` and undefined
* when the parameter is absent. (Note that in,
* `examples.queryParams` boolean query params should be given
* `null` values.)
*/
static get route() {
throw new Error(`Route not defined for ${this.name}`)
}
/**
* Example URLs for this service. These should use the format
* specified in `route`, and can be used to demonstrate how to use badges for
* this service.
*
* The preferred way to specify an example is with `namedParams` which are
* substituted into the service's compiled route pattern. The rendered badge
* is specified with `staticPreview`.
*
* For services which use a route `format`, the `pattern` can be specified as
* part of the example.
*
* title: Descriptive text that will be shown next to the badge. The default
* is to use the service class name, which probably is not what you want.
* namedParams: An object containing the values of named parameters to
* substitute into the compiled route pattern.
* queryParams: An object containing query parameters to include in the
* example URLs. For alphanumeric query parameters, specify a string value.
* For boolean query parameters, specify `null`.
* pattern: The route pattern to compile. Defaults to `this.route.pattern`.
* staticPreview: A rendered badge of the sort returned by `handle()` or
* `render()`: an object containing `message` and optional `label` and
* `color`. This is usually generated by invoking `this.render()` with some
* explicit props.
* keywords: Additional keywords, other than words in the title. This helps
* users locate relevant badges.
* documentation: An HTML string that is included in the badge popup.
*/
static get examples() {
return []
}
static get _cacheLength() {
const cacheLengths = {
build: 30,
license: 3600,
version: 300,
debug: 60,
}
return cacheLengths[this.category]
}
/**
* Default data for the badge. Can include label, logo, and color. These
* defaults are used if the value is neither included in the service data
* from the handler nor overridden by the user via query parameters.
*/
static get defaultBadgeData() {
return {}
}
static render(props) {
throw new Error(`render() function not implemented for ${this.name}`)
}
static validateDefinition() {
assertValidCategory(this.category, `Category for ${this.name}`)
assertValidRoute(this.route, `Route for ${this.name}`)
Joi.assert(
this.defaultBadgeData,
defaultBadgeDataSchema,
`Default badge data for ${this.name}`
)
this.examples.forEach((example, index) =>
validateExample(example, index, this)
)
}
static getDefinition() {
const { category, name, isDeprecated } = this
const { base, format, pattern } = this.route
const queryParams = getQueryParamNames(this.route)
const examples = this.examples.map((example, index) =>
transformExample(example, index, this)
)
let route
if (pattern) {
route = { pattern: makeFullUrl(base, pattern), queryParams }
} else if (format) {
route = { format, queryParams }
} else {
route = undefined
}
const result = { category, name, isDeprecated, route, examples }
assertValidServiceDefinition(result, `getDefinition() for ${this.name}`)
return result
}
constructor({ sendAndCacheRequest }, { handleInternalErrors }) {
this._requestFetcher = sendAndCacheRequest
this._handleInternalErrors = handleInternalErrors
}
async _request({ url, options = {}, errorMessages = {} }) {
const logTrace = (...args) => trace.logTrace('fetch', ...args)
logTrace(emojic.bowAndArrow, 'Request', url, '\n', options)
const { res, buffer } = await this._requestFetcher(url, options)
logTrace(emojic.dart, 'Response status code', res.statusCode)
return checkErrorResponse(errorMessages)({ buffer, res })
}
static _validate(
data,
schema,
{
prettyErrorMessage = 'invalid response data',
includeKeys = false,
allowAndStripUnknownKeys = true,
} = {}
) {
return validate(
{
ErrorClass: InvalidResponse,
prettyErrorMessage,
includeKeys,
traceErrorMessage: 'Response did not match schema',
traceSuccessMessage: 'Response after validation',
allowAndStripUnknownKeys,
},
data,
schema
)
}
/**
* Asynchronous function to handle requests for this service. Take the route
* parameters (as defined in the `route` property), perform a request using
* `this._sendAndCacheRequest`, and return the badge data.
*/
async handle(namedParams, queryParams) {
throw new Error(`Handler not implemented for ${this.constructor.name}`)
}
_handleError(error) {
if (error instanceof NotFound || error instanceof InvalidParameter) {
trace.logTrace('outbound', emojic.noGoodWoman, 'Handled error', error)
return {
isError: true,
message: error.prettyMessage,
color: 'red',
}
} else if (
error instanceof InvalidResponse ||
error instanceof Inaccessible ||
error instanceof Deprecated
) {
trace.logTrace('outbound', emojic.noGoodWoman, 'Handled error', error)
return {
isError: true,
message: error.prettyMessage,
color: 'lightgray',
}
} else if (this._handleInternalErrors) {
if (
!trace.logTrace(
'unhandledError',
emojic.boom,
'Unhandled internal error',
error
)
) {
// This is where we end up if an unhandled exception is thrown in
// production. Send the error to the logs.
console.log(error)
}
return {
isError: true,
label: 'shields',
message: 'internal error',
color: 'lightgray',
}
} else {
trace.logTrace(
'unhandledError',
emojic.boom,
'Unhandled internal error',
error
)
throw error
}
}
static async invoke(
context = {},
config = {},
namedParams = {},
queryParams = {}
) {
trace.logTrace('inbound', emojic.womanCook, 'Service class', this.name)
trace.logTrace('inbound', emojic.ticket, 'Named params', namedParams)
trace.logTrace('inbound', emojic.crayon, 'Query params', queryParams)
const serviceInstance = new this(context, config)
let serviceError
const { queryParamSchema } = this.route
let transformedQueryParams
if (queryParamSchema) {
try {
transformedQueryParams = validate(
{
ErrorClass: InvalidParameter,
prettyErrorMessage: 'invalid query parameter',
includeKeys: true,
traceErrorMessage: 'Query params did not match schema',
traceSuccessMessage: 'Query params after validation',
},
queryParams,
queryParamSchema
)
trace.logTrace(
'inbound',
emojic.crayon,
'Query params after validation',
queryParams
)
} catch (error) {
serviceError = error
}
} else {
transformedQueryParams = {}
}
let serviceData
if (!serviceError) {
try {
serviceData = await serviceInstance.handle(
namedParams,
transformedQueryParams
)
Joi.assert(serviceData, serviceDataSchema)
} catch (error) {
serviceError = error
}
}
if (serviceError) {
serviceData = serviceInstance._handleError(serviceError)
}
trace.logTrace('outbound', emojic.shield, 'Service data', serviceData)
return serviceData
}
static _createServiceRequestCounter({ requestCounter }) {
if (requestCounter) {
const { category, serviceFamily, name } = this
const service = decamelize(name)
return requestCounter.labels(category, serviceFamily, service)
} else {
// When metrics are disabled, return a mock counter.
return { inc: () => {} }
}
}
static register(
{ camp, handleRequest, githubApiProvider, requestCounter },
serviceConfig
) {
const { cacheHeaders: cacheHeaderConfig, fetchLimitBytes } = serviceConfig
const { regex, captureNames } = prepareRoute(this.route)
const queryParams = getQueryParamNames(this.route)
const serviceRequestCounter = this._createServiceRequestCounter({
requestCounter,
})
camp.route(
regex,
handleRequest(cacheHeaderConfig, {
queryParams,
handler: async (queryParams, match, sendBadge, request) => {
const namedParams = namedParamsForMatch(captureNames, match, this)
const serviceData = await this.invoke(
{
sendAndCacheRequest: request.asPromise,
sendAndCacheRequestWithCallbacks: request,
githubApiProvider,
},
serviceConfig,
namedParams,
queryParams
)
const badgeData = coalesceBadge(
queryParams,
serviceData,
this.defaultBadgeData,
this
)
// The final capture group is the extension.
const format = match.slice(-1)[0]
sendBadge(format, badgeData)
serviceRequestCounter.inc()
},
cacheLength: this._cacheLength,
fetchLimitBytes,
})
)
}
}

View File

@@ -0,0 +1,485 @@
'use strict'
const Joi = require('joi')
const { expect } = require('chai')
const sinon = require('sinon')
const trace = require('./trace')
const {
NotFound,
Inaccessible,
InvalidResponse,
InvalidParameter,
Deprecated,
} = require('./errors')
const BaseService = require('./base')
require('../register-chai-plugins.spec')
const queryParamSchema = Joi.object({
queryParamA: Joi.string(),
})
.rename('legacyQueryParamA', 'queryParamA', {
ignoreUndefined: true,
override: true,
})
.required()
class DummyService extends BaseService {
static get category() {
return 'other'
}
static get route() {
return {
base: 'foo',
pattern: ':namedParamA',
queryParamSchema,
}
}
static get examples() {
return [
{
pattern: ':world',
namedParams: { world: 'World' },
staticPreview: this.render({ namedParamA: 'foo', queryParamA: 'bar' }),
keywords: ['hello'],
},
]
}
static get defaultBadgeData() {
return { label: 'cat', namedLogo: 'appveyor' }
}
static render({ namedParamA, queryParamA }) {
return {
message: `Hello namedParamA: ${namedParamA} with queryParamA: ${queryParamA}`,
}
}
async handle({ namedParamA }, { queryParamA }) {
return this.constructor.render({ namedParamA, queryParamA })
}
}
describe('BaseService', function() {
const defaultConfig = { handleInternalErrors: false }
it('Invokes the handler as expected', async function() {
expect(
await DummyService.invoke(
{},
defaultConfig,
{ namedParamA: 'bar.bar.bar' },
{ queryParamA: '!' }
)
).to.deep.equal({
message: 'Hello namedParamA: bar.bar.bar with queryParamA: !',
})
})
it('Validates query params', async function() {
expect(
await DummyService.invoke(
{},
defaultConfig,
{ namedParamA: 'bar.bar.bar' },
{ queryParamA: ['foo', 'bar'] }
)
).to.deep.equal({
color: 'red',
isError: true,
message: 'invalid query parameter: queryParamA',
})
})
describe('Required overrides', function() {
it('Should throw if render() is not overridden', function() {
expect(() => BaseService.render()).to.throw(
'render() function not implemented for BaseService'
)
})
it('Should throw if route is not overridden', async function() {
try {
await BaseService.invoke({}, {}, {})
expect.fail('Expected to throw')
} catch (e) {
expect(e.message).to.equal('Route not defined for BaseService')
}
})
class WithRoute extends BaseService {
static get route() {
return {}
}
}
it('Should throw if handle() is not overridden', async function() {
try {
await WithRoute.invoke({}, {}, {})
expect.fail('Expected to throw')
} catch (e) {
expect(e.message).to.equal('Handler not implemented for WithRoute')
}
})
it('Should throw if category is not overridden', function() {
expect(() => BaseService.category).to.throw(
'Category not set for BaseService'
)
})
})
describe('Logging', function() {
let sandbox
beforeEach(function() {
sandbox = sinon.createSandbox()
})
afterEach(function() {
sandbox.restore()
})
beforeEach(function() {
sandbox.stub(trace, 'logTrace')
})
it('Invokes the logger as expected', async function() {
await DummyService.invoke(
{},
defaultConfig,
{ namedParamA: 'bar.bar.bar' },
{ queryParamA: '!' }
)
expect(trace.logTrace).to.be.calledWithMatch(
'inbound',
sinon.match.string,
'Service class',
'DummyService'
)
expect(trace.logTrace).to.be.calledWith(
'inbound',
sinon.match.string,
'Named params',
{ namedParamA: 'bar.bar.bar' }
)
expect(trace.logTrace).to.be.calledWith(
'inbound',
sinon.match.string,
'Query params after validation',
{ queryParamA: '!' }
)
})
})
describe('Service data validation', function() {
it('Allows a link array', async function() {
const message = 'hello'
const link = ['https://example.com/', 'https://other.example.com/']
class LinkService extends DummyService {
async handle() {
return { message, link }
}
}
const serviceData = await LinkService.invoke(
{},
{ handleInternalErrors: false },
{ namedParamA: 'bar.bar.bar' }
)
expect(serviceData).to.deep.equal({
message,
link,
})
})
it('Throws a validation error on invalid data', async function() {
class ThrowingService extends DummyService {
async handle() {
return {
some: 'nonsense',
}
}
}
try {
await ThrowingService.invoke(
{},
{ handleInternalErrors: false },
{ namedParamA: 'bar.bar.bar' }
)
expect.fail('Expected to throw')
} catch (e) {
expect(e.name).to.equal('ValidationError')
expect(e.details.map(({ message }) => message)).to.deep.equal([
'"message" is required',
])
}
})
})
describe('Error handling', function() {
it('Handles internal errors', async function() {
class ThrowingService extends DummyService {
async handle() {
throw Error("I've made a huge mistake")
}
}
expect(
await ThrowingService.invoke(
{},
{ handleInternalErrors: true },
{ namedParamA: 'bar.bar.bar' }
)
).to.deep.equal({
isError: true,
color: 'lightgray',
label: 'shields',
message: 'internal error',
})
})
describe('Handles known subtypes of ShieldsInternalError', function() {
it('handles NotFound errors', async function() {
class ThrowingService extends DummyService {
async handle() {
throw new NotFound()
}
}
expect(
await ThrowingService.invoke({}, {}, { namedParamA: 'bar.bar.bar' })
).to.deep.equal({
isError: true,
color: 'red',
message: 'not found',
})
})
it('handles Inaccessible errors', async function() {
class ThrowingService extends DummyService {
async handle() {
throw new Inaccessible()
}
}
expect(
await ThrowingService.invoke({}, {}, { namedParamA: 'bar.bar.bar' })
).to.deep.equal({
isError: true,
color: 'lightgray',
message: 'inaccessible',
})
})
it('handles InvalidResponse errors', async function() {
class ThrowingService extends DummyService {
async handle() {
throw new InvalidResponse()
}
}
expect(
await ThrowingService.invoke({}, {}, { namedParamA: 'bar.bar.bar' })
).to.deep.equal({
isError: true,
color: 'lightgray',
message: 'invalid',
})
})
it('handles Deprecated', async function() {
class ThrowingService extends DummyService {
async handle() {
throw new Deprecated()
}
}
expect(
await ThrowingService.invoke({}, {}, { namedParamA: 'bar.bar.bar' })
).to.deep.equal({
isError: true,
color: 'lightgray',
message: 'no longer available',
})
})
it('handles InvalidParameter errors', async function() {
class ThrowingService extends DummyService {
async handle() {
throw new InvalidParameter()
}
}
expect(
await ThrowingService.invoke({}, {}, { namedParamA: 'bar.bar.bar' })
).to.deep.equal({
isError: true,
color: 'red',
message: 'invalid parameter',
})
})
})
})
describe('ScoutCamp integration', function() {
const expectedRouteRegex = /^\/foo\/([^/]+?)\.(svg|png|gif|jpg|json)$/
let mockCamp
let mockHandleRequest
beforeEach(function() {
mockCamp = {
route: sinon.spy(),
}
mockHandleRequest = sinon.spy()
DummyService.register(
{ camp: mockCamp, handleRequest: mockHandleRequest },
defaultConfig
)
})
it('registers the service', function() {
expect(mockCamp.route).to.have.been.calledOnce
expect(mockCamp.route).to.have.been.calledWith(expectedRouteRegex)
})
it('handles the request', async function() {
expect(mockHandleRequest).to.have.been.calledOnce
const {
queryParams: serviceQueryParams,
handler: requestHandler,
} = mockHandleRequest.getCall(0).args[1]
expect(serviceQueryParams).to.deep.equal([
'queryParamA',
'legacyQueryParamA',
])
const mockSendBadge = sinon.spy()
const mockRequest = {
asPromise: sinon.spy(),
}
const queryParams = { queryParamA: '?' }
const match = '/foo/bar.svg'.match(expectedRouteRegex)
await requestHandler(queryParams, match, mockSendBadge, mockRequest)
const expectedFormat = 'svg'
expect(mockSendBadge).to.have.been.calledOnce
expect(mockSendBadge).to.have.been.calledWith(expectedFormat, {
text: ['cat', 'Hello namedParamA: bar with queryParamA: ?'],
color: 'lightgrey',
template: undefined,
namedLogo: undefined,
logo: undefined,
logoWidth: undefined,
logoPosition: undefined,
links: [],
labelColor: undefined,
cacheLengthSeconds: undefined,
})
})
})
describe('getDefinition', function() {
it('returns the expected result', function() {
const {
category,
name,
isDeprecated,
route,
examples,
} = DummyService.getDefinition()
expect({
category,
name,
isDeprecated,
route,
}).to.deep.equal({
category: 'other',
name: 'DummyService',
isDeprecated: false,
route: {
pattern: '/foo/:namedParamA',
queryParams: ['queryParamA', 'legacyQueryParamA'],
},
})
// The in-depth tests for examples reside in examples.spec.js
expect(examples).to.have.lengthOf(1)
})
})
describe('validate', function() {
const dummySchema = Joi.object({
requiredString: Joi.string().required(),
}).required()
it('throws error for invalid responses', async function() {
try {
DummyService._validate(
{ requiredString: ['this', "shouldn't", 'work'] },
dummySchema
)
expect.fail('Expected to throw')
} catch (e) {
expect(e).to.be.an.instanceof(InvalidResponse)
}
})
})
describe('request', function() {
let sandbox
beforeEach(function() {
sandbox = sinon.createSandbox()
})
afterEach(function() {
sandbox.restore()
})
beforeEach(function() {
sandbox.stub(trace, 'logTrace')
})
it('logs appropriate information', async function() {
const sendAndCacheRequest = async () => ({
buffer: '',
res: { statusCode: 200 },
})
const serviceInstance = new DummyService(
{ sendAndCacheRequest },
defaultConfig
)
const url = 'some-url'
const options = { headers: { Cookie: 'some-cookie' } }
await serviceInstance._request({ url, options })
expect(trace.logTrace).to.be.calledWithMatch(
'fetch',
sinon.match.string,
'Request',
url,
'\n',
options
)
expect(trace.logTrace).to.be.calledWithMatch(
'fetch',
sinon.match.string,
'Response status code',
200
)
})
it('handles errors', async function() {
const sendAndCacheRequest = async () => ({
buffer: '',
res: { statusCode: 404 },
})
const serviceInstance = new DummyService(
{ sendAndCacheRequest },
defaultConfig
)
try {
await serviceInstance._request({})
expect.fail('Expected to throw')
} catch (e) {
expect(e).to.be.an.instanceof(NotFound)
expect(e.message).to.equal('Not Found')
expect(e.prettyMessage).to.equal('not found')
}
})
})
})

View File

@@ -0,0 +1,115 @@
'use strict'
const assert = require('assert')
const Joi = require('joi')
const coalesce = require('./coalesce')
const serverStartTimeGMTString = new Date().toGMTString()
const serverStartTimestamp = Date.now()
const isOptionalNonNegativeInteger = Joi.number()
.integer()
.min(0)
const queryParamSchema = Joi.object({
cacheSeconds: isOptionalNonNegativeInteger,
maxAge: isOptionalNonNegativeInteger,
})
.oxor('cacheSeconds', 'maxAge')
.unknown(true)
.required()
function overrideCacheLengthFromQueryParams(queryParams) {
try {
const {
cacheSeconds: overrideCacheLength,
maxAge: legacyOverrideCacheLength,
} = Joi.attempt(queryParams, queryParamSchema)
return coalesce(overrideCacheLength, legacyOverrideCacheLength)
} catch (e) {
return undefined
}
}
function coalesceCacheLength({
cacheHeaderConfig,
serviceDefaultCacheLengthSeconds,
serviceOverrideCacheLengthSeconds,
queryParams,
}) {
const { defaultCacheLengthSeconds } = cacheHeaderConfig
// The config returns a number so this should never happen. But this logic
// would be completely broken if it did.
assert(defaultCacheLengthSeconds !== undefined)
const cacheLength = coalesce(
serviceDefaultCacheLengthSeconds,
defaultCacheLengthSeconds
)
// Overrides can apply _more_ caching, but not less. Query param overriding
// can request more overriding than service override, but not less.
const candidateOverrides = [
serviceOverrideCacheLengthSeconds,
overrideCacheLengthFromQueryParams(queryParams),
].filter(x => x !== undefined)
return Math.max(cacheLength, ...candidateOverrides)
}
function setHeadersForCacheLength(res, cacheLengthSeconds) {
const now = new Date()
const nowGMTString = now.toGMTString()
// Send both Cache-Control max-age and Expires in case the client implements
// HTTP/1.0 but not HTTP/1.1.
let cacheControl, expires
if (cacheLengthSeconds === 0) {
// Prevent as much downstream caching as possible.
cacheControl = 'no-cache, no-store, must-revalidate'
expires = nowGMTString
} else {
cacheControl = `max-age=${cacheLengthSeconds}`
expires = new Date(now.getTime() + cacheLengthSeconds * 1000).toGMTString()
}
res.setHeader('Date', nowGMTString)
res.setHeader('Cache-Control', cacheControl)
res.setHeader('Expires', expires)
}
function setCacheHeaders({
cacheHeaderConfig,
serviceDefaultCacheLengthSeconds,
serviceOverrideCacheLengthSeconds,
queryParams,
res,
}) {
const cacheLengthSeconds = coalesceCacheLength({
cacheHeaderConfig,
serviceDefaultCacheLengthSeconds,
serviceOverrideCacheLengthSeconds,
queryParams,
})
setHeadersForCacheLength(res, cacheLengthSeconds)
}
const staticCacheControlHeader = `max-age=${24 * 3600}` // 1 day.
function setCacheHeadersForStaticResource(res) {
res.setHeader('Cache-Control', staticCacheControlHeader)
res.setHeader('Last-Modified', serverStartTimeGMTString)
}
function serverHasBeenUpSinceResourceCached(req) {
return (
serverStartTimestamp <= new Date(req.headers['if-modified-since']).getTime()
)
}
module.exports = {
coalesceCacheLength,
setCacheHeaders,
setHeadersForCacheLength,
setCacheHeadersForStaticResource,
serverHasBeenUpSinceResourceCached,
}

View File

@@ -0,0 +1,241 @@
'use strict'
const { test, given } = require('sazerac')
const chai = require('chai')
const { expect } = require('chai')
const sinon = require('sinon')
const httpMocks = require('node-mocks-http')
const {
coalesceCacheLength,
setHeadersForCacheLength,
setCacheHeaders,
setCacheHeadersForStaticResource,
serverHasBeenUpSinceResourceCached,
} = require('./cache-headers')
chai.use(require('chai-datetime'))
describe('Cache header functions', function() {
let res
beforeEach(function() {
res = httpMocks.createResponse()
})
describe('coalesceCacheLength', function() {
const cacheHeaderConfig = { defaultCacheLengthSeconds: 777 }
test(coalesceCacheLength, () => {
given({ cacheHeaderConfig, queryParams: {} }).expect(777)
given({
cacheHeaderConfig,
serviceDefaultCacheLengthSeconds: 900,
queryParams: {},
}).expect(900)
given({
cacheHeaderConfig,
serviceDefaultCacheLengthSeconds: 900,
queryParams: { cacheSeconds: 1000 },
}).expect(1000)
given({
cacheHeaderConfig,
serviceDefaultCacheLengthSeconds: 900,
queryParams: { cacheSeconds: 1000, other: 'here', maybe: 'bogus' },
}).expect(1000)
given({
cacheHeaderConfig,
serviceDefaultCacheLengthSeconds: 900,
queryParams: { cacheSeconds: 400 },
}).expect(900)
given({
cacheHeaderConfig,
serviceDefaultCacheLengthSeconds: 900,
queryParams: { cacheSeconds: '-1000' },
}).expect(900)
given({
cacheHeaderConfig,
serviceDefaultCacheLengthSeconds: 900,
queryParams: { cacheSeconds: '' },
}).expect(900)
given({
cacheHeaderConfig,
serviceDefaultCacheLengthSeconds: 900,
queryParams: { cacheSeconds: 'not a number' },
}).expect(900)
given({
cacheHeaderConfig,
serviceDefaultCacheLengthSeconds: 900,
// Legacy name.
queryParams: { maxAge: 1000 },
}).expect(1000)
given({
cacheHeaderConfig,
serviceDefaultCacheLengthSeconds: 900,
// Both legacy and new name provided -> both ignored.
queryParams: { maxAge: 1000, cacheSeconds: 1000 },
}).expect(900)
given({
cacheHeaderConfig,
serviceDefaultCacheLengthSeconds: 900,
serviceOverrideCacheLengthSeconds: 400,
queryParams: {},
}).expect(900)
given({
cacheHeaderConfig,
serviceOverrideCacheLengthSeconds: 400,
queryParams: {},
}).expect(777)
given({
cacheHeaderConfig,
serviceOverrideCacheLengthSeconds: 900,
queryParams: {},
}).expect(900)
given({
cacheHeaderConfig,
serviceOverrideCacheLengthSeconds: 800,
queryParams: { cacheSeconds: 500 },
}).expect(800)
given({
cacheHeaderConfig,
serviceOverrideCacheLengthSeconds: 900,
queryParams: { cacheSeconds: 800 },
}).expect(900)
})
})
describe('setHeadersForCacheLength', function() {
let sandbox
beforeEach(function() {
sandbox = sinon.createSandbox()
sandbox.useFakeTimers()
})
afterEach(function() {
sandbox.restore()
sandbox = undefined
})
it('should set the correct Date header', function() {
// Confidence check.
expect(res._headers.date).to.equal(undefined)
// Act.
setHeadersForCacheLength(res, 123)
// Assert.
const now = new Date().toGMTString()
expect(res._headers.date).to.equal(now)
})
context('cacheLengthSeconds is zero', function() {
beforeEach(function() {
setHeadersForCacheLength(res, 0)
})
it('should set the expected Cache-Control header', function() {
expect(res._headers['cache-control']).to.equal(
'no-cache, no-store, must-revalidate'
)
})
it('should set the expected Expires header', function() {
expect(res._headers.expires).to.equal(new Date().toGMTString())
})
})
context('cacheLengthSeconds is nonzero', function() {
beforeEach(function() {
setHeadersForCacheLength(res, 123)
})
it('should set the expected Cache-Control header', function() {
expect(res._headers['cache-control']).to.equal('max-age=123')
})
it('should set the expected Expires header', function() {
const expires = new Date(Date.now() + 123 * 1000).toGMTString()
expect(res._headers.expires).to.equal(expires)
})
})
})
describe('setCacheHeaders', function() {
it('sets the expected fields', function() {
const expectedFields = ['date', 'cache-control', 'expires']
expectedFields.forEach(field =>
expect(res._headers[field]).to.equal(undefined)
)
setCacheHeaders({
cacheHeaderConfig: { defaultCacheLengthSeconds: 1234 },
serviceDefaultCacheLengthSeconds: 567,
queryParams: { cacheSeconds: 999999 },
res,
})
expectedFields.forEach(field =>
expect(res._headers[field])
.to.be.a('string')
.and.have.lengthOf.at.least(1)
)
})
})
describe('setCacheHeadersForStaticResource', function() {
beforeEach(function() {
setCacheHeadersForStaticResource(res)
})
it('should set the expected Cache-Control header', function() {
expect(res._headers['cache-control']).to.equal(`max-age=${24 * 3600}`)
})
it('should set the expected Last-Modified header', function() {
const lastModified = res._headers['last-modified']
expect(new Date(lastModified)).to.be.withinTime(
// Within the last 60 seconds.
new Date(Date.now() - 60 * 1000),
new Date()
)
})
})
describe('serverHasBeenUpSinceResourceCached', function() {
// The stringified req's are hard to understand. I thought Sazerac
// provided a way to override the describe message, though I can't find it.
context('when there is no If-Modified-Since header', function() {
it('returns false', function() {
const req = httpMocks.createRequest()
expect(serverHasBeenUpSinceResourceCached(req)).to.equal(false)
})
})
context('when the If-Modified-Since header is invalid', function() {
it('returns false', function() {
const req = httpMocks.createRequest({
headers: { 'If-Modified-Since': 'this-is-not-a-date' },
})
expect(serverHasBeenUpSinceResourceCached(req)).to.equal(false)
})
})
context(
'when the If-Modified-Since header is before the process started',
function() {
it('returns false', function() {
const req = httpMocks.createRequest({
headers: { 'If-Modified-Since': '2018-02-01T05:00:00.000Z' },
})
expect(serverHasBeenUpSinceResourceCached(req)).to.equal(false)
})
}
)
context(
'when the If-Modified-Since header is after the process started',
function() {
it('returns true', function() {
const modifiedTimeStamp = new Date(Date.now() + 1800000)
const req = httpMocks.createRequest({
headers: { 'If-Modified-Since': modifiedTimeStamp.toISOString() },
})
expect(serverHasBeenUpSinceResourceCached(req)).to.equal(true)
})
}
)
})
})

View File

@@ -0,0 +1,19 @@
'use strict'
const Joi = require('joi')
const categories = require('../../services/categories')
const isRealCategory = Joi.equal(categories.map(({ id }) => id)).required()
const isValidCategory = Joi.alternatives()
.try(isRealCategory, Joi.equal('debug', 'dynamic', 'static').required())
.required()
function assertValidCategory(category, message = undefined) {
Joi.assert(category, isValidCategory, message)
}
module.exports = {
isValidCategory,
assertValidCategory,
}

View File

@@ -0,0 +1,37 @@
'use strict'
const { NotFound, InvalidResponse, Inaccessible } = require('./errors')
const defaultErrorMessages = {
404: 'not found',
}
module.exports = function checkErrorResponse(errorMessages = {}) {
return async function({ buffer, res }) {
let error
errorMessages = { ...defaultErrorMessages, ...errorMessages }
if (res.statusCode === 404) {
error = new NotFound({ prettyMessage: errorMessages[404] })
} else if (res.statusCode !== 200) {
const underlying = Error(
`Got status code ${res.statusCode} (expected 200)`
)
const props = { underlyingError: underlying }
if (errorMessages[res.statusCode] !== undefined) {
props.prettyMessage = errorMessages[res.statusCode]
}
if (res.statusCode >= 500) {
error = new Inaccessible(props)
} else {
error = new InvalidResponse(props)
}
}
if (error) {
error.response = res
error.buffer = buffer
throw error
} else {
return { buffer, res }
}
}
}

View File

@@ -1,82 +1,43 @@
'use strict'
const { expect } = require('chai')
const { checkErrorResponse } = require('./error-helper')
const {
NotFound,
InvalidResponse,
Inaccessible,
} = require('../services/errors')
describe('Standard Error Handler', function() {
it('makes inaccessible badge', function() {
const badgeData = { text: [] }
expect(checkErrorResponse(badgeData, 'something other than null', {})).to.be
.true
expect(badgeData.text[1]).to.equal('inaccessible')
expect(badgeData.colorscheme).to.equal('red')
})
it('makes not found badge', function() {
const badgeData = { text: [] }
expect(checkErrorResponse(badgeData, null, { statusCode: 404 })).to.be.true
expect(badgeData.text[1]).to.equal('not found')
expect(badgeData.colorscheme).to.equal('lightgrey')
})
it('makes not found badge with custom error', function() {
const badgeData = { text: [] }
expect(
checkErrorResponse(
badgeData,
null,
{ statusCode: 404 },
{ 404: 'custom message' }
)
).to.be.true
expect(badgeData.text[1]).to.equal('custom message')
expect(badgeData.colorscheme).to.equal('lightgrey')
})
it('makes invalid badge', function() {
const badgeData = { text: [] }
expect(checkErrorResponse(badgeData, null, { statusCode: 500 })).to.be.true
expect(badgeData.text[1]).to.equal('invalid')
expect(badgeData.colorscheme).to.equal('lightgrey')
})
it('return false on 200 status', function() {
expect(checkErrorResponse({ text: [] }, null, { statusCode: 200 })).to.be
.false
})
})
const { NotFound, InvalidResponse, Inaccessible } = require('./errors')
const checkErrorResponse = require('./check-error-response')
describe('async error handler', function() {
const buffer = Buffer.from('some stuff')
context('when status is 200', function() {
it('passes through the inputs', async function() {
const args = { buffer: 'buffer', res: { statusCode: 200 } }
expect(await checkErrorResponse.asPromise()(args)).to.deep.equal(args)
const res = { statusCode: 200 }
expect(await checkErrorResponse()({ res, buffer })).to.deep.equal({
res,
buffer,
})
})
})
context('when status is 404', function() {
const buffer = Buffer.from('some stuff')
const res = { statusCode: 404 }
it('throws NotFound', async function() {
try {
await checkErrorResponse.asPromise()({ res })
await checkErrorResponse()({ res, buffer })
expect.fail('Expected to throw')
} catch (e) {
expect(e).to.be.an.instanceof(NotFound)
expect(e.message).to.equal('Not Found')
expect(e.prettyMessage).to.equal('not found')
expect(e.response).to.equal(res)
expect(e.buffer).to.equal(buffer)
}
})
it('displays the custom not found message', async function() {
const notFoundMessage = 'no goblins found'
try {
await checkErrorResponse.asPromise({ 404: notFoundMessage })({ res })
await checkErrorResponse({ 404: notFoundMessage })({ res, buffer })
expect.fail('Expected to throw')
} catch (e) {
expect(e).to.be.an.instanceof(NotFound)
@@ -90,7 +51,7 @@ describe('async error handler', function() {
it('throws InvalidResponse', async function() {
const res = { statusCode: 499 }
try {
await checkErrorResponse.asPromise()({ res })
await checkErrorResponse()({ res, buffer })
expect.fail('Expected to throw')
} catch (e) {
expect(e).to.be.an.instanceof(InvalidResponse)
@@ -98,15 +59,15 @@ describe('async error handler', function() {
'Invalid Response: Got status code 499 (expected 200)'
)
expect(e.prettyMessage).to.equal('invalid')
expect(e.response).to.equal(res)
expect(e.buffer).to.equal(buffer)
}
})
it('displays the custom error message', async function() {
const res = { statusCode: 403 }
try {
await checkErrorResponse.asPromise({
403: 'access denied',
})({ res })
await checkErrorResponse({ 403: 'access denied' })({ res })
expect.fail('Expected to throw')
} catch (e) {
expect(e).to.be.an.instanceof(InvalidResponse)
@@ -122,7 +83,7 @@ describe('async error handler', function() {
it('throws Inaccessible', async function() {
const res = { statusCode: 503 }
try {
await checkErrorResponse.asPromise()({ res })
await checkErrorResponse()({ res, buffer })
expect.fail('Expected to throw')
} catch (e) {
expect(e).to.be.an.instanceof(Inaccessible)
@@ -130,15 +91,15 @@ describe('async error handler', function() {
'Inaccessible: Got status code 503 (expected 200)'
)
expect(e.prettyMessage).to.equal('inaccessible')
expect(e.response).to.equal(res)
expect(e.buffer).to.equal(buffer)
}
})
it('displays the custom error message', async function() {
const res = { statusCode: 500 }
try {
await checkErrorResponse.asPromise({
500: 'server overloaded',
})({ res })
await checkErrorResponse({ 500: 'server overloaded' })({ res, buffer })
expect.fail('Expected to throw')
} catch (e) {
expect(e).to.be.an.instanceof(Inaccessible)

View File

@@ -0,0 +1,174 @@
'use strict'
const {
decodeDataUrlFromQueryParam,
prepareNamedLogo,
} = require('../../lib/logos')
const { svg2base64 } = require('../../lib/svg-helpers')
const coalesce = require('./coalesce')
const toArray = require('./to-array')
// Translate modern badge data to the legacy schema understood by the badge
// maker. Allow the user to override the label, color, logo, etc. through the
// query string. Provide support for most badge options via `serviceData` so
// the Endpoint badge can specify logos and colors, though allow that the
// user's logo or color to take precedence. A notable exception is the case of
// errors. When the service specifies that an error has occurred, the user's
// requested color does not override the error color.
//
// Logos are resolved in this manner:
//
// 1. When `?logo=` contains the name of one of the Shields logos, or contains
// base64-encoded SVG, that logo is used. In the case of a named logo, when
// a `&logoColor=` is specified, that color is used. Otherwise the default
// color is used. `logoColor` will not be applied to a custom
// (base64-encoded) logo; if a custom color is desired the logo should be
// recolored prior to making the request. The appearance of the logo can be
// customized using `logoWidth`, and in the case of the popout badge,
// `logoPosition`. 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
// used only by the Endpoint badge. The `logoColor` can be overridden by the
// query string.
// 3. In the case of the `social` style only, the last precedence is the
// service's default logo. The `logoColor` can be overridden by the query
// string.
module.exports = function coalesceBadge(
overrides,
serviceData,
// These two parameters were kept separate to make tests clearer.
defaultBadgeData,
{ category, _cacheLength: defaultCacheSeconds } = {}
) {
// The "overrideX" naming is based on services that provide badge
// parameters themselves, which can be overridden by a query string
// parameter. (For a couple services, the dynamic badge and the
// query-string-based static badge, the service never sets a value
// so the query string overrides are the _only_ way to configure
// these badge parameters.
const {
style: overrideStyle,
label: overrideLabel,
logo: overrideLogo,
logoColor: overrideLogoColor,
link: overrideLink,
colorB: legacyOverrideColor,
colorA: legacyOverrideLabelColor,
} = overrides
let {
logoWidth: overrideLogoWidth,
logoPosition: overrideLogoPosition,
color: overrideColor,
labelColor: overrideLabelColor,
} = overrides
// Only use the legacy properties if the new ones are not provided
if (typeof overrideColor === 'undefined') {
overrideColor = legacyOverrideColor
}
if (typeof overrideLabelColor === 'undefined') {
overrideLabelColor = legacyOverrideLabelColor
}
// Scoutcamp converts numeric query params to numbers. Convert them back.
if (typeof overrideColor === 'number') {
overrideColor = `${overrideColor}`
}
if (typeof overrideLabelColor === 'number') {
overrideLabelColor = `${overrideLabelColor}`
}
overrideLogoWidth = +overrideLogoWidth || undefined
overrideLogoPosition = +overrideLogoPosition || undefined
const {
isError,
label: serviceLabel,
message: serviceMessage,
color: serviceColor,
labelColor: serviceLabelColor,
logoSvg: serviceLogoSvg,
namedLogo: serviceNamedLogo,
logoColor: serviceLogoColor,
logoWidth: serviceLogoWidth,
logoPosition: serviceLogoPosition,
link: serviceLink,
cacheSeconds: serviceCacheSeconds,
style: serviceStyle,
} = serviceData
const {
color: defaultColor,
namedLogo: defaultNamedLogo,
label: defaultLabel,
labelColor: defaultLabelColor,
} = defaultBadgeData
const style = coalesce(overrideStyle, serviceStyle)
let namedLogo, namedLogoColor, logoWidth, logoPosition, logoSvgBase64
if (overrideLogo) {
// `?logo=` could be a named logo or encoded svg.
const overrideLogoSvgBase64 = decodeDataUrlFromQueryParam(overrideLogo)
if (overrideLogoSvgBase64) {
logoSvgBase64 = overrideLogoSvgBase64
} else {
namedLogo = overrideLogo
// If the logo has been overridden it does not make sense to inherit the
// original color.
namedLogoColor = overrideLogoColor
}
// If the logo has been overridden it does not make sense to inherit the
// original width or position.
logoWidth = overrideLogoWidth
logoPosition = overrideLogoPosition
} else {
if (serviceLogoSvg) {
logoSvgBase64 = svg2base64(serviceLogoSvg)
} else {
namedLogo = coalesce(
serviceNamedLogo,
style === 'social' ? defaultNamedLogo : undefined
)
namedLogoColor = coalesce(overrideLogoColor, serviceLogoColor)
}
logoWidth = coalesce(overrideLogoWidth, serviceLogoWidth)
logoPosition = coalesce(overrideLogoPosition, serviceLogoPosition)
}
if (namedLogo) {
logoSvgBase64 = prepareNamedLogo({
name: namedLogo,
color: namedLogoColor,
style,
})
}
return {
text: [
// Use `coalesce()` to support empty labels and messages, as in the
// static badge.
coalesce(overrideLabel, serviceLabel, defaultLabel, category),
coalesce(serviceMessage, 'n/a'),
],
color: coalesce(
// In case of an error, disregard user's color override.
isError ? undefined : overrideColor,
serviceColor,
defaultColor,
'lightgrey'
),
labelColor: coalesce(
// In case of an error, disregard user's color override.
isError ? undefined : overrideLabelColor,
serviceLabelColor,
defaultLabelColor
),
template: style,
namedLogo,
logo: logoSvgBase64,
logoWidth,
logoPosition,
links: toArray(overrideLink || serviceLink),
cacheLengthSeconds: coalesce(serviceCacheSeconds, defaultCacheSeconds),
}
}

View File

@@ -0,0 +1,294 @@
'use strict'
const { expect } = require('chai')
const { getShieldsIcon, getSimpleIcon } = require('../../lib/logos')
const coalesceBadge = require('./coalesce-badge')
describe('coalesceBadge', function() {
describe('Label', function() {
it('uses the default label', function() {
expect(coalesceBadge({}, {}, { label: 'heyo' }).text).to.deep.equal([
'heyo',
'n/a',
])
})
// This behavior isn't great and we might want to remove it.
it('uses the category as a default label', function() {
expect(coalesceBadge({}, {}, {}, { category: 'cat' }).text).to.deep.equal(
['cat', 'n/a']
)
})
it('preserves an empty label', function() {
expect(
coalesceBadge({}, { label: '', message: '10k' }, {}).text
).to.deep.equal(['', '10k'])
})
it('overrides the label', function() {
expect(
coalesceBadge({ label: 'purr count' }, { label: 'purrs' }, {}).text
).to.deep.equal(['purr count', 'n/a'])
})
})
describe('Message', function() {
it('applies the service message', function() {
expect(coalesceBadge({}, { message: '10k' }, {}).text).to.deep.equal([
undefined,
'10k',
])
})
it('applies a numeric service message', function() {
// While a number of badges use this, in the long run we may want
// `render()` to always return a string.
expect(coalesceBadge({}, { message: 10 }, {}).text).to.deep.equal([
undefined,
10,
])
})
})
describe('Right color', function() {
it('uses the default color', function() {
expect(coalesceBadge({}, {}, {}).color).to.equal('lightgrey')
})
it('overrides the color', function() {
expect(
coalesceBadge({ color: '10ADED' }, { color: 'red' }, {}).color
).to.equal('10ADED')
// also expected for legacy name
expect(
coalesceBadge({ colorB: 'B0ADED' }, { color: 'red' }, {}).color
).to.equal('B0ADED')
})
context('In case of an error', function() {
it('does not override the color', function() {
expect(
coalesceBadge(
{ color: '10ADED' },
{ isError: true, color: 'lightgray' },
{}
).color
).to.equal('lightgray')
// also expected for legacy name
expect(
coalesceBadge(
{ colorB: 'B0ADED' },
{ isError: true, color: 'lightgray' },
{}
).color
).to.equal('lightgray')
})
})
it('applies the service color', function() {
expect(coalesceBadge({}, { color: 'red' }, {}).color).to.equal('red')
})
})
describe('Left color', function() {
it('provides no default label color', function() {
expect(coalesceBadge({}, {}, {}).labelColor).to.be.undefined
})
it('applies the service label color', function() {
expect(coalesceBadge({}, { labelColor: 'red' }, {}).labelColor).to.equal(
'red'
)
})
it('overrides the label color', function() {
expect(
coalesceBadge({ labelColor: '42f483' }, { color: 'green' }, {})
.labelColor
).to.equal('42f483')
// also expected for legacy name
expect(
coalesceBadge({ colorA: 'B2f483' }, { color: 'green' }, {}).labelColor
).to.equal('B2f483')
})
it('converts a query-string numeric color to a string', function() {
expect(
coalesceBadge(
// Scoutcamp converts numeric query params to numbers.
{ color: 123 },
{ color: 'green' },
{}
).color
).to.equal('123')
// also expected for legacy name
expect(
coalesceBadge(
// Scoutcamp converts numeric query params to numbers.
{ colorB: 123 },
{ color: 'green' },
{}
).color
).to.equal('123')
})
})
describe('Named logos', function() {
it('when not a social badge, ignores the default named logo', function() {
expect(coalesceBadge({}, {}, { namedLogo: 'appveyor' }).logo).to.be
.undefined
})
it('when a social badge, uses the default named logo', function() {
// .not.be.empty for confidence that nothing has changed with `getShieldsIcon()`.
expect(
coalesceBadge({ style: 'social' }, {}, { namedLogo: 'appveyor' }).logo
).to.equal(getSimpleIcon({ name: 'appveyor' })).and.not.be.empty
})
it('applies the named logo', function() {
expect(coalesceBadge({}, { namedLogo: 'npm' }, {}).namedLogo).to.equal(
'npm'
)
expect(coalesceBadge({}, { namedLogo: 'npm' }, {}).logo).to.equal(
getShieldsIcon({ name: 'npm' })
).and.not.to.be.empty
})
it('applies the named logo with color', function() {
expect(
coalesceBadge({}, { namedLogo: 'npm', logoColor: 'blue' }, {}).logo
).to.equal(getShieldsIcon({ name: 'npm', color: 'blue' })).and.not.to.be
.empty
})
it('overrides the logo', function() {
expect(
coalesceBadge({ logo: 'npm' }, { namedLogo: 'appveyor' }, {}).logo
).to.equal(getShieldsIcon({ name: 'npm' })).and.not.be.empty
})
it('overrides the logo with a color', function() {
expect(
coalesceBadge(
{ logo: 'npm', logoColor: 'blue' },
{ namedLogo: 'appveyor' },
{}
).logo
).to.equal(getShieldsIcon({ name: 'npm', color: 'blue' })).and.not.be
.empty
})
it("when the logo is overridden, it ignores the service's logo color, position, and width", function() {
expect(
coalesceBadge(
{ logo: 'npm' },
{
namedLogo: 'appveyor',
logoColor: 'red',
logoPosition: -3,
logoWidth: 100,
},
{}
).logo
).to.equal(getShieldsIcon({ name: 'npm' })).and.not.be.empty
})
it("overrides the service logo's color", function() {
expect(
coalesceBadge(
{ logoColor: 'blue' },
{ namedLogo: 'npm', logoColor: 'red' },
{}
).logo
).to.equal(getShieldsIcon({ name: 'npm', color: 'blue' })).and.not.be
.empty
})
// https://github.com/badges/shields/issues/2998
it('overrides logoSvg', function() {
const logoSvg = 'data:image/svg+xml;base64,PHN2ZyB4bWxu'
expect(coalesceBadge({ logo: 'npm' }, { logoSvg }, {}).logo).to.equal(
getShieldsIcon({ name: 'npm' })
).and.not.be.empty
})
})
describe('Custom logos', function() {
it('overrides the logo with custom svg', function() {
const logoSvg = 'data:image/svg+xml;base64,PHN2ZyB4bWxu'
expect(
coalesceBadge({ logo: logoSvg }, { namedLogo: 'appveyor' }, {}).logo
).to.equal(logoSvg)
})
it('ignores the color when custom svg is provided', function() {
const logoSvg = 'data:image/svg+xml;base64,PHN2ZyB4bWxu'
expect(
coalesceBadge(
{ logo: logoSvg, logoColor: 'brightgreen' },
{ namedLogo: 'appveyor' },
{}
).logo
).to.equal(logoSvg)
})
})
describe('Logo width', function() {
it('overrides the logoWidth', function() {
expect(coalesceBadge({ logoWidth: 20 }, {}, {}).logoWidth).to.equal(20)
})
it('applies the logo width', function() {
expect(
coalesceBadge({}, { namedLogo: 'npm', logoWidth: 275 }, {}).logoWidth
).to.equal(275)
})
})
describe('Logo position', function() {
it('overrides the logoPosition', function() {
expect(
coalesceBadge({ logoPosition: -10 }, {}, {}).logoPosition
).to.equal(-10)
})
it('applies the logo position', function() {
expect(
coalesceBadge({}, { namedLogo: 'npm', logoPosition: -10 }, {})
.logoPosition
).to.equal(-10)
})
})
describe('Links', function() {
it('overrides the links', function() {
expect(
coalesceBadge(
{ link: 'https://circleci.com/gh/badges/daily-tests' },
{
link:
'https://circleci.com/workflow-run/184ef3de-4836-4805-a2e4-0ceba099f92d',
},
{}
).links
).to.deep.equal(['https://circleci.com/gh/badges/daily-tests'])
})
})
describe('Style', function() {
it('overrides the template', function() {
expect(coalesceBadge({ style: 'pill' }, {}, {}).template).to.equal('pill')
})
})
describe('Cache length', function() {
it('overrides the cache length', function() {
expect(
coalesceBadge({ style: 'pill' }, { cacheSeconds: 123 }, {})
.cacheLengthSeconds
).to.equal(123)
})
})
})

View File

@@ -0,0 +1,5 @@
'use strict'
module.exports = function coalesce(...candidates) {
return candidates.find(c => c !== undefined && c !== null)
}

View File

@@ -0,0 +1,23 @@
'use strict'
const { test, given } = require('sazerac')
const coalesce = require('./coalesce')
// Sticking with our one-line spread implementation, and defaulting to
// `undefined` instead of `null`, though h/t to
// https://github.com/royriojas/coalescy for these tests!
describe('coalesce', function() {
test(coalesce, function() {
given().expect(undefined)
given(null, []).expect([])
given(null, [], {}).expect([])
given(null, undefined, 0, {}).expect(0)
const a = null,
c = 0,
d = 1
let b
given(a, b, c, d).expect(0)
})
})

View File

@@ -0,0 +1,63 @@
'use strict'
const Joi = require('joi')
const camelcase = require('camelcase')
const BaseService = require('./base')
const { isValidCategory } = require('./categories')
const { Deprecated } = require('./errors')
const { isValidRoute } = require('./route')
const attrSchema = Joi.object({
route: isValidRoute,
name: Joi.string(),
label: Joi.string(),
category: isValidCategory,
// The content of examples is validated later, via `transformExamples()`.
examples: Joi.array().default([]),
message: Joi.string(),
dateAdded: Joi.date().required(),
}).required()
function deprecatedService(attrs) {
const { route, name, label, category, examples, message } = Joi.attempt(
attrs,
attrSchema,
`Deprecated service for ${attrs.route.base}`
)
return class DeprecatedService extends BaseService {
static get name() {
return name
? `Deprecated${name}`
: `Deprecated${camelcase(route.base.replace(/\//g, '_'), {
pascalCase: true,
})}`
}
static get category() {
return category
}
static get isDeprecated() {
return true
}
static get route() {
return route
}
static get examples() {
return examples
}
static get defaultBadgeData() {
return { label }
}
async handle() {
throw new Deprecated({ prettyMessage: message })
}
}
}
module.exports = deprecatedService

View File

@@ -0,0 +1,69 @@
'use strict'
const { expect } = require('chai')
const deprecatedService = require('./deprecated-service')
describe('DeprecatedService', function() {
const route = {
base: 'service/that/no/longer/exists',
format: '(?:.+)',
}
const category = 'analysis'
const dateAdded = new Date()
const commonAttrs = { route, category, dateAdded }
it('returns true on isDeprecated', function() {
const service = deprecatedService({ ...commonAttrs })
expect(service.isDeprecated).to.be.true
})
it('has the expected name', function() {
const service = deprecatedService({ ...commonAttrs })
expect(service.name).to.equal('DeprecatedServiceThatNoLongerExists')
})
it('sets specified route', function() {
const service = deprecatedService({ ...commonAttrs })
expect(service.route).to.deep.equal(route)
})
it('sets specified label', function() {
const label = 'coverity'
const service = deprecatedService({ ...commonAttrs, label })
expect(service.defaultBadgeData.label).to.equal(label)
})
it('sets specified category', function() {
const service = deprecatedService({ ...commonAttrs })
expect(service.category).to.equal(category)
})
it('sets specified examples', function() {
const examples = [
{
title: 'Not sure we would have examples',
},
]
const service = deprecatedService({ ...commonAttrs, examples })
expect(service.examples).to.deep.equal(examples)
})
it('uses default deprecation message when no message specified', async function() {
const service = deprecatedService({ ...commonAttrs })
expect(await service.invoke()).to.deep.equal({
isError: true,
color: 'lightgray',
message: 'no longer available',
})
})
it('uses custom deprecation message when specified', async function() {
const message = 'extended outage'
const service = deprecatedService({ ...commonAttrs, message })
expect(await service.invoke()).to.deep.equal({
isError: true,
color: 'lightgray',
message,
})
})
})

View File

@@ -34,6 +34,7 @@ class NotFound extends ShieldsRuntimeError {
? 'Not Found'
: `Not Found: ${prettyMessage}`
super(props, message)
this.response = props.response
}
}
@@ -50,6 +51,7 @@ class InvalidResponse extends ShieldsRuntimeError {
? `Invalid Response: ${props.underlyingError.message}`
: 'Invalid Response'
super(props, message)
this.response = props.response
}
}
@@ -66,6 +68,7 @@ class Inaccessible extends ShieldsRuntimeError {
? `Inaccessible: ${props.underlyingError.message}`
: 'Inaccessible'
super(props, message)
this.response = props.response
}
}
@@ -82,6 +85,7 @@ class InvalidParameter extends ShieldsRuntimeError {
? `Invalid Parameter: ${props.underlyingError.message}`
: 'Invalid Parameter'
super(props, message)
this.response = props.response
}
}
@@ -100,6 +104,7 @@ class Deprecated extends ShieldsRuntimeError {
}
module.exports = {
ShieldsRuntimeError,
NotFound,
InvalidResponse,
Inaccessible,

View File

@@ -0,0 +1,169 @@
'use strict'
const Joi = require('joi')
const pathToRegexp = require('path-to-regexp')
const coalesceBadge = require('./coalesce-badge')
const { makeFullUrl } = require('./route')
const optionalObjectOfKeyValues = Joi.object().pattern(
/./,
Joi.string().allow(null)
)
const schema = Joi.object({
// This should be:
// title: Joi.string().required(),
title: Joi.string(),
namedParams: optionalObjectOfKeyValues.required(),
queryParams: optionalObjectOfKeyValues.default({}),
pattern: Joi.string(),
staticPreview: Joi.object({
label: Joi.string(),
message: Joi.alternatives()
.try(
Joi.string()
.allow('')
.required(),
Joi.number()
)
.required(),
color: Joi.string(),
style: Joi.string(),
}).required(),
keywords: Joi.array()
.items(Joi.string())
.default([]),
documentation: Joi.string(), // Valid HTML.
}).required()
function validateExample(example, index, ServiceClass) {
const result = Joi.attempt(
example,
schema,
`Example for ${ServiceClass.name} at index ${index}`
)
const { pattern, namedParams } = result
if (!pattern && !ServiceClass.route.pattern) {
throw new Error(
`Example for ${
ServiceClass.name
} at index ${index} does not declare a pattern`
)
}
if (pattern === ServiceClass.route.pattern) {
throw new Error(
`Example for ${
ServiceClass.name
} at index ${index} declares a redundant pattern which should be removed`
)
}
// Make sure we can build the full URL using these patterns.
try {
pathToRegexp.compile(pattern || ServiceClass.route.pattern)(namedParams)
} catch (e) {
throw Error(
`In example for ${
ServiceClass.name
} at index ${index}, ${e.message.toLowerCase()}`
)
}
// Make sure there are no extra keys.
let keys = []
pathToRegexp(pattern || ServiceClass.route.pattern, keys)
keys = keys.map(({ name }) => name)
const extraKeys = Object.keys(namedParams).filter(k => !keys.includes(k))
if (extraKeys.length) {
throw Error(
`In example for ${
ServiceClass.name
} at index ${index}, namedParams contains unknown keys: ${extraKeys.join(
', '
)}`
)
}
if (example.keywords) {
// Make sure the keywords are at least two characters long.
const tinyKeywords = example.keywords.filter(k => k.length < 2)
if (tinyKeywords.length) {
throw Error(
`In example for ${
ServiceClass.name
} at index ${index}, keywords contains words that are less than two characters long: ${tinyKeywords.join(
', '
)}`
)
}
// Make sure none of the keywords are already included in the title.
const title = (example.title || ServiceClass.name).toLowerCase()
const redundantKeywords = example.keywords.filter(k =>
title.includes(k.toLowerCase())
)
if (redundantKeywords.length) {
throw Error(
`In example for ${
ServiceClass.name
} at index ${index}, keywords contains words that are already in the title: ${redundantKeywords.join(
', '
)}`
)
}
}
return result
}
function transformExample(inExample, index, ServiceClass) {
const {
// We should get rid of this transform, since the class name is never what
// we want to see.
title = ServiceClass.name,
namedParams,
queryParams,
pattern,
staticPreview,
keywords,
documentation,
} = validateExample(inExample, index, ServiceClass)
const {
text: [label, message],
color,
template: style,
namedLogo,
} = coalesceBadge(
{},
staticPreview,
ServiceClass.defaultBadgeData,
ServiceClass
)
return {
title,
example: {
pattern: makeFullUrl(
ServiceClass.route.base,
pattern || ServiceClass.route.pattern
),
namedParams,
queryParams,
},
preview: {
label,
message: `${message}`,
color,
style: style === 'flat' ? undefined : style,
namedLogo,
},
keywords,
documentation: documentation ? { __html: documentation } : undefined,
}
}
module.exports = {
validateExample,
transformExample,
}

View File

@@ -0,0 +1,168 @@
'use strict'
const { expect } = require('chai')
const { test, given } = require('sazerac')
const { validateExample, transformExample } = require('./examples')
describe('validateExample function', function() {
it('passes valid examples', function() {
const validExamples = [
{
title: 'Package manager versioning badge',
staticPreview: { message: '123' },
pattern: 'dt/:package',
namedParams: { package: 'mypackage' },
keywords: ['semver', 'management'],
},
]
validExamples.forEach(example => {
expect(() =>
validateExample(example, 0, { route: {}, name: 'mockService' })
).not.to.throw(Error)
})
})
it('rejects invalid examples', function() {
const invalidExamples = [
{},
{ staticPreview: { message: '123' } },
{
staticPreview: { message: '123' },
pattern: 'dt/:package',
namedParams: { package: 'mypackage' },
exampleUrl: 'dt/mypackage',
},
{ staticPreview: { message: '123' }, pattern: 'dt/:package' },
{
staticPreview: { message: '123' },
pattern: 'dt/:package',
previewUrl: 'dt/mypackage',
},
{
staticPreview: { message: '123' },
pattern: 'dt/:package',
exampleUrl: 'dt/mypackage',
},
{ previewUrl: 'dt/mypackage' },
{
staticPreview: { message: '123' },
pattern: 'dt/:package',
namedParams: { package: 'mypackage' },
keywords: ['a'], // Keyword too short.
},
{
staticPreview: { message: '123' },
pattern: 'dt/:package',
namedParams: { package: 'mypackage' },
keywords: ['mockService'], // No title and keyword matching the class name.
},
{
title: 'Package manager versioning badge',
staticPreview: { message: '123' },
pattern: 'dt/:package',
namedParams: { package: 'mypackage' },
keywords: ['version'], // Keyword included in title.
},
]
invalidExamples.forEach(example => {
expect(() =>
validateExample(example, 0, { route: {}, name: 'mockService' })
).to.throw(Error)
})
})
})
test(transformExample, function() {
const ExampleService = {
name: 'ExampleService',
route: {
base: 'some-service',
pattern: ':interval/:packageName',
},
defaultBadgeData: {
label: 'downloads',
},
}
given(
{
pattern: 'dt/:packageName',
namedParams: { packageName: 'express' },
staticPreview: { message: '50k' },
keywords: ['hello'],
},
0,
ExampleService
).expect({
title: 'ExampleService',
example: {
pattern: '/some-service/dt/:packageName',
namedParams: { packageName: 'express' },
queryParams: {},
},
preview: {
label: 'downloads',
message: '50k',
color: 'lightgrey',
namedLogo: undefined,
style: undefined,
},
keywords: ['hello'],
documentation: undefined,
})
given(
{
namedParams: { interval: 'dt', packageName: 'express' },
staticPreview: { message: '50k' },
keywords: ['hello'],
},
0,
ExampleService
).expect({
title: 'ExampleService',
example: {
pattern: '/some-service/:interval/:packageName',
namedParams: { interval: 'dt', packageName: 'express' },
queryParams: {},
},
preview: {
label: 'downloads',
message: '50k',
color: 'lightgrey',
namedLogo: undefined,
style: undefined,
},
keywords: ['hello'],
documentation: undefined,
})
given(
{
namedParams: { interval: 'dt', packageName: 'express' },
queryParams: { registry_url: 'http://example.com/' },
staticPreview: { message: '50k' },
keywords: ['hello'],
},
0,
ExampleService
).expect({
title: 'ExampleService',
example: {
pattern: '/some-service/:interval/:packageName',
namedParams: { interval: 'dt', packageName: 'express' },
queryParams: { registry_url: 'http://example.com/' },
},
preview: {
label: 'downloads',
message: '50k',
color: 'lightgrey',
namedLogo: undefined,
style: undefined,
},
keywords: ['hello'],
documentation: undefined,
})
})

View File

@@ -0,0 +1,35 @@
'use strict'
const BaseService = require('./base')
const BaseJsonService = require('./base-json')
const NonMemoryCachingBaseService = require('./base-non-memory-caching')
const BaseStaticService = require('./base-static')
const BaseSvgScrapingService = require('./base-svg-scraping')
const BaseXmlService = require('./base-xml')
const BaseYamlService = require('./base-yaml')
const deprecatedService = require('./deprecated-service')
const redirector = require('./redirector')
const {
NotFound,
InvalidResponse,
Inaccessible,
InvalidParameter,
Deprecated,
} = require('./errors')
module.exports = {
BaseService,
BaseJsonService,
NonMemoryCachingBaseService,
BaseStaticService,
BaseSvgScrapingService,
BaseXmlService,
BaseYamlService,
deprecatedService,
redirector,
NotFound,
InvalidResponse,
Inaccessible,
InvalidParameter,
Deprecated,
}

View File

@@ -3,14 +3,18 @@
// eslint-disable-next-line node/no-deprecated-api
const domain = require('domain')
const request = require('request')
const { makeBadgeData: getBadgeData } = require('./badge-data')
const log = require('./log')
const LruCache = require('../gh-badges/lib/lru-cache')
const makeBadge = require('../gh-badges/lib/make-badge')
const analytics = require('./analytics')
const { makeSend } = require('./result-sender')
const queryString = require('query-string')
const { Inaccessible } = require('../services/errors')
const LruCache = require('../../gh-badges/lib/lru-cache')
const makeBadge = require('../../gh-badges/lib/make-badge')
const log = require('../server/log')
const { setCacheHeaders } = require('./cache-headers')
const {
Inaccessible,
InvalidResponse,
ShieldsRuntimeError,
} = require('./errors')
const { makeSend } = require('./legacy-result-sender')
const coalesceBadge = require('./coalesce-badge')
// We avoid calling the vendor's server for computation of the information in a
// number of badges.
@@ -34,8 +38,8 @@ vendorDomain.on('error', err => {
log.error('Vendor hook error:', err.stack)
})
// These query parameters are available to any badge. For the most part they
// are used by makeBadgeData (see `lib/badge-data.js`) and related functions.
// These query parameters are available to any badge. They are handled by
// `coalesceBadge`.
const globalQueryParams = new Set([
'label',
'style',
@@ -47,6 +51,8 @@ const globalQueryParams = new Set([
'link',
'colorA',
'colorB',
'color',
'labelColor',
])
function flattenQueryParams(queryParams) {
@@ -57,29 +63,13 @@ function flattenQueryParams(queryParams) {
return Array.from(union).sort()
}
function getBadgeMaxAge(handlerOptions, queryParams) {
let maxAge = isInt(process.env.BADGE_MAX_AGE_SECONDS)
? parseInt(process.env.BADGE_MAX_AGE_SECONDS)
: 120
if (handlerOptions.cacheLength) {
// If we've set a more specific cache length for this badge (or category),
// use that instead of env.BADGE_MAX_AGE_SECONDS.
maxAge = handlerOptions.cacheLength
}
if (isInt(queryParams.maxAge) && parseInt(queryParams.maxAge) > maxAge) {
// Only allow queryParams.maxAge to override the default if it is greater
// than the default.
maxAge = parseInt(queryParams.maxAge)
}
return maxAge
}
// handlerOptions can contain:
// - handler: The service's request handler function
// - queryParams: An array of the field names of any custom query parameters
// the service uses
// - cacheLength: An optional badge or category-specific cache length
// (in number of seconds) to be used in preference to the default
// - fetchLimitBytes: A limit on the response size we're willing to parse
//
// For safety, the service must declare the query parameters it wants to use.
// Only the declared parameters (and the global parameters) are provided to
@@ -89,34 +79,47 @@ function getBadgeMaxAge(handlerOptions, queryParams) {
// (undesirable and hard to debug).
//
// Pass just the handler function as shorthand.
function handleRequest(handlerOptions) {
function handleRequest(cacheHeaderConfig, handlerOptions) {
if (!cacheHeaderConfig) {
throw Error('cacheHeaderConfig is required')
}
if (typeof handlerOptions === 'function') {
handlerOptions = { handler: handlerOptions }
}
const allowedKeys = flattenQueryParams(handlerOptions.queryParams)
const {
cacheLength: serviceDefaultCacheLengthSeconds,
fetchLimitBytes,
} = handlerOptions
return (queryParams, match, end, ask) => {
const reqTime = new Date()
const maxAge = getBadgeMaxAge(handlerOptions, queryParams)
// send both Cache-Control max-age and Expires
// in case the client implements HTTP/1.0 but not HTTP/1.1
if (maxAge === 0) {
ask.res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate')
ask.res.setHeader('Expires', reqTime.toGMTString())
} else {
ask.res.setHeader('Cache-Control', `max-age=${maxAge}`)
ask.res.setHeader(
'Expires',
new Date(+reqTime + maxAge * 1000).toGMTString()
)
// `defaultCacheLengthSeconds` can be overridden by
// `serviceDefaultCacheLengthSeconds` (either by category or on a badge-
// by-badge basis). Then in turn that can be overridden by
// `serviceOverrideCacheLengthSeconds` (which we expect to be used only in
// the dynamic badge) but only if `serviceOverrideCacheLengthSeconds` is
// longer than `serviceDefaultCacheLengthSeconds` and then the `cacheSeconds`
// query param can also override both of those but again only if `cacheSeconds`
// is longer.
//
// When the legacy services have been rewritten, all the code in here
// will go away, which should achieve this goal in a simpler way.
//
// Ref: https://github.com/badges/shields/pull/2755
function setCacheHeadersOnResponse(res, serviceOverrideCacheLengthSeconds) {
setCacheHeaders({
cacheHeaderConfig,
serviceDefaultCacheLengthSeconds,
serviceOverrideCacheLengthSeconds,
queryParams,
res,
})
}
ask.res.setHeader('Date', reqTime.toGMTString())
analytics.noteRequest(queryParams, match)
const filteredQueryParams = {}
allowedKeys.forEach(key => {
filteredQueryParams[key] = queryParams[key]
@@ -135,6 +138,10 @@ function handleRequest(handlerOptions) {
const tooSoon = +reqTime - cached.time < cached.interval
if (tooSoon || cached.dataChange / cached.reqs <= freqRatioMax) {
const svg = makeBadge(cached.data.badgeData)
setCacheHeadersOnResponse(
ask.res,
cached.data.badgeData.cacheLengthSeconds
)
makeSend(cached.data.format, ask.res, end)(svg)
cachedVersionSent = true
// We do not wish to call the vendor servers.
@@ -152,21 +159,29 @@ function handleRequest(handlerOptions) {
return
}
if (requestCache.has(cacheIndex)) {
const cached = requestCache.get(cacheIndex).data
const svg = makeBadge(cached.badgeData)
makeSend(cached.format, ask.res, end)(svg)
const cached = requestCache.get(cacheIndex)
const svg = makeBadge(cached.data.badgeData)
setCacheHeadersOnResponse(
ask.res,
cached.data.badgeData.cacheLengthSeconds
)
makeSend(cached.data.format, ask.res, end)(svg)
return
}
ask.res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate')
const badgeData = getBadgeData('vendor', filteredQueryParams)
badgeData.text[1] = 'unresponsive'
const badgeData = coalesceBadge(
filteredQueryParams,
{ label: 'vendor', message: 'unresponsive' },
{}
)
const svg = makeBadge(badgeData)
let extension
try {
extension = match[0].split('.').pop()
} catch (e) {
extension = 'svg'
}
const svg = makeBadge(badgeData)
setCacheHeadersOnResponse(ask.res)
makeSend(extension, ask.res, end)(svg)
}, 25000)
@@ -187,7 +202,8 @@ function handleRequest(handlerOptions) {
options.headers['User-Agent'] =
options.headers['User-Agent'] || 'Shields.io'
request(options, (err, res, body) => {
let bufferLength = 0
const r = request(options, (err, res, body) => {
if (res != null && res.headers != null) {
const cacheControl = res.headers['cache-control']
if (cacheControl != null) {
@@ -201,6 +217,18 @@ function handleRequest(handlerOptions) {
}
callback(err, res, body)
})
r.on('data', chunk => {
bufferLength += chunk.length
if (bufferLength > fetchLimitBytes) {
r.abort()
r.emit(
'error',
new InvalidResponse({
prettyMessage: 'Maximum response size exceeded',
})
)
}
})
}
// Wrapper around `cachingRequest` that returns a promise rather than
@@ -209,9 +237,13 @@ function handleRequest(handlerOptions) {
new Promise((resolve, reject) => {
cachingRequest(uri, options, (err, res, buffer) => {
if (err) {
// Wrap the error in an Inaccessible so it can be identified
// by the BaseService handler.
reject(new Inaccessible({ underlyingError: err }))
if (err instanceof ShieldsRuntimeError) {
reject(err)
} else {
// Wrap the error in an Inaccessible so it can be identified
// by the BaseService handler.
reject(new Inaccessible({ underlyingError: err }))
}
} else {
resolve({ res, buffer })
}
@@ -251,6 +283,7 @@ function handleRequest(handlerOptions) {
requestCache.set(cacheIndex, updatedCache)
if (!cachedVersionSent) {
const svg = makeBadge(badgeData)
setCacheHeadersOnResponse(ask.res, badgeData.cacheLengthSeconds)
makeSend(format, ask.res, end)(svg)
}
},
@@ -269,14 +302,9 @@ function clearRequestCache() {
requestCache.clear()
}
function isInt(number) {
return number !== undefined && /^[0-9]+$/.test(number)
}
module.exports = {
handleRequest,
clearRequestCache,
// Expose for testing.
_requestCache: requestCache,
getBadgeMaxAge,
}

View File

@@ -0,0 +1,392 @@
'use strict'
const { expect } = require('chai')
// https://github.com/nock/nock/issues/1523
const got = require('got').extend({ retry: 0 })
const nock = require('nock')
const portfinder = require('portfinder')
const Camp = require('camp')
const coalesceBadge = require('./coalesce-badge')
const {
handleRequest,
clearRequestCache,
_requestCache,
} = require('./legacy-request-handler')
async function performTwoRequests(baseUrl, first, second) {
expect((await got(`${baseUrl}${first}`)).statusCode).to.equal(200)
expect((await got(`${baseUrl}${second}`)).statusCode).to.equal(200)
}
function fakeHandler(queryParams, match, sendBadge, request) {
const [, someValue, format] = match
const badgeData = coalesceBadge(
queryParams,
{
label: 'testing',
message: someValue,
},
{}
)
sendBadge(format, badgeData)
}
function createFakeHandlerWithCacheLength(cacheLengthSeconds) {
return function fakeHandler(queryParams, match, sendBadge, request) {
const [, someValue, format] = match
const badgeData = coalesceBadge(
queryParams,
{
label: 'testing',
message: someValue,
},
{},
{
_cacheLength: cacheLengthSeconds,
}
)
sendBadge(format, badgeData)
}
}
function fakeHandlerWithNetworkIo(queryParams, match, sendBadge, request) {
const [, someValue, format] = match
request('https://www.google.com/foo/bar', (err, res, buffer) => {
let message
if (err) {
message = err.prettyMessage
} else {
message = someValue
}
const badgeData = coalesceBadge(
queryParams,
{
label: 'testing',
message,
format,
},
{}
)
sendBadge(format, badgeData)
})
}
describe('The request handler', function() {
let port, baseUrl
beforeEach(async function() {
port = await portfinder.getPortPromise()
baseUrl = `http://127.0.0.1:${port}`
})
let camp
beforeEach(function(done) {
camp = Camp.start({ port, hostname: '::' })
camp.on('listening', () => done())
})
afterEach(function(done) {
clearRequestCache()
if (camp) {
camp.close(() => done())
camp = null
}
})
const standardCacheHeaders = { defaultCacheLengthSeconds: 120 }
describe('the options object calling style', function() {
beforeEach(function() {
camp.route(
/^\/testing\/([^/]+)\.(svg|png|gif|jpg|json)$/,
handleRequest(standardCacheHeaders, { handler: fakeHandler })
)
})
it('should return the expected response', async function() {
const { statusCode, body } = await got(`${baseUrl}/testing/123.json`, {
json: true,
})
expect(statusCode).to.equal(200)
expect(body).to.deep.equal({
name: 'testing',
value: '123',
label: 'testing',
message: '123',
color: 'lightgrey',
link: [],
})
})
})
describe('the function shorthand calling style', function() {
beforeEach(function() {
camp.route(
/^\/testing\/([^/]+)\.(svg|png|gif|jpg|json)$/,
handleRequest(standardCacheHeaders, fakeHandler)
)
})
it('should return the expected response', async function() {
const { statusCode, body } = await got(`${baseUrl}/testing/123.json`, {
json: true,
})
expect(statusCode).to.equal(200)
expect(body).to.deep.equal({
name: 'testing',
value: '123',
label: 'testing',
message: '123',
color: 'lightgrey',
link: [],
})
})
})
describe('the response size limit', function() {
beforeEach(function() {
camp.route(
/^\/testing\/([^/]+)\.(svg|png|gif|jpg|json)$/,
handleRequest(standardCacheHeaders, {
handler: fakeHandlerWithNetworkIo,
fetchLimitBytes: 100,
})
)
})
it('should not throw an error if the response <= fetchLimitBytes', async function() {
nock('https://www.google.com')
.get('/foo/bar')
.once()
.reply(200, 'x'.repeat(100))
const { statusCode, body } = await got(`${baseUrl}/testing/123.json`, {
json: true,
})
expect(statusCode).to.equal(200)
expect(body).to.deep.equal({
name: 'testing',
value: '123',
label: 'testing',
message: '123',
color: 'lightgrey',
link: [],
})
})
it('should throw an error if the response is > fetchLimitBytes', async function() {
nock('https://www.google.com')
.get('/foo/bar')
.once()
.reply(200, 'x'.repeat(101))
const { statusCode, body } = await got(`${baseUrl}/testing/123.json`, {
json: true,
})
expect(statusCode).to.equal(200)
expect(body).to.deep.equal({
name: 'testing',
value: 'Maximum response size exceeded',
label: 'testing',
message: 'Maximum response size exceeded',
color: 'lightgrey',
link: [],
})
})
afterEach(function() {
nock.cleanAll()
})
})
describe('caching', function() {
describe('standard query parameters', function() {
let handlerCallCount
beforeEach(function() {
handlerCallCount = 0
})
function register({ cacheHeaderConfig }) {
camp.route(
/^\/testing\/([^/]+)\.(svg|png|gif|jpg|json)$/,
handleRequest(
cacheHeaderConfig,
(queryParams, match, sendBadge, request) => {
++handlerCallCount
fakeHandler(queryParams, match, sendBadge, request)
}
)
)
}
context('With standard cache settings', function() {
beforeEach(function() {
register({ cacheHeaderConfig: standardCacheHeaders })
})
it('should cache identical requests', async function() {
await performTwoRequests(
baseUrl,
'/testing/123.svg',
'/testing/123.svg'
)
expect(handlerCallCount).to.equal(1)
})
it('should differentiate known query parameters', async function() {
await performTwoRequests(
baseUrl,
'/testing/123.svg?label=foo',
'/testing/123.svg?label=bar'
)
expect(handlerCallCount).to.equal(2)
})
it('should ignore unknown query parameters', async function() {
await performTwoRequests(
baseUrl,
'/testing/123.svg?foo=1',
'/testing/123.svg?foo=2'
)
expect(handlerCallCount).to.equal(1)
})
})
it('should set the expires header to current time + defaultCacheLengthSeconds', async function() {
register({ cacheHeaderConfig: { defaultCacheLengthSeconds: 900 } })
const { headers } = await got(`${baseUrl}/testing/123.json`)
const expectedExpiry = new Date(
+new Date(headers.date) + 900000
).toGMTString()
expect(headers.expires).to.equal(expectedExpiry)
expect(headers['cache-control']).to.equal('max-age=900')
})
it('should set the expected cache headers on cached responses', async function() {
register({ cacheHeaderConfig: { defaultCacheLengthSeconds: 900 } })
// Make first request.
await got(`${baseUrl}/testing/123.json`)
const { headers } = await got(`${baseUrl}/testing/123.json`)
const expectedExpiry = new Date(
+new Date(headers.date) + 900000
).toGMTString()
expect(headers.expires).to.equal(expectedExpiry)
expect(headers['cache-control']).to.equal('max-age=900')
})
it('should let live service data override the default cache headers with longer value', async function() {
camp.route(
/^\/testing\/([^/]+)\.(svg|png|gif|jpg|json)$/,
handleRequest(
{ defaultCacheLengthSeconds: 300 },
(queryParams, match, sendBadge, request) => {
++handlerCallCount
createFakeHandlerWithCacheLength(400)(
queryParams,
match,
sendBadge,
request
)
}
)
)
const { headers } = await got(`${baseUrl}/testing/123.json`)
expect(headers['cache-control']).to.equal('max-age=400')
})
it('should not let live service data override the default cache headers with shorter value', async function() {
camp.route(
/^\/testing\/([^/]+)\.(svg|png|gif|jpg|json)$/,
handleRequest(
{ defaultCacheLengthSeconds: 300 },
(queryParams, match, sendBadge, request) => {
++handlerCallCount
createFakeHandlerWithCacheLength(200)(
queryParams,
match,
sendBadge,
request
)
}
)
)
const { headers } = await got(`${baseUrl}/testing/123.json`)
expect(headers['cache-control']).to.equal('max-age=300')
})
it('should set the expires header to current time + cacheSeconds', async function() {
register({ cacheHeaderConfig: { defaultCacheLengthSeconds: 0 } })
const { headers } = await got(
`${baseUrl}/testing/123.json?cacheSeconds=3600`
)
const expectedExpiry = new Date(
+new Date(headers.date) + 3600000
).toGMTString()
expect(headers.expires).to.equal(expectedExpiry)
expect(headers['cache-control']).to.equal('max-age=3600')
})
it('should ignore cacheSeconds when shorter than defaultCacheLengthSeconds', async function() {
register({ cacheHeaderConfig: { defaultCacheLengthSeconds: 600 } })
const { headers } = await got(
`${baseUrl}/testing/123.json?cacheSeconds=300`
)
const expectedExpiry = new Date(
+new Date(headers.date) + 600000
).toGMTString()
expect(headers.expires).to.equal(expectedExpiry)
expect(headers['cache-control']).to.equal('max-age=600')
})
it('should set Cache-Control: no-cache, no-store, must-revalidate if cache seconds is 0', async function() {
register({ cacheHeaderConfig: { defaultCacheLengthSeconds: 0 } })
const { headers } = await got(`${baseUrl}/testing/123.json`)
expect(headers.expires).to.equal(headers.date)
expect(headers['cache-control']).to.equal(
'no-cache, no-store, must-revalidate'
)
})
describe('the cache key', function() {
beforeEach(function() {
register({ cacheHeaderConfig: standardCacheHeaders })
})
const expectedCacheKey = '/testing/123.json?color=123&label=foo'
it('should match expected and use canonical order - 1', async function() {
await got(`${baseUrl}/testing/123.json?color=123&label=foo`)
expect(_requestCache.cache).to.have.keys(expectedCacheKey)
})
it('should match expected and use canonical order - 2', async function() {
await got(`${baseUrl}/testing/123.json?label=foo&color=123`)
expect(_requestCache.cache).to.have.keys(expectedCacheKey)
})
})
})
describe('custom query parameters', function() {
let handlerCallCount
beforeEach(function() {
handlerCallCount = 0
camp.route(
/^\/testing\/([^/]+)\.(svg|png|gif|jpg|json)$/,
handleRequest(standardCacheHeaders, {
queryParams: ['foo'],
handler: (queryParams, match, sendBadge, request) => {
++handlerCallCount
fakeHandler(queryParams, match, sendBadge, request)
},
})
)
})
it('should differentiate them', async function() {
await performTwoRequests(
baseUrl,
'/testing/123.svg?foo=1',
'/testing/123.svg?foo=2'
)
expect(handlerCallCount).to.equal(2)
})
})
})
})

View File

@@ -1,8 +1,15 @@
'use strict'
const fs = require('fs')
const path = require('path')
const stream = require('stream')
const log = require('./log')
const svg2img = require('../gh-badges/lib/svg-to-img')
const svg2img = require('../../gh-badges/lib/svg-to-img')
const log = require('../server/log')
const internalError = fs.readFileSync(
path.resolve(__dirname, '..', 'server', 'error-pages', '500.html'),
'utf-8'
)
function streamFromString(str) {
const newStream = new stream.Readable()
@@ -13,16 +20,6 @@ function streamFromString(str) {
return newStream
}
function makeSend(format, askres, end) {
if (format === 'svg') {
return res => sendSVG(res, askres, end)
} else if (format === 'json') {
return res => sendJSON(res, askres, end)
} else {
return res => sendOther(format, res, askres, end)
}
}
function sendSVG(res, askres, end) {
askres.setHeader('Content-Type', 'image/svg+xml;charset=utf-8')
end(null, { template: streamFromString(res) })
@@ -39,7 +36,7 @@ function sendOther(format, res, askres, end) {
.catch(err => {
// This emits status code 200, though 500 would be preferable.
log.error('svg2img error', err)
end(null, { template: '500.html' })
end(internalError)
})
}
@@ -49,6 +46,16 @@ function sendJSON(res, askres, end) {
end(null, { template: streamFromString(res) })
}
function makeSend(format, askres, end) {
if (format === 'svg') {
return res => sendSVG(res, askres, end)
} else if (format === 'json') {
return res => sendJSON(res, askres, end)
} else {
return res => sendOther(format, res, askres, end)
}
}
module.exports = {
makeSend,
}

View File

@@ -1,6 +1,6 @@
'use strict'
const BaseJsonService = require('../services/base-json')
const BaseJsonService = require('../base-json')
class BadBaseService {}
class GoodService extends BaseJsonService {}

View File

@@ -0,0 +1,30 @@
'use strict'
const BaseJsonService = require('../base-json')
class GoodServiceOne extends BaseJsonService {
static get category() {
return 'build'
}
static get route() {
return {
base: 'good',
pattern: 'one',
}
}
}
class GoodServiceTwo extends BaseJsonService {
static get category() {
return 'build'
}
static get route() {
return {
base: 'good',
pattern: 'two',
}
}
}
module.exports = [GoodServiceOne, GoodServiceTwo]

View File

@@ -0,0 +1,18 @@
'use strict'
const BaseJsonService = require('../base-json')
class GoodService extends BaseJsonService {
static get category() {
return 'build'
}
static get route() {
return {
base: 'it/is',
pattern: 'good',
}
}
}
module.exports = GoodService

View File

@@ -0,0 +1,30 @@
'use strict'
const BaseJsonService = require('../base-json')
class GoodServiceOne extends BaseJsonService {
static get category() {
return 'build'
}
static get route() {
return {
base: 'good',
pattern: 'one',
}
}
}
class GoodServiceTwo extends BaseJsonService {
static get category() {
return 'build'
}
static get route() {
return {
base: 'good',
pattern: 'two',
}
}
}
module.exports = { GoodServiceOne, GoodServiceTwo }

115
core/base-service/loader.js Normal file
View File

@@ -0,0 +1,115 @@
'use strict'
const path = require('path')
const glob = require('glob')
const countBy = require('lodash.countby')
const categories = require('../../services/categories')
const BaseService = require('./base')
const { assertValidServiceDefinitionExport } = require('./service-definitions')
const serviceDir = path.join(__dirname, '..', '..', 'services')
class InvalidService extends Error {
constructor(message) {
super(message)
this.name = 'InvalidService'
}
}
function loadServiceClasses(servicePaths) {
if (!servicePaths) {
servicePaths = glob.sync(path.join(serviceDir, '**', '*.service.js'))
}
let serviceClasses = []
servicePaths.forEach(servicePath => {
const module = require(servicePath)
const theseServiceClasses = []
if (
!module ||
(module.constructor === Array && module.length === 0) ||
(module.constructor === Object && Object.keys(module).length === 0)
) {
throw new InvalidService(
`Expected ${servicePath} to export a service or a collection of services`
)
} else if (module.prototype instanceof BaseService) {
theseServiceClasses.push(module)
} else if (module.constructor === Array || module.constructor === Object) {
for (const key in module) {
const serviceClass = module[key]
if (serviceClass.prototype instanceof BaseService) {
theseServiceClasses.push(serviceClass)
} else {
throw new InvalidService(
`Expected ${servicePath} to export a service or a collection of services; one of them was ${serviceClass}`
)
}
}
} else {
throw new InvalidService(
`Expected ${servicePath} to export a service or a collection of services; got ${module}`
)
}
// Decorate each service class with the directory that contains it.
theseServiceClasses.forEach(serviceClass => {
serviceClass.serviceFamily = servicePath
.replace(serviceDir, '')
.split(path.sep)[1]
})
serviceClasses = serviceClasses.concat(theseServiceClasses)
})
serviceClasses.forEach(ServiceClass => ServiceClass.validateDefinition())
return serviceClasses
}
function assertNamesUnique(names, { message }) {
const duplicates = {}
Object.entries(countBy(names))
.filter(([name, count]) => count > 1)
.forEach(([name, count]) => {
duplicates[name] = count
})
if (Object.keys(duplicates).length) {
throw new Error(`${message}: ${JSON.stringify(duplicates, undefined, 2)}`)
}
}
function checkNames() {
const services = loadServiceClasses()
assertNamesUnique(services.map(({ name }) => name), {
message: 'Duplicate service names found',
})
}
function collectDefinitions() {
const services = loadServiceClasses()
// flatMap.
.map(ServiceClass => ServiceClass.getDefinition())
.reduce((accum, these) => accum.concat(these), [])
const result = { schemaVersion: '0', categories, services }
assertValidServiceDefinitionExport(result)
return result
}
function loadTesters() {
return glob
.sync(path.join(serviceDir, '**', '*.tester.js'))
.map(path => require(path))
}
module.exports = {
InvalidService,
loadServiceClasses,
checkNames,
collectDefinitions,
loadTesters,
}

View File

@@ -0,0 +1,59 @@
'use strict'
const { expect } = require('chai')
const { loadServiceClasses, InvalidService } = require('./loader')
describe('loadServiceClasses function', function() {
it('throws if module exports empty', function() {
expect(() =>
loadServiceClasses(['./loader-test-fixtures/empty-undefined.fixture.js'])
).to.throw(InvalidService)
expect(() =>
loadServiceClasses(['./loader-test-fixtures/empty-array.fixture.js'])
).to.throw()
expect(() =>
loadServiceClasses(['./loader-test-fixtures/empty-object.fixture.js'])
).to.throw(InvalidService)
expect(() =>
loadServiceClasses(['./loader-test-fixtures/empty-no-export.fixture.js'])
).to.throw(InvalidService)
expect(() =>
loadServiceClasses([
'./loader-test-fixtures/valid-array.fixture.js',
'./loader-test-fixtures/valid-class.fixture.js',
'./loader-test-fixtures/empty-array.fixture.js',
])
).to.throw(InvalidService)
})
it('throws if module exports invalid', function() {
expect(() =>
loadServiceClasses(['./loader-test-fixtures/invalid-no-base.fixture.js'])
).to.throw(InvalidService)
expect(() =>
loadServiceClasses([
'./loader-test-fixtures/invalid-wrong-base.fixture.js',
])
).to.throw(InvalidService)
expect(() =>
loadServiceClasses(['./loader-test-fixtures/invalid-mixed.fixture.js'])
).to.throw(InvalidService)
expect(() =>
loadServiceClasses([
'./loader-test-fixtures/valid-array.fixture.js',
'./loader-test-fixtures/valid-class.fixture.js',
'./loader-test-fixtures/invalid-no-base.fixture.js',
])
).to.throw(InvalidService)
})
it('registers services if module exports valid service classes', function() {
expect(
loadServiceClasses([
'./loader-test-fixtures/valid-array.fixture.js',
'./loader-test-fixtures/valid-object.fixture.js',
'./loader-test-fixtures/valid-class.fixture.js',
])
).to.have.length(5)
})
})

View File

@@ -0,0 +1,123 @@
'use strict'
const camelcase = require('camelcase')
const emojic = require('emojic')
const Joi = require('joi')
const queryString = require('query-string')
const BaseService = require('./base')
const {
serverHasBeenUpSinceResourceCached,
setCacheHeadersForStaticResource,
} = require('./cache-headers')
const { isValidCategory } = require('./categories')
const { isValidRoute, prepareRoute, namedParamsForMatch } = require('./route')
const trace = require('./trace')
const attrSchema = Joi.object({
name: Joi.string().min(3),
category: isValidCategory,
route: isValidRoute,
transformPath: Joi.func()
.maxArity(1)
.required()
.error(
() =>
'"transformPath" must be a function that transforms named params to a new path'
),
transformQueryParams: Joi.func().arity(1),
dateAdded: Joi.date().required(),
overrideTransformedQueryParams: Joi.bool().optional(),
}).required()
module.exports = function redirector(attrs) {
const {
name,
category,
route,
transformPath,
transformQueryParams,
overrideTransformedQueryParams,
} = Joi.attempt(attrs, attrSchema, `Redirector for ${attrs.route.base}`)
return class Redirector extends BaseService {
static get name() {
if (name) {
return name
} else {
return `${camelcase(route.base.replace(/\//g, '_'), {
pascalCase: true,
})}Redirect`
}
}
static get category() {
return category
}
static get isDeprecated() {
return true
}
static get route() {
return route
}
static register({ camp, requestCounter }) {
const { regex, captureNames } = prepareRoute(this.route)
const serviceRequestCounter = this._createServiceRequestCounter({
requestCounter,
})
camp.route(regex, async (queryParams, match, end, ask) => {
if (serverHasBeenUpSinceResourceCached(ask.req)) {
// Send Not Modified.
ask.res.statusCode = 304
ask.res.end()
return
}
const namedParams = namedParamsForMatch(captureNames, match, this)
trace.logTrace(
'inbound',
emojic.arrowHeadingUp,
'Redirector',
route.base
)
trace.logTrace('inbound', emojic.ticket, 'Named params', namedParams)
trace.logTrace('inbound', emojic.crayon, 'Query params', queryParams)
const targetPath = transformPath(namedParams)
trace.logTrace('validate', emojic.dart, 'Target', targetPath)
let urlSuffix = ask.uri.search || ''
if (transformQueryParams) {
const specifiedParams = queryString.parse(urlSuffix)
const transformedParams = transformQueryParams(namedParams)
const redirectParams = overrideTransformedQueryParams
? Object.assign(transformedParams, specifiedParams)
: Object.assign(specifiedParams, transformedParams)
const outQueryString = queryString.stringify(redirectParams)
urlSuffix = `?${outQueryString}`
}
// The final capture group is the extension.
const format = match.slice(-1)[0]
const redirectUrl = `${targetPath}.${format}${urlSuffix}`
trace.logTrace('outbound', emojic.shield, 'Redirect URL', redirectUrl)
ask.res.statusCode = 301
ask.res.setHeader('Location', redirectUrl)
// To avoid caching mistakes for a long time, and to make this simpler
// to reason about, use the same cache semantics as the static badge.
setCacheHeadersForStaticResource(ask.res)
ask.res.end()
serviceRequestCounter.inc()
})
}
}
}

View File

@@ -0,0 +1,207 @@
'use strict'
const Camp = require('camp')
const got = require('got')
const portfinder = require('portfinder')
const { expect } = require('chai')
const redirector = require('./redirector')
describe('Redirector', function() {
const route = {
base: 'very/old/service',
pattern: ':namedParamA',
}
const category = 'analysis'
const transformPath = () => {}
const dateAdded = new Date()
const attrs = { category, route, transformPath, dateAdded }
it('returns true on isDeprecated', function() {
expect(redirector(attrs).isDeprecated).to.be.true
})
it('has the expected name', function() {
expect(redirector(attrs).name).to.equal('VeryOldServiceRedirect')
})
it('overrides the name', function() {
expect(
redirector({
...attrs,
name: 'ShinyRedirect',
}).name
).to.equal('ShinyRedirect')
})
it('sets specified route', function() {
expect(redirector(attrs).route).to.deep.equal(route)
})
it('sets specified category', function() {
expect(redirector(attrs).category).to.equal(category)
})
it('throws the expected error when dateAdded is missing', function() {
expect(() =>
redirector({ route, category, transformPath }).validateDefinition()
).to.throw('"dateAdded" is required')
})
describe('ScoutCamp integration', function() {
let port, baseUrl
beforeEach(async function() {
port = await portfinder.getPortPromise()
baseUrl = `http://127.0.0.1:${port}`
})
let camp
beforeEach(async function() {
camp = Camp.start({ port, hostname: '::' })
await new Promise(resolve => camp.on('listening', () => resolve()))
})
afterEach(async function() {
if (camp) {
await new Promise(resolve => camp.close(resolve))
camp = undefined
}
})
const transformPath = ({ namedParamA }) => `/new/service/${namedParamA}`
beforeEach(function() {
const ServiceClass = redirector({
category,
route,
transformPath,
dateAdded,
})
ServiceClass.register({ camp }, {})
})
it('should redirect as configured', async function() {
const { statusCode, headers } = await got(
`${baseUrl}/very/old/service/hello-world.svg`,
{
followRedirect: false,
}
)
expect(statusCode).to.equal(301)
expect(headers.location).to.equal('/new/service/hello-world.svg')
})
it('should preserve the extension', async function() {
const { statusCode, headers } = await got(
`${baseUrl}/very/old/service/hello-world.png`,
{
followRedirect: false,
}
)
expect(statusCode).to.equal(301)
expect(headers.location).to.equal('/new/service/hello-world.png')
})
it('should forward the query params', async function() {
const { statusCode, headers } = await got(
`${baseUrl}/very/old/service/hello-world.svg?color=123&style=flat-square`,
{
followRedirect: false,
}
)
expect(statusCode).to.equal(301)
expect(headers.location).to.equal(
'/new/service/hello-world.svg?color=123&style=flat-square'
)
})
describe('transformQueryParams', function() {
const route = {
base: 'another/old/service',
pattern: 'token/:token/:namedParamA',
}
const transformQueryParams = ({ token }) => ({ token })
beforeEach(function() {
const ServiceClass = redirector({
category,
route,
transformPath,
transformQueryParams,
dateAdded,
})
ServiceClass.register({ camp }, {})
})
it('should forward the transformed query params', async function() {
const { statusCode, headers } = await got(
`${baseUrl}/another/old/service/token/abc123/hello-world.svg`,
{
followRedirect: false,
}
)
expect(statusCode).to.equal(301)
expect(headers.location).to.equal(
'/new/service/hello-world.svg?token=abc123'
)
})
it('should forward the specified and transformed query params', async function() {
const { statusCode, headers } = await got(
`${baseUrl}/another/old/service/token/abc123/hello-world.svg?color=123&style=flat-square`,
{
followRedirect: false,
}
)
expect(statusCode).to.equal(301)
expect(headers.location).to.equal(
'/new/service/hello-world.svg?color=123&style=flat-square&token=abc123'
)
})
it('should use transformed query params on param conflicts by default', async function() {
const { statusCode, headers } = await got(
`${baseUrl}/another/old/service/token/abc123/hello-world.svg?color=123&style=flat-square&token=def456`,
{
followRedirect: false,
}
)
expect(statusCode).to.equal(301)
expect(headers.location).to.equal(
'/new/service/hello-world.svg?color=123&style=flat-square&token=abc123'
)
})
it('should use specified query params on param conflicts when configured', async function() {
const route = {
base: 'override/service',
pattern: 'token/:token/:namedParamA',
}
const ServiceClass = redirector({
category,
route,
transformPath,
transformQueryParams,
overrideTransformedQueryParams: true,
dateAdded,
})
ServiceClass.register({ camp }, {})
const { statusCode, headers } = await got(
`${baseUrl}/override/service/token/abc123/hello-world.svg?style=flat-square&token=def456`,
{
followRedirect: false,
}
)
expect(statusCode).to.equal(301)
expect(headers.location).to.equal(
'/new/service/hello-world.svg?style=flat-square&token=def456'
)
})
})
})
})

View File

@@ -0,0 +1,88 @@
'use strict'
const Joi = require('joi')
const pathToRegexp = require('path-to-regexp')
function makeFullUrl(base, partialUrl) {
return `/${[base, partialUrl].filter(Boolean).join('/')}`
}
const isValidRoute = Joi.object({
base: Joi.string()
.allow('')
.required(),
pattern: Joi.string().allow(''),
format: Joi.string(),
capture: Joi.alternatives().when('format', {
is: Joi.string().required(),
then: Joi.array().items(Joi.string().required()),
}),
queryParamSchema: Joi.object().schema(),
})
.xor('pattern', 'format')
.required()
function assertValidRoute(route, message = undefined) {
Joi.assert(route, isValidRoute, message)
}
function prepareRoute({ base, pattern, format, capture }) {
let regex, captureNames
if (pattern === undefined) {
regex = new RegExp(
`^${makeFullUrl(base, format)}\\.(svg|png|gif|jpg|json)$`
)
captureNames = capture || []
} else {
const fullPattern = `${makeFullUrl(
base,
pattern
)}.:ext(svg|png|gif|jpg|json)`
const keys = []
regex = pathToRegexp(fullPattern, keys, {
strict: true,
sensitive: true,
})
captureNames = keys.map(item => item.name).slice(0, -1)
}
return { regex, captureNames }
}
function namedParamsForMatch(captureNames = [], match, ServiceClass) {
// Assume the last match is the format, and drop match[0], which is the
// entire match.
const captures = match.slice(1, -1)
if (captureNames.length !== captures.length) {
throw new Error(
`Service ${
ServiceClass.name
} declares incorrect number of named params ` +
`(expected ${captures.length}, got ${captureNames.length})`
)
}
const result = {}
captureNames.forEach((name, index) => {
result[name] = captures[index]
})
return result
}
function getQueryParamNames({ queryParamSchema }) {
if (queryParamSchema) {
const { children, renames = [] } = Joi.describe(queryParamSchema)
return Object.keys(children).concat(renames.map(({ from }) => from))
} else {
return []
}
}
module.exports = {
makeFullUrl,
isValidRoute,
assertValidRoute,
prepareRoute,
namedParamsForMatch,
getQueryParamNames,
}

View File

@@ -0,0 +1,124 @@
'use strict'
const { expect } = require('chai')
const Joi = require('joi')
const { test, given, forCases } = require('sazerac')
const {
prepareRoute,
namedParamsForMatch,
getQueryParamNames,
} = require('./route')
describe('Route helpers', function() {
context('A `pattern` with a named param is declared', function() {
const { regex, captureNames } = prepareRoute({
base: 'foo',
pattern: ':namedParamA',
queryParamSchema: Joi.object({ queryParamA: Joi.string() }).required(),
})
const regexExec = str => regex.exec(str)
test(regexExec, () => {
forCases([
given('/foo/bar.bar.bar.zip'),
given('/foo/bar/bar.svg'),
// This is a valid example with the wrong extension separator, to
// test that we only accept a `.`.
given('/foo/bar.bar.bar_svg'),
]).expect(null)
})
const namedParams = str =>
namedParamsForMatch(captureNames, regex.exec(str))
test(namedParams, () => {
forCases([
given('/foo/bar.bar.bar.svg'),
given('/foo/bar.bar.bar.png'),
given('/foo/bar.bar.bar.gif'),
given('/foo/bar.bar.bar.jpg'),
given('/foo/bar.bar.bar.json'),
]).expect({ namedParamA: 'bar.bar.bar' })
})
})
context('A `format` with a named param is declared', function() {
const { regex, captureNames } = prepareRoute({
base: 'foo',
format: '([^/]+)',
capture: ['namedParamA'],
})
const regexExec = str => regex.exec(str)
test(regexExec, () => {
forCases([
given('/foo/bar.bar.bar.zip'),
given('/foo/bar/bar.svg'),
// This is a valid example with the wrong extension separator, to
// test that we only accept a `.`.
given('/foo/bar.bar.bar_svg'),
]).expect(null)
})
const namedParams = str =>
namedParamsForMatch(captureNames, regex.exec(str))
test(namedParams, () => {
forCases([
given('/foo/bar.bar.bar.svg'),
given('/foo/bar.bar.bar.png'),
given('/foo/bar.bar.bar.gif'),
given('/foo/bar.bar.bar.jpg'),
given('/foo/bar.bar.bar.json'),
]).expect({ namedParamA: 'bar.bar.bar' })
})
})
context('No named params are declared', function() {
const { regex, captureNames } = prepareRoute({
base: 'foo',
format: '(?:[^/]+)',
})
const namedParams = str =>
namedParamsForMatch(captureNames, regex.exec(str))
test(namedParams, () => {
forCases([
given('/foo/bar.bar.bar.svg'),
given('/foo/bar.bar.bar.png'),
given('/foo/bar.bar.bar.gif'),
given('/foo/bar.bar.bar.jpg'),
given('/foo/bar.bar.bar.json'),
]).expect({})
})
})
context('The wrong number of params are declared', function() {
const { regex, captureNames } = prepareRoute({
base: 'foo',
format: '([^/]+)/([^/]+)',
capture: ['namedParamA'],
})
expect(() =>
namedParamsForMatch(captureNames, regex.exec('/foo/bar/baz.svg'), {
name: 'MyService',
})
).to.throw(
'Service MyService declares incorrect number of named params (expected 2, got 1)'
)
})
it('getQueryParamNames', function() {
expect(
getQueryParamNames({
queryParamSchema: Joi.object({ foo: Joi.string() }).required(),
})
).to.deep.equal(['foo'])
expect(
getQueryParamNames({
queryParamSchema: Joi.object({ foo: Joi.string() })
.rename('bar', 'foo', { ignoreUndefined: true, override: true })
.required(),
})
).to.deep.equal(['foo', 'bar'])
})
})

View File

@@ -0,0 +1,86 @@
'use strict'
const Joi = require('joi')
// This should be kept in sync with the schema in
// `frontend/lib/service-definitions/service-definition-prop-types.js`.
const arrayOfStrings = Joi.array()
.items(Joi.string())
.allow([])
.required()
const objectOfKeyValues = Joi.object()
.pattern(/./, Joi.string().allow(null))
.required()
const serviceDefinition = Joi.object({
category: Joi.string().required(),
name: Joi.string().required(),
isDeprecated: Joi.boolean().required(),
route: Joi.alternatives().try(
Joi.object({
pattern: Joi.string().required(),
queryParams: arrayOfStrings,
}),
Joi.object({
format: Joi.string().required(),
queryParams: arrayOfStrings,
})
),
examples: Joi.array()
.items(
Joi.object({
title: Joi.string().required(),
example: Joi.object({
pattern: Joi.string(),
namedParams: objectOfKeyValues,
queryParams: objectOfKeyValues,
}).required(),
preview: Joi.object({
label: Joi.string(),
message: Joi.string()
.allow('')
.required(),
color: Joi.string().required(),
style: Joi.string(),
namedLogo: Joi.string(),
}).required(),
keywords: arrayOfStrings,
documentation: Joi.object({
__html: Joi.string().required(), // Valid HTML.
}),
})
)
.default([]),
}).required()
function assertValidServiceDefinition(example, message = undefined) {
Joi.assert(example, serviceDefinition, message)
}
const serviceDefinitionExport = Joi.object({
schemaVersion: Joi.equal('0').required(),
categories: Joi.array()
.items(
Joi.object({
id: Joi.string().required(),
name: Joi.string().required(),
})
)
.required(),
services: Joi.array()
.items(serviceDefinition)
.required(),
}).required()
function assertValidServiceDefinitionExport(examples, message = undefined) {
Joi.assert(examples, serviceDefinitionExport, message)
}
module.exports = {
serviceDefinition,
assertValidServiceDefinition,
serviceDefinitionExport,
assertValidServiceDefinitionExport,
}

View File

@@ -0,0 +1,11 @@
'use strict'
module.exports = function toArray(val) {
if (val === undefined) {
return []
} else if (Object(val) instanceof Array) {
return val
} else {
return [val]
}
}

View File

@@ -1,6 +1,7 @@
'use strict'
const chalk = require('chalk')
const config = require('config').util.toObject()
// Config is loaded globally but it would be better to inject it. To do that,
// there needs to be one instance of the service created at registration time,
@@ -9,7 +10,7 @@ const chalk = require('chalk')
// thereby gaining access to the injected config.
const {
services: { trace: enableTraceLogging },
} = require('../lib/server-config')
} = config.public
function _formatLabelForStage(stage, label) {
const colorFn = {

View File

@@ -2,14 +2,16 @@
const emojic = require('emojic')
const Joi = require('joi')
const trace = require('../services/trace')
const trace = require('./trace')
function validate(
{
ErrorClass,
prettyErrorMessage = 'data does not match schema',
includeKeys = false,
traceErrorMessage = 'Data did not match schema',
traceSuccessMessage = 'Data after validation',
allowAndStripUnknownKeys = true,
},
data,
schema
@@ -17,10 +19,13 @@ function validate(
if (!schema || !schema.isJoi) {
throw Error('A Joi schema is required')
}
const { error, value } = Joi.validate(data, schema, {
allowUnknown: true,
stripUnknown: true,
})
const options = allowAndStripUnknownKeys
? {
allowUnknown: true,
stripUnknown: true,
}
: undefined
const { error, value } = Joi.validate(data, schema, options)
if (error) {
trace.logTrace(
'validate',
@@ -28,10 +33,16 @@ function validate(
traceErrorMessage,
error.message
)
throw new ErrorClass({
prettyMessage: prettyErrorMessage,
underlyingError: error,
})
let prettyMessage = prettyErrorMessage
if (includeKeys) {
const keys = error.details.map(({ path }) => path)
if (keys) {
prettyMessage = `${prettyErrorMessage}: ${keys.join(', ')}`
}
}
throw new ErrorClass({ prettyMessage, underlyingError: error })
} else {
trace.logTrace('validate', emojic.bathtub, traceSuccessMessage, value, {
deep: true,

View File

@@ -3,8 +3,8 @@
const Joi = require('joi')
const { expect } = require('chai')
const sinon = require('sinon')
const trace = require('../services/trace')
const { InvalidParameter } = require('../services/errors')
const trace = require('./trace')
const { InvalidParameter } = require('./errors')
const validate = require('./validate')
describe('validate', function() {
@@ -61,7 +61,7 @@ describe('validate', function() {
})
context('data does not match schema', function() {
it('logs the data and throws the expected error', async function() {
it('logs the data and throws the expected error', function() {
try {
validate(
options,
@@ -83,5 +83,45 @@ describe('validate', function() {
'child "requiredString" fails because ["requiredString" must be a string]'
)
})
context('with includeKeys: true', function() {
it('includes keys in the error text', function() {
try {
validate(
{ ...options, includeKeys: true },
{
requiredString: ['this', "shouldn't", 'work'],
},
schema
)
expect.fail('Expected to throw')
} catch (e) {
expect(e).to.be.an.instanceof(InvalidParameter)
expect(e.message).to.equal(
'Invalid Parameter: child "requiredString" fails because ["requiredString" must be a string]'
)
expect(e.prettyMessage).to.equal(
`${prettyErrorMessage}: requiredString`
)
}
})
})
})
it('allowAndStripUnknownKeys', function() {
try {
validate(
{ ...options, allowAndStripUnknownKeys: false, includeKeys: true },
{ requiredString: 'bar', extra: 'nonsense', more: 'bogus' },
schema
)
expect.fail('Expected to throw')
} catch (e) {
expect(e).to.be.an.instanceof(InvalidParameter)
expect(e.message).to.equal(
'Invalid Parameter: "extra" is not allowed. "more" is not allowed'
)
expect(e.prettyMessage).to.equal(`${prettyErrorMessage}: extra, more`)
}
})
})

View File

@@ -1,6 +1,6 @@
'use strict'
const { Inaccessible, InvalidResponse } = require('../services/errors')
const { Inaccessible, InvalidResponse } = require('../base-service/errors')
// Map from URL to { timestamp: last fetch time, data: data }.
let regularUpdateCache = Object.create(null)
@@ -12,7 +12,7 @@ let regularUpdateCache = Object.create(null)
// To use this from a service:
//
// const { promisify } = require('util')
// const { regularUpdate } = require('../../lib/regular-update')
// const { regularUpdate } = require('../../core/legacy/regular-update')
//
// function getThing() {
// return promisify(regularUpdate)({

View File

@@ -0,0 +1,23 @@
'use strict'
const config = require('config').util.toObject()
const Server = require('./server')
function createTestServer({ port }) {
const serverConfig = {
...config,
public: {
...config.public,
bind: {
...config.public.bind,
port,
},
},
}
return new Server(serverConfig)
}
module.exports = {
createTestServer,
}

Some files were not shown because too many files have changed in this diff Show More