adopt JSDoc, eslint-plugin-jsdoc (#3645)

eslint-plugin-jsdoc:
- install eslint-plugin-jsdoc
- config file
- fix lint/style errors

JSDoc:
- add JSDoc as a dev dependency
- get everything rendering nicely with JSDoc
- config, build command + ignores
This commit is contained in:
chris48s
2019-07-11 20:14:47 +01:00
committed by GitHub
parent ad7023bcbe
commit 38cdc0033f
21 changed files with 445 additions and 138 deletions
+1
View File
@@ -1,3 +1,4 @@
/api-docs/
/build
/coverage
/__snapshots__
+6 -1
View File
@@ -1,6 +1,7 @@
extends:
- standard
- prettier
- plugin:jsdoc/recommended
env:
node: true
@@ -44,9 +45,10 @@ overrides:
]
plugins:
- chai-friendly
- jsdoc
- mocha
- no-extension-in-require
- chai-friendly
- sort-class-members
rules:
@@ -83,3 +85,6 @@ rules:
# Chai friendly.
no-unused-expressions: 'off'
chai-friendly/no-unused-expressions: 'error'
# Disable some rules from jsdoc/recommended.
jsdoc/require-jsdoc: 0
+3
View File
@@ -110,3 +110,6 @@ service-definitions.yml
# Cypress
/cypress/videos/
/cypress/screenshots/
# Rendered API docs
/api-docs/
+1
View File
@@ -3,6 +3,7 @@ package-lock.json
/__snapshots__
/.next
/.cache
/api-docs
/build
/public
/coverage
+1 -1
View File
@@ -1,5 +1,5 @@
<p align="center">
<img src="./frontend/images/logo.svg"
<img src="https://raw.githubusercontent.com/badges/shields/master/frontend/images/logo.svg?sanitize=true"
height="130">
</p>
<p align="center">
+117 -82
View File
@@ -1,4 +1,7 @@
'use strict'
/**
* @module
*/
const decamelize = require('decamelize')
// See available emoji at http://emoji.muan.co/
@@ -72,18 +75,17 @@ const serviceDataSchema = Joi.object({
.required()
/**
* BaseService
*
* Abstract base class which all service classes inherit from.
* Concrete implementations of BaseService must implement the methods
* category(), route() and handle(namedParams, queryParams)
*/
module.exports = class BaseService {
class BaseService {
/**
* Name of the category to sort this badge into (eg. "build"). Used to sort
* the badges on the main shields.io website.
*
* @abstract
* @return {string}
* @type {string}
*/
static get category() {
throw new Error(`Category not set for ${this.name}`)
@@ -97,38 +99,7 @@ module.exports = class BaseService {
* Route to mount this service on
*
* @abstract
* @return {object} route
* @return {string} route.base
* (Optional) The base path of the routes for this service.
* This is used as a prefix.
* @return {string} route.pattern
* A path-to-regexp pattern defining the route pattern and param names
* See https://www.npmjs.com/package/path-to-regexp
* @return {Regexp} route.format
* Deprecated: Regular expression to use for routes for this service's badges
* Use `pattern` instead
* @return {string[]} route.capture
* Deprecated: Array of names for the capture groups in the regular
* expression. The handler will be passed an object containing
* the matches.
* Use `pattern` instead
* @return {Joi.object} route.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.)
* @type {module:core/base-service/base~Route}
*/
static get route() {
throw new Error(`Route not defined for ${this.name}`)
@@ -138,33 +109,25 @@ module.exports = class BaseService {
* Configuration for the authentication helper that prepares credentials
* for upstream requests.
*
* @abstract
* @return {object} auth
* @return {string} auth.userKey
* (Optional) The key from `privateConfig` to use as the username.
* @return {string} auth.passKey
* (Optional) The key from `privateConfig` to use as the password.
* If auth is configured, either `userKey` or `passKey` is required.
* @return {string} auth.isRequired
* (Optional) If `true`, the service will return `NotFound` unless the
* configured credentials are present.
*
* See also the config schema in `./server.js` and `doc/server-secrets.md`.
*
* To use the configured auth in the handler or fetch method, pass the
* credentials to the request. For example:
* `{ options: { auth: this.authHelper.basicAuth } }`
* `{ options: { headers: this.authHelper.bearerAuthHeader } }`
* `{ options: { qs: { token: this.authHelper.pass } } }`
* - `{ options: { auth: this.authHelper.basicAuth } }`
* - `{ options: { headers: this.authHelper.bearerAuthHeader } }`
* - `{ options: { qs: { token: this.authHelper.pass } } }`
*
* @abstract
* @type {module:core/base-service/base~Auth}
*/
static get auth() {
return undefined
}
/**
* 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.
* Array of Example objects describing 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
@@ -173,25 +136,9 @@ module.exports = class BaseService {
* For services which use a route `format`, the `pattern` can be specified as
* part of the example.
*
* An example object has the following structure:
* 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.
*
* @see {@link module:core/base-service/base~Example}
* @abstract
* @return {Object[]} Array of Example objects
* @type {module:core/base-service/base~Example[]}
*/
static get examples() {
return []
@@ -212,11 +159,7 @@ module.exports = class BaseService {
* 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.
*
* @return {object} defaultBadgeData
* @return {string} defaultBadgeData.label (Optional)
* @return {string} defaultBadgeData.color (Optional)
* @return {string} defaultBadgeData.labelColor (Optional)
* @return {string} defaultBadgeData.namedLogo (Optional)
* @type {module:core/base-service/base~DefaultBadgeData}
*/
static get defaultBadgeData() {
return {}
@@ -313,12 +256,8 @@ module.exports = class BaseService {
* @param {object} namedParams Params parsed from route pattern
* defined in this.route.pattern or this.route.capture
* @param {object} queryParams Params parsed from the query string
* @returns {object} badge Object validated against serviceDataSchema
* @return {boolean} badge.isError (Optional)
* @return {string} badge.label (Optional)
* @return {(string|number)} badge.message
* @return {string} badge.color (Optional)
* @return {string[]} badge.link (Optional)
* @returns {module:core/base-service/base~Badge}
* badge Object validated against serviceDataSchema
*/
async handle(namedParams, queryParams) {
throw new Error(`Handler not implemented for ${this.constructor.name}`)
@@ -509,3 +448,99 @@ module.exports = class BaseService {
)
}
}
/**
* Default badge properties, validated against defaultBadgeDataSchema
*
* @typedef {object} DefaultBadgeData
* @property {string} label (Optional)
* @property {string} color (Optional)
* @property {string} labelColor (Optional)
* @property {string} namedLogo (Optional)
*/
/**
* Badge Object, validated against serviceDataSchema
*
* @typedef {object} Badge
* @property {boolean} isError (Optional)
* @property {string} label (Optional)
* @property {(string|number)} message
* @property {string} color (Optional)
* @property {string[]} link (Optional)
*/
/**
* @typedef {object} Route
* @property {string} base
* (Optional) The base path of the routes for this service.
* This is used as a prefix.
* @property {string} pattern
* A path-to-regexp pattern defining the route pattern and param names
* See {@link https://www.npmjs.com/package/path-to-regexp}
* @property {RegExp} format
* Deprecated: Regular expression to use for routes for this service's badges
* Use `pattern` instead
* @property {string[]} capture
* Deprecated: Array of names for the capture groups in the regular
* expression. The handler will be passed an object containing
* the matches.
* Use `pattern` instead
* @property {Joi.object} 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.)
*/
/**
* @typedef {object} Auth
* @property {string} userKey
* (Optional) The key from `privateConfig` to use as the username.
* @property {string} passKey
* (Optional) The key from `privateConfig` to use as the password.
* If auth is configured, either `userKey` or `passKey` is required.
* @property {string} isRequired
* (Optional) If `true`, the service will return `NotFound` unless the
* configured credentials are present.
*/
/**
* @typedef {object} Example
* @property {string} 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.
* @property {object} namedParams
* An object containing the values of named parameters to
* substitute into the compiled route pattern.
* @property {object} 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`.
* @property {string} pattern
* The route pattern to compile. Defaults to `this.route.pattern`.
* @property {object} 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.
* @property {string[]} keywords
* Additional keywords, other than words in the title. This helps
* users locate relevant badges.
* @property {string} documentation
* An HTML string that is included in the badge popup.
*/
module.exports = BaseService
+9 -12
View File
@@ -1,4 +1,7 @@
'use strict'
/**
* @module
*/
const fs = require('fs')
const path = require('path')
@@ -112,14 +115,12 @@ const privateConfigSchema = Joi.object({
}).required()
/**
* Badge Server
*
* The Server is based on the web framework Scoutcamp. It creates
* an http server, sets up helpers for token persistence and monitoring.
* Then it loads all the services, injecting dependencies as it
* asks each one to register its route with Scoutcamp.
*/
module.exports = class Server {
class Server {
/**
* Badge Server Constructor
*
@@ -179,8 +180,6 @@ module.exports = class Server {
}
/**
* Register Error Handlers
*
* Set up Scoutcamp routes for 404/not found responses
*/
registerErrorHandlers() {
@@ -229,8 +228,6 @@ module.exports = class Server {
}
/**
* Register Services
*
* Iterate all the service classes defined in /services,
* load each service and register a Scoutcamp route for each service.
*/
@@ -255,12 +252,11 @@ module.exports = class Server {
}
/**
* Register Redirects
*
* Set up a couple of redirects:
* One for the raster badges.
* Another to redirect the base URL /
* (we use this to redirect https://img.shields.io/ to https://shields.io/ )
* (we use this to redirect {@link https://img.shields.io/}
* to {@link https://shields.io/} )
*/
registerRedirects() {
const { config, camp } = this
@@ -297,8 +293,7 @@ module.exports = class Server {
}
/**
* Start the HTTP server
*
* Start the HTTP server:
* Bootstrap Scoutcamp,
* Register handlers,
* Start listening for requests on this.baseUrl()
@@ -375,3 +370,5 @@ module.exports = class Server {
}
}
}
module.exports = Server
@@ -1,4 +1,7 @@
'use strict'
/**
* @module
*/
const caller = require('caller')
const BaseService = require('../base-service/base')
@@ -13,7 +16,8 @@ const ServiceTester = require('./service-tester')
* This can't be used for `.service.js` files which export more than one
* service.
*
* @return {ServiceTester} ServiceTester instance
* @returns {module:core/service-test-runner/service-tester~ServiceTester}
* ServiceTester instance
*/
function createServiceTester() {
const servicePath = caller().replace('.tester.js', '.service.js')
@@ -1,4 +1,7 @@
'use strict'
/**
* @module
*/
const Joi = require('@hapi/joi')
const { expect } = require('chai')
@@ -7,7 +10,10 @@ const { expect } = require('chai')
* Factory which wraps an "icedfrisby-nock" with some additional functionality:
* - check if a request was intercepted
* - set expectations on the badge JSON response
*
* @param {Function} superclass class to extend
* @see https://github.com/paulmelnikow/icedfrisby-nock/blob/master/icedfrisby-nock.js
* @returns {Function} wrapped class
*/
const factory = superclass =>
class IcedFrisbyNock extends superclass {
+17 -7
View File
@@ -1,4 +1,7 @@
'use strict'
/**
* @module
*/
const { URL, format: urlFormat } = require('url')
@@ -64,13 +67,9 @@ function _inferPullRequestFromCircleEnv(env) {
* When called inside a CI build, infer the details
* of a pull request from the environment variables.
*
* @param {object} [env=process.env]
* @return {object} pr
* @return {string} pr.baseUrl (returned for travis CI only)
* @return {string} pr.owner
* @return {string} pr.repo
* @return {string} pr.pullRequest PR/issue number
* @return {string} pr.slug owner/repo/#pullRequest
* @param {object} [env=process.env] Environment variables
* @returns {module:core/service-test-runner/infer-pull-request~PullRequest}
* Pull Request
*/
function inferPullRequest(env = process.env) {
if (env.TRAVIS) {
@@ -88,6 +87,17 @@ function inferPullRequest(env = process.env) {
}
}
/**
* Pull Request
*
* @typedef PullRequest
* @property {string} pr.baseUrl (returned for travis CI only)
* @property {string} owner
* @property {string} repo
* @property {string} pullRequest PR/issue number
* @property {string} slug owner/repo/#pullRequest
*/
module.exports = {
parseGithubPullRequestUrl,
parseGithubRepoSlug,
+3
View File
@@ -1,4 +1,7 @@
'use strict'
/**
* @module
*/
const { loadTesters } = require('../base-service/loader')
+11 -5
View File
@@ -1,4 +1,7 @@
'use strict'
/**
* @module
*/
const emojic = require('emojic')
const trace = require('../base-service/trace')
@@ -17,9 +20,9 @@ class ServiceTester {
/**
* Service Tester Constructor
*
* @param {object} attrs
* @param {object} attrs Refer to individual attrs
* @param {string} attrs.id
* Secifies which tests to run from the CLI or pull requests
* Specifies which tests to run from the CLI or pull requests
* @param {string} attrs.title
* Prints in the Mocha output
* @param {string} attrs.path
@@ -44,6 +47,8 @@ class ServiceTester {
*
* @param {Function} ServiceClass
* A class that extends base-service/base.BaseService
* @returns {module:core/service-test-runner/service-tester~ServiceTester}
* ServiceTester for ServiceClass
*/
static forServiceClass(ServiceClass) {
const id = ServiceClass.name
@@ -65,13 +70,13 @@ class ServiceTester {
/**
* Create a new test. The hard work is delegated to IcedFrisby.
* https://github.com/MarkHerhold/IcedFrisby/#show-me-some-code
* {@link https://github.com/MarkHerhold/IcedFrisby/#show-me-some-code}
*
* Note: The caller should not invoke toss() on the Frisby chain, as it's
* invoked automatically by the tester.
*
* @param {string} msg The name of the test
* @return {IcedFrisby} IcedFrisby instance
* @returns {module:icedfrisby~IcedFrisby} IcedFrisby instance
*/
create(msg) {
const spec = frisby
@@ -107,7 +112,7 @@ class ServiceTester {
/**
* Register the tests with Mocha.
*
* @param {object} attrs
* @param {object} attrs Refer to individual attrs
* @param {string} attrs.baseUrl base URL for test server
* @param {boolean} attrs.skipIntercepted skip tests which intercept requests
*/
@@ -130,4 +135,5 @@ class ServiceTester {
})
}
}
module.exports = ServiceTester
@@ -1,4 +1,7 @@
'use strict'
/**
* @module
*/
const difference = require('lodash.difference')
@@ -8,9 +11,10 @@ const difference = require('lodash.difference')
* extract the list of service names in square brackets
* as an array of strings.
*
* @return {string[]}
* @param {string} title Pull Request title
* @returns {string[]} Array of service names
*/
module.exports = function servicesForTitle(title) {
function servicesForTitle(title) {
const bracketed = /\[([^\]]+)\]/g
const preNormalized = title.toLowerCase()
@@ -26,3 +30,5 @@ module.exports = function servicesForTitle(title) {
const ignored = ['wip', 'rfc', 'security']
return difference(services, ignored)
}
module.exports = servicesForTitle
+14 -13
View File
@@ -1,4 +1,7 @@
'use strict'
/**
* @module
*/
const crypto = require('crypto')
const PriorityQueue = require('priorityqueuejs')
@@ -6,7 +9,8 @@ const PriorityQueue = require('priorityqueuejs')
/**
* Compute a one-way hash of the input string.
*
* @return {string}
* @param {string} id token
* @returns {string} hash
*/
function sanitizeToken(id) {
return crypto
@@ -30,7 +34,7 @@ class Token {
* Token Constructor
*
* @param {string} id token string
* @param data
* @param {*} data reserved for future use
* @param {number} usesRemaining
* Number of uses remaining until the token is exhausted
* @param {number} nextReset
@@ -186,9 +190,9 @@ class TokenPool {
/**
* compareTokens
*
* @param {Token} first
* @param {Token} second
* @return {Token} The token whose current rate allotment is expiring soonest.
* @param {module:core/token-pooling/token-pool~Token} first first token to compare
* @param {module:core/token-pooling/token-pool~Token} second second token to compare
* @returns {module:core/token-pooling/token-pool~Token} The token whose current rate allotment is expiring soonest.
*/
static compareTokens(first, second) {
return second.nextReset - first.nextReset
@@ -197,17 +201,14 @@ class TokenPool {
/**
* Add a token with user-provided ID and data.
*
* @param id
* The ID can be a primitive value or an object reference, and is used
* (with `Set`) for deduplication. If a token already exists with a
* given id, it will be ignored.
* @param data
* @param {string} id token string
* @param {*} data reserved for future use
* @param {number} usesRemaining
* Number of uses remaining until the token is exhausted
* @param {number} nextReset
* Time when the token can be used again even if it's exhausted (unix timestamp)
*
* @return {boolean} Was the token added to the pool?
* @returns {boolean} Was the token added to the pool?
*/
add(id, data, usesRemaining, nextReset) {
if (this.tokenIds.has(id)) {
@@ -289,7 +290,7 @@ class TokenPool {
* new use-remaining count and next-reset time. Invoke `invalidate()` to
* indicate it should not be reused.
*
* @return {Token}
* @returns {module:core/token-pooling/token-pool~Token} token
*/
next() {
let token = this.currentBatch.token
@@ -314,7 +315,7 @@ class TokenPool {
/**
* Iterate over all valid tokens.
*
* @param {Function} callback
* @param {Function} callback function to execute on each valid token
*/
forEach(callback) {
function visit(item) {
+1 -1
View File
@@ -1,6 +1,6 @@
'use strict'
/**
/*
* Implement Gatsby's Node APIs in this file.
*
* See: https://www.gatsbyjs.org/docs/node-apis/
+17 -10
View File
@@ -1,7 +1,13 @@
'use strict'
/**
* @module gh-badges
*/
const makeBadge = require('./make-badge')
/**
* BadgeFactory
*/
class BadgeFactory {
constructor(options) {
if (options !== undefined) {
@@ -14,16 +20,17 @@ class BadgeFactory {
/**
* Create a badge
*
* @param {object} format - Object specifying badge data
* @param {string[]} format.text
* @param {string} format.labelColor - label color
* @param {string} format.color - message color
* @param {string} format.colorA - deprecated: alias for `labelColor`
* @param {string} format.colorscheme - deprecated: alias for `color`
* @param {string} format.colorB - deprecated: alias for `color`
* @param {string} format.format
* @param {string} format.template
* @return {string} Badge in SVG or JSON format
* @param {object} format Object specifying badge data
* @param {string[]} format.text Badge text in an array e.g: ['build', 'passing']
* @param {string} format.labelColor (Optional) Label color
* @param {string} format.color (Optional) Message color
* @param {string} format.colorA (Deprecated, Optional) alias for `labelColor`
* @param {string} format.colorscheme (Deprecated, Optional) alias for `color`
* @param {string} format.colorB (Deprecated, Optional) alias for `color`
* @param {string} format.format (Optional) Output format: 'svg' or 'json'
* @param {string} format.template (Optional) Visual template e.g: 'flat'
* see {@link https://github.com/badges/shields/tree/master/gh-badges/templates}
* @returns {string} Badge in SVG or JSON format
* @see https://github.com/badges/shields/tree/master/gh-badges/README.md
*/
create(format) {
+20
View File
@@ -0,0 +1,20 @@
{
"source": {
"exclude": [
"__snapshots__",
"build",
"coverage",
"logo",
"node_modules",
"private",
"public"
]
},
"plugins": ["plugins/markdown"],
"opts": {
"destination": "api-docs/",
"readme": "README.md",
"recurse": true,
"tutorials": "doc/"
}
}
+190
View File
@@ -4828,6 +4828,15 @@
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
},
"catharsis": {
"version": "0.8.10",
"resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.8.10.tgz",
"integrity": "sha512-l2OUaz/3PU3MZylspVFJvwHCVfWyvcduPq4lv3AzZ2pJzZCo7kNKFNyatwujD7XgvGkNAE/Jhhbh2uARNwNkfw==",
"dev": true,
"requires": {
"lodash": "^4.17.11"
}
},
"chai": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz",
@@ -5990,6 +5999,12 @@
"integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==",
"dev": true
},
"comment-parser": {
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-0.5.5.tgz",
"integrity": "sha512-oB3TinFT+PV3p8UwDQt71+HkG03+zwPwikDlKU6ZDmql6QX2zFlQ+G0GGSDqyJhdZi4PSlzFBm+YJ+ebOX3Vgw==",
"dev": true
},
"common-tags": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz",
@@ -8976,6 +8991,36 @@
}
}
},
"eslint-plugin-jsdoc": {
"version": "10.0.3",
"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-10.0.3.tgz",
"integrity": "sha512-aTlXmX4iCWf/vZyzcT13ggrHG6WW1QFvFbtrAVHU+Llcm1T7cvS/zQgPdRms2fY5XR4qBmsfeUuLe7RsszzhxQ==",
"dev": true,
"requires": {
"comment-parser": "^0.5.5",
"debug": "^4.1.1",
"flat-map-polyfill": "^0.3.8",
"jsdoctypeparser": "4.0.0",
"lodash": "^4.17.11"
},
"dependencies": {
"debug": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
"dev": true,
"requires": {
"ms": "^2.1.1"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
}
}
},
"eslint-plugin-jsx-a11y": {
"version": "6.2.3",
"resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.3.tgz",
@@ -10121,6 +10166,12 @@
"write": "1.0.3"
}
},
"flat-map-polyfill": {
"version": "0.3.8",
"resolved": "https://registry.npmjs.org/flat-map-polyfill/-/flat-map-polyfill-0.3.8.tgz",
"integrity": "sha512-ZfmD5MnU7GglUEhiky9C7yEPaNq1/wh36RDohe+Xr3nJVdccwHbdTkFIYvetcdsoAckUKT51fuf44g7Ni5Doyg==",
"dev": true
},
"flatted": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.0.tgz",
@@ -14331,12 +14382,75 @@
}
}
},
"js2xmlparser": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.0.tgz",
"integrity": "sha512-WuNgdZOXVmBk5kUPMcTcVUpbGRzLfNkv7+7APq7WiDihpXVKrgxo6wwRpRl9OQeEBgKCVk9mR7RbzrnNWC8oBw==",
"dev": true,
"requires": {
"xmlcreate": "^2.0.0"
}
},
"jsbn": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
"optional": true
},
"jsdoc": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.2.tgz",
"integrity": "sha512-S2vzg99C5+gb7FWlrK4TVdyzVPGGkdvpDkCEJH1JABi2PKzPeLu5/zZffcJUifgWUJqXWl41Hoc+MmuM2GukIg==",
"dev": true,
"requires": {
"@babel/parser": "^7.4.4",
"bluebird": "^3.5.4",
"catharsis": "^0.8.10",
"escape-string-regexp": "^2.0.0",
"js2xmlparser": "^4.0.0",
"klaw": "^3.0.0",
"markdown-it": "^8.4.2",
"markdown-it-anchor": "^5.0.2",
"marked": "^0.6.2",
"mkdirp": "^0.5.1",
"requizzle": "^0.2.2",
"strip-json-comments": "^3.0.1",
"taffydb": "2.6.2",
"underscore": "~1.9.1"
},
"dependencies": {
"@babel/parser": {
"version": "7.5.0",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.5.0.tgz",
"integrity": "sha512-I5nW8AhGpOXGCCNYGc+p7ExQIBxRFnS2fd/d862bNOKvmoEPjYPcfIjsfdy0ujagYOIYPczKgD9l3FsgTkAzKA==",
"dev": true
},
"bluebird": {
"version": "3.5.5",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz",
"integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==",
"dev": true
},
"strip-json-comments": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz",
"integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==",
"dev": true
},
"underscore": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz",
"integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==",
"dev": true
}
}
},
"jsdoctypeparser": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/jsdoctypeparser/-/jsdoctypeparser-4.0.0.tgz",
"integrity": "sha512-Bh6AW8eJ1bVdofhYUuqgFOVo0FE9qII+a+Go+juEnAfaDS5lZAiIqBAFm9gDu80OqBcQ1UI3v/8cP+3D5IGVww==",
"dev": true
},
"jsdom": {
"version": "7.2.2",
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-7.2.2.tgz",
@@ -14577,6 +14691,15 @@
"is-buffer": "^1.1.5"
}
},
"klaw": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz",
"integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==",
"dev": true,
"requires": {
"graceful-fs": "^4.1.9"
}
},
"kleur": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
@@ -14654,6 +14777,15 @@
"integrity": "sha1-IsWbyu+qmo7zWc91l4TkvxBq6hs=",
"dev": true
},
"linkify-it": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.1.0.tgz",
"integrity": "sha512-4REs8/062kV2DSHxNfq5183zrqXMl7WP0WzABH9IeJI+NLm429FgE1PDecltYfnOoFDFlZGh2T8PfZn0r+GTRg==",
"dev": true,
"requires": {
"uc.micro": "^1.0.1"
}
},
"lint-staged": {
"version": "8.1.7",
"resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-8.1.7.tgz",
@@ -15360,6 +15492,31 @@
"object-visit": "^1.0.0"
}
},
"markdown-it": {
"version": "8.4.2",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz",
"integrity": "sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==",
"dev": true,
"requires": {
"argparse": "^1.0.7",
"entities": "~1.1.1",
"linkify-it": "^2.0.0",
"mdurl": "^1.0.1",
"uc.micro": "^1.0.5"
}
},
"markdown-it-anchor": {
"version": "5.2.4",
"resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.2.4.tgz",
"integrity": "sha512-n8zCGjxA3T+Mx1pG8HEgbJbkB8JFUuRkeTZQuIM8iPY6oQ8sWOPRZJDFC9a/pNg2QkHEjjGkhBEl/RSyzaDZ3A==",
"dev": true
},
"marked": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/marked/-/marked-0.6.3.tgz",
"integrity": "sha512-Fqa7eq+UaxfMriqzYLayfqAE40WN03jf+zHjT18/uXNuzjq3TY0XTbrAoPeqSJrAmPz11VuUA+kBPYOhHt9oOQ==",
"dev": true
},
"matcher": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/matcher/-/matcher-1.1.1.tgz",
@@ -15420,6 +15577,12 @@
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-1.1.4.tgz",
"integrity": "sha512-FSYbp3lyKjyj3E7fMl6rYvUdX0FBXaluGqlFoYESWQlyUTq8R+wp0rkFxoYFqZlHCvsUXGjyJmLQSnXToYhOSA=="
},
"mdurl": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
"integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=",
"dev": true
},
"meant": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/meant/-/meant-1.0.1.tgz",
@@ -20871,6 +21034,15 @@
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
"dev": true
},
"requizzle": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.2.tgz",
"integrity": "sha512-oJ6y7JcUJkblRGhMByGNcszeLgU0qDxNKFCiUZR1XyzHyVsev+Mxb1tyygxLd1ORsKee1SA5BInFdUwY64GE/A==",
"dev": true,
"requires": {
"lodash": "^4.17.11"
}
},
"resolve": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz",
@@ -22875,6 +23047,12 @@
}
}
},
"taffydb": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz",
"integrity": "sha1-fLy2S1oUG2ou/CxdLGe04VCyomg=",
"dev": true
},
"tapable": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz",
@@ -23504,6 +23682,12 @@
"ucfirst": "^1.0.0"
}
},
"uc.micro": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
"integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==",
"dev": true
},
"ucfirst": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/ucfirst/-/ucfirst-1.0.0.tgz",
@@ -24877,6 +25061,12 @@
"integrity": "sha1-TYuPHszTQZqjYgYb7O9RXh5VljU=",
"optional": true
},
"xmlcreate": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.1.tgz",
"integrity": "sha512-MjGsXhKG8YjTKrDCXseFo3ClbMGvUD4en29H2Cev1dv4P/chlpw6KdYmlCWDkhosBVKRDjM836+3e3pm1cBNJA==",
"dev": true
},
"xmldom": {
"version": "0.1.27",
"resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz",
+4 -1
View File
@@ -111,7 +111,8 @@
"start": "concurrently --names server,frontend \"npm run start:server\" \"cross-env GATSBY_BASE_URL=http://localhost:8080 gatsby develop --port 3000\"",
"e2e": "start-server-and-test start http://localhost:3000 test:e2e",
"e2e-on-build": "cross-env CYPRESS_baseUrl=http://localhost:8080 start-server-and-test start:server:e2e-on-build http://localhost:8080 test:e2e",
"badge": "cross-env NODE_CONFIG_ENV=test TRACE_SERVICES=true node scripts/badge-cli.js"
"badge": "cross-env NODE_CONFIG_ENV=test TRACE_SERVICES=true node scripts/badge-cli.js",
"build-docs": "rimraf api-docs/ && jsdoc --pedantic -c ./jsdoc.json ."
},
"lint-staged": {
"**/*.js": [
@@ -172,6 +173,7 @@
"eslint-plugin-chai-friendly": "^0.4.1",
"eslint-plugin-cypress": "^2.2.1",
"eslint-plugin-import": "^2.18.0",
"eslint-plugin-jsdoc": "^10.0.3",
"eslint-plugin-mocha": "^5.3.0",
"eslint-plugin-no-extension-in-require": "^0.2.0",
"eslint-plugin-node": "^9.1.0",
@@ -196,6 +198,7 @@
"is-png": "^2.0.0",
"is-svg": "^4.2.0",
"js-yaml-loader": "^1.2.2",
"jsdoc": "^3.6.2",
"lint-staged": "^8.1.7",
"lodash.debounce": "^4.0.8",
"lodash.difference": "^4.5.0",
+1 -1
View File
@@ -65,7 +65,7 @@ module.exports = class Gerrit extends BaseJsonService {
}
}
/**
/*
* To prevent against Cross Site Script Inclusion (XSSI) attacks, Gerrit's
* JSON response body starts with a magic prefix line that must be stripped
* before feeding the rest of the response body to a JSON parser.
+10 -1
View File
@@ -1,14 +1,19 @@
'use strict'
/**
* @module
*/
const { BaseJsonService } = require('..')
/**
* The steam api is based like /{interface}/{method}/v{version}/
*
* @see https://partner.steamgames.com/doc/webapi_overview#2
*/
module.exports = class BaseSteamAPI extends BaseJsonService {
class BaseSteamAPI extends BaseJsonService {
/**
* Steam API Interface
*
* @see https://partner.steamgames.com/doc/webapi_overview#2
*/
static get interf() {
@@ -17,6 +22,7 @@ module.exports = class BaseSteamAPI extends BaseJsonService {
/**
* Steam API Method
*
* @see https://partner.steamgames.com/doc/webapi_overview#2
*/
static get method() {
@@ -25,6 +31,7 @@ module.exports = class BaseSteamAPI extends BaseJsonService {
/**
* Steam API Version
*
* @see https://partner.steamgames.com/doc/webapi_overview#2
*/
static get version() {
@@ -46,3 +53,5 @@ module.exports = class BaseSteamAPI extends BaseJsonService {
})
}
}
module.exports = BaseSteamAPI