Update to eslint 6.8.0 [appveyor githubissuedetail packagist] (#4489)

* update to eslint 6.8.0 and related packages

* Fixes for no-prototype-builtins

* Updates for explicit-function-return-type

* Add ignores for no-explicit-any

* update to eslint 6.8.0 and related packages

* Fixes for no-prototype-builtins

* Updates for explicit-function-return-type

* Add ignores for no-explicit-any

* package: activate eslint-config-standard

* apply updated eslint configuration

* lint: apply eslint feedback after rebase

* Update lockfile

* Update lockfile

* Restore missing deps

* Update lockfile

* Re-add eslint-plugin-node

* Add eslint-plugin-standard and eslint-plugin-react-hooks

* Clean lint

Co-authored-by: Paul Melnikow <github@paulmelnikow.com>
This commit is contained in:
François Hodierne
2020-02-29 11:06:36 -06:00
committed by GitHub
co-authored by Paul Melnikow
parent fe70e75f3e
commit 0d8a2d5ca0
57 changed files with 685 additions and 511 deletions
+12 -5
View File
@@ -1,7 +1,8 @@
extends:
- standard-jsx
- standard
- standard-react
- plugin:@typescript-eslint/recommended
- prettier
- prettier/@typescript-eslint
- prettier/standard
- prettier/react
@@ -39,7 +40,6 @@ overrides:
es6: true
rules:
no-console: 'off'
'@typescript-eslint/no-var-requires': off
- files:
- '**/*.@(ts|tsx)'
@@ -48,8 +48,13 @@ overrides:
parser: '@typescript-eslint/parser'
rules:
# Argh.
'@typescript-eslint/explicit-function-return-type': 'off'
'@typescript-eslint/explicit-function-return-type':
['error', { 'allowExpressions': true }]
'@typescript-eslint/no-empty-function': 'error'
'@typescript-eslint/no-var-requires': 'error'
'@typescript-eslint/no-object-literal-type-assertion': 'off'
'@typescript-eslint/no-explicit-any': 'error'
'@typescript-eslint/ban-ts-ignore': 'off'
- files:
- core/**/*.ts
@@ -113,9 +118,9 @@ rules:
# Allow unused parameters. In callbacks, removing them seems to obscure
# what the functions are doing.
'@typescript-eslint/no-unused-vars': ['error', { 'args': 'none' }]
no-unused-vars: off
no-unused-vars: 'off'
'@typescript-eslint/no-var-requires': error
'@typescript-eslint/no-var-requires': 'off'
# These should be disabled by eslint-config-prettier, but are not.
no-extra-semi: 'off'
@@ -163,6 +168,8 @@ rules:
# Disable some from TypeScript.
'@typescript-eslint/camelcase': off
'@typescript-eslint/explicit-function-return-type': 'off'
'@typescript-eslint/no-empty-function': 'off'
react/jsx-sort-props: 'error'
react-hooks/rules-of-hooks: 'error'
+3 -3
View File
@@ -14,9 +14,9 @@ describe('coalesce', function() {
given(null, [], {}).expect([])
given(null, undefined, 0, {}).expect(0)
const a = null,
c = 0,
d = 1
const a = null
const c = 0
const d = 1
let b
given(a, b, c, d).expect(0)
})
+6
View File
@@ -56,6 +56,7 @@ class NotFound extends ShieldsRuntimeError {
get name() {
return 'NotFound'
}
get defaultPrettyMessage() {
return defaultNotFoundError
}
@@ -82,6 +83,7 @@ class InvalidResponse extends ShieldsRuntimeError {
get name() {
return 'InvalidResponse'
}
get defaultPrettyMessage() {
return 'invalid'
}
@@ -107,6 +109,7 @@ class Inaccessible extends ShieldsRuntimeError {
get name() {
return 'Inaccessible'
}
get defaultPrettyMessage() {
return 'inaccessible'
}
@@ -131,6 +134,7 @@ class ImproperlyConfigured extends ShieldsRuntimeError {
get name() {
return 'ImproperlyConfigured'
}
get defaultPrettyMessage() {
return 'improperly configured'
}
@@ -156,6 +160,7 @@ class InvalidParameter extends ShieldsRuntimeError {
get name() {
return 'InvalidParameter'
}
get defaultPrettyMessage() {
return 'invalid parameter'
}
@@ -180,6 +185,7 @@ class Deprecated extends ShieldsRuntimeError {
get name() {
return 'Deprecated'
}
get defaultPrettyMessage() {
return 'no longer available'
}
+2 -2
View File
@@ -21,8 +21,8 @@ function validate(
}
const options = { abortEarly: false }
if (allowAndStripUnknownKeys) {
options['allowUnknown'] = true
options['stripUnknown'] = true
options.allowUnknown = true
options.stripUnknown = true
}
const { error, value } = schema.validate(data, options)
if (error) {
+1 -1
View File
@@ -43,7 +43,7 @@ function setRoutes({ rateLimit }, { server, metricInstance }) {
.split(/[/-]/)
.slice(0, 3)
.join('')
const referer = req.headers['referer']
const referer = req.headers.referer
if (ipRateLimit.isBanned(ip, req, res)) {
metricInstance.noteRateLimitExceeded('ip')
+1 -1
View File
@@ -24,7 +24,7 @@ describe('The server', function() {
})
it('should allow strings for port', async function() {
//fixes #4391 - This allows the app to be run using iisnode, which uses a named pipe for the port.
// fixes #4391 - This allows the app to be run using iisnode, which uses a named pipe for the port.
const pipeServer = createTestServer({
port: '\\\\.\\pipe\\9c137306-7c4d-461e-b7cf-5213a3939ad6',
})
+5
View File
@@ -55,18 +55,23 @@ class Token {
get id() {
return this._id
}
get data() {
return this._data
}
get usesRemaining() {
return this._usesRemaining
}
get nextReset() {
return this._nextReset
}
get isValid() {
return this._isValid
}
get isFrozen() {
return this._isFrozen
}
+3 -3
View File
@@ -42,8 +42,8 @@ function Example({
onClick: (example: RenderableExample, isSuggestion: boolean) => void
exampleData: RenderableExample
isBadgeSuggestion: boolean
}) {
function handleClick() {
}): JSX.Element {
function handleClick(): void {
onClick(exampleData, isBadgeSuggestion)
}
@@ -106,7 +106,7 @@ export function BadgeExamples({
areBadgeSuggestions: boolean
baseUrl?: string
onClick: (exampleData: RenderableExample, isSuggestion: boolean) => void
}) {
}): JSX.Element {
return (
<ExampleTable>
<tbody>
+11 -3
View File
@@ -12,7 +12,7 @@ export function CategoryHeading({
category: { id, name },
}: {
category: Category
}) {
}): JSX.Element {
return (
<Link to={`/category/${id}`}>
<H3 id={id}>{name}</H3>
@@ -20,7 +20,11 @@ export function CategoryHeading({
)
}
export function CategoryHeadings({ categories }: { categories: Category[] }) {
export function CategoryHeadings({
categories,
}: {
categories: Category[]
}): JSX.Element {
return (
<div>
{categories.map(category => (
@@ -61,7 +65,11 @@ const StyledNav = styled.nav`
}
`
export function CategoryNav({ categories }: { categories: Category[] }) {
export function CategoryNav({
categories,
}: {
categories: Category[]
}): JSX.Element {
return (
<StyledNav>
<ul>
+1 -1
View File
@@ -74,7 +74,7 @@ export function Badge({
height = '20px',
clickable = false,
...rest
}: BadgeProps) {
}: BadgeProps): JSX.Element {
return (
<BadgeWrapper clickable={clickable} display={display} height={height}>
{src ? <img alt={alt} src={src} {...rest} /> : nonBreakingSpace}
@@ -20,7 +20,7 @@ export function BuilderContainer({
children,
}: {
children: JSX.Element[] | JSX.Element
}) {
}): JSX.Element {
return (
<BuilderOuterContainer>
<BuilderInnerContainer>{children}</BuilderInnerContainer>
@@ -41,7 +41,7 @@ function _CopiedContentIndicator(
children: JSX.Element | JSX.Element[]
},
ref: React.Ref<CopiedContentIndicatorHandle>
) {
): JSX.Element {
const [pose, setPose] = useState('hidden')
useImperativeHandle(ref, () => ({
@@ -50,7 +50,7 @@ function _CopiedContentIndicator(
},
}))
function handlePoseComplete() {
function handlePoseComplete(): void {
if (pose === 'effectStart') {
setPose('effectEnd')
} else {
@@ -36,7 +36,7 @@ export default function Customizer({
initialStyle?: string
isPrefilled: boolean
link?: string
}) {
}): JSX.Element {
// https://github.com/DefinitelyTyped/DefinitelyTyped/issues/35572
// https://github.com/DefinitelyTyped/DefinitelyTyped/issues/28884#issuecomment-471341041
const indicatorRef = useRef<
@@ -48,12 +48,12 @@ export default function Customizer({
const [markup, setMarkup] = useState()
const [message, setMessage] = useState()
function generateBuiltBadgeUrl() {
function generateBuiltBadgeUrl(): string {
const suffix = queryString ? `?${queryString}` : ''
return `${baseUrl || getBaseUrlFromWindowLocation()}${path}${suffix}`
}
function renderLivePreview() {
function renderLivePreview(): JSX.Element {
// There are some usability issues here. It would be better if the message
// changed from a validation error to a loading message once the
// parameters were filled in, and also switched back to loading when the
@@ -75,7 +75,7 @@ export default function Customizer({
)
}
async function copyMarkup(markupFormat: MarkupFormat) {
async function copyMarkup(markupFormat: MarkupFormat): Promise<void> {
const builtBadgeUrl = generateBuiltBadgeUrl()
const markup = generateMarkup({
badgeUrl: builtBadgeUrl,
@@ -98,7 +98,7 @@ export default function Customizer({
}
}
function renderMarkupAndLivePreview() {
function renderMarkupAndLivePreview(): JSX.Element {
return (
<div>
{renderLivePreview()}
@@ -124,7 +124,7 @@ export default function Customizer({
}: {
path: string
isComplete: boolean
}) {
}): void {
setPath(path)
setPathIsComplete(isComplete)
}
@@ -135,7 +135,7 @@ export default function Customizer({
}: {
queryString: string
isComplete: boolean
}) {
}): void {
setQueryString(queryString)
}
@@ -84,7 +84,7 @@ export function constructPath({
}: {
tokens: Token[]
namedParams: { [k: string]: string }
}) {
}): { path: string; isComplete: boolean } {
let isComplete = true
const path = tokens
.map(token => {
@@ -123,7 +123,7 @@ export default function PathBuilder({
isComplete: boolean
}) => void
isPrefilled: boolean
}) {
}): JSX.Element {
const [tokens] = useState(() => parse(pattern))
const [namedParams, setNamedParams] = useState(() =>
isPrefilled
@@ -150,7 +150,7 @@ export default function PathBuilder({
function handleTokenChange({
target: { name, value },
}: ChangeEvent<HTMLInputElement | HTMLSelectElement>) {
}: ChangeEvent<HTMLInputElement | HTMLSelectElement>): void {
setNamedParams({
...namedParams,
[name]: value,
@@ -161,7 +161,7 @@ export default function PathBuilder({
literal: string,
tokenIndex: number,
pathContainsOnlyLiterals: boolean
) {
): JSX.Element {
return (
<PathBuilderColumn
key={`${tokenIndex}-${literal}`}
@@ -177,7 +177,7 @@ export default function PathBuilder({
)
}
function renderNamedParamInput(token: Key) {
function renderNamedParamInput(token: Key): JSX.Element {
const { pattern } = token
const name = `${token.name}`
const options = patternToOptions(pattern)
@@ -219,7 +219,7 @@ export default function PathBuilder({
token: Key,
tokenIndex: number,
namedParamIndex: number
) {
): JSX.Element {
const { delimiter, optional } = token
const name = `${token.name}`
@@ -113,7 +113,7 @@ function ServiceQueryParam({
isStringParam: boolean
stringParamCount?: number
handleServiceQueryParamChange: ChangeEventHandler<HTMLInputElement>
}) {
}): JSX.Element {
return (
<tr>
<td>
@@ -160,7 +160,7 @@ function BadgeOptionInput({
handleBadgeOptionChange: ChangeEventHandler<
HTMLSelectElement | HTMLInputElement
>
}) {
}): JSX.Element {
if (name === 'style') {
return (
<select name="style" onChange={handleBadgeOptionChange} value={value}>
@@ -192,7 +192,7 @@ function BadgeOption({
name: BadgeOptionName
value: string
handleBadgeOptionChange: ChangeEventHandler<HTMLInputElement>
}) {
}): JSX.Element {
const {
label = humanizeString(name),
shieldsDefaultValue: hasShieldsDefaultValue,
@@ -237,7 +237,7 @@ export default function QueryStringBuilder({
queryString: string
isComplete: boolean
}) => void
}) {
}): JSX.Element {
const [queryParams, setQueryParams] = useState(() =>
// For each of the custom query params defined in `exampleParams`,
// create empty values in `queryParams`.
@@ -266,14 +266,14 @@ export default function QueryStringBuilder({
function handleServiceQueryParamChange({
target: { name, type: targetType, checked, value },
}: ChangeEvent<HTMLInputElement>) {
}: ChangeEvent<HTMLInputElement>): void {
const outValue = targetType === 'checkbox' ? checked : value
setQueryParams({ ...queryParams, [name]: outValue })
}
function handleBadgeOptionChange({
target: { name, value },
}: ChangeEvent<HTMLInputElement>) {
}: ChangeEvent<HTMLInputElement>): void {
setBadgeOptions({ ...badgeOptions, [name]: value })
}
@@ -3,14 +3,17 @@ import styled from 'styled-components'
import Select, { components } from 'react-select'
import { MarkupFormat } from '../../lib/generate-image-markup'
const ClickableControl = (props: any) => (
<components.Control
{...props}
innerProps={{
onMouseDown: props.selectProps.onControlMouseDown,
}}
/>
)
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function ClickableControl(props: any): JSX.Element {
return (
<components.Control
{...props}
innerProps={{
onMouseDown: props.selectProps.onControlMouseDown,
}}
/>
)
}
interface Option {
value: MarkupFormat
@@ -76,14 +79,14 @@ export default function GetMarkupButton({
}: {
onMarkupRequested: (markupFormat: MarkupFormat) => Promise<void>
isDisabled: boolean
}) {
}): JSX.Element {
// https://github.com/DefinitelyTyped/DefinitelyTyped/issues/35572
// https://github.com/DefinitelyTyped/DefinitelyTyped/issues/28884#issuecomment-471341041
const selectRef = useRef<Select<Option>>() as React.MutableRefObject<
Select<Option>
>
async function onControlMouseDown(event: MouseEvent) {
async function onControlMouseDown(event: MouseEvent): Promise<void> {
if (onMarkupRequested) {
await onMarkupRequested('link')
}
@@ -18,7 +18,7 @@ const StyledTable = styled.table`
}
`
function NamedLogoTable({ logoNames }: { logoNames: string[] }) {
function NamedLogoTable({ logoNames }: { logoNames: string[] }): JSX.Element {
return (
<StyledTable>
<thead>
@@ -62,7 +62,7 @@ function NamedLogoTable({ logoNames }: { logoNames: string[] }) {
)
}
export default function LogoPage() {
export default function LogoPage(): JSX.Element {
return (
<div>
<Meta />
+1 -1
View File
@@ -5,7 +5,7 @@ const Donate = styled.div`
padding: 25px 50px;
`
export default function DonateBox() {
export default function DonateBox(): JSX.Element {
return (
<Donate>
Love Shields? Please consider{' '}
+3 -3
View File
@@ -28,7 +28,7 @@ const inputs = [
export default function DynamicBadgeMaker({
baseUrl = document.location.href,
}) {
}): JSX.Element {
const [values, setValues] = useState<State>({
datatype: '',
label: '',
@@ -44,14 +44,14 @@ export default function DynamicBadgeMaker({
function onChange({
target: { name, value },
}: ChangeEvent<HTMLInputElement | HTMLSelectElement>) {
}: ChangeEvent<HTMLInputElement | HTMLSelectElement>): void {
setValues({
...values,
[name]: value,
})
}
function onSubmit(e: React.FormEvent) {
function onSubmit(e: React.FormEvent): void {
e.preventDefault()
const { datatype, label, dataUrl, query, color, prefix, suffix } = values
+1 -1
View File
@@ -8,7 +8,7 @@ const SpacedA = styled.a`
margin-right: 10px;
`
export default function Footer({ baseUrl }: { baseUrl: string }) {
export default function Footer({ baseUrl }: { baseUrl: string }): JSX.Element {
return (
<section>
<H2 id="like-this">Like This?</H2>
+1 -1
View File
@@ -8,7 +8,7 @@ const Highlights = styled.p`
font-style: italic;
`
export default function Header() {
export default function Header(): JSX.Element {
return (
<section>
<Link to="/">
+14 -7
View File
@@ -38,7 +38,11 @@ interface PageContext {
category?: Category
}
export default function Main({ pageContext }: { pageContext: PageContext }) {
export default function Main({
pageContext,
}: {
pageContext: PageContext
}): JSX.Element {
const [searchIsInProgress, setSearchIsInProgress] = useState(false)
const [queryIsTooShort, setQueryIsTooShort] = useState(false)
const [searchResults, setSearchResults] = useState<{
@@ -51,7 +55,7 @@ export default function Main({ pageContext }: { pageContext: PageContext }) {
] = useState(false)
const searchTimeout = useRef(0)
function performSearch(query: string) {
function performSearch(query: string): void {
setSearchIsInProgress(false)
setQueryIsTooShort(query.length === 1)
@@ -67,7 +71,7 @@ export default function Main({ pageContext }: { pageContext: PageContext }) {
}
}
function searchQueryChanged(query: string) {
function searchQueryChanged(query: string): void {
/*
Add a small delay before showing search results
so that we wait until the user has stopped typing
@@ -83,12 +87,15 @@ export default function Main({ pageContext }: { pageContext: PageContext }) {
searchTimeout.current = window.setTimeout(() => performSearch(query), 500)
}
function exampleClicked(example: RenderableExample, isSuggestion: boolean) {
function exampleClicked(
example: RenderableExample,
isSuggestion: boolean
): void {
setSelectedExample(example)
setSelectedExampleIsSuggestion(isSuggestion)
}
function dismissMarkupModal() {
function dismissMarkupModal(): void {
setSelectedExample(undefined)
}
@@ -98,7 +105,7 @@ export default function Main({ pageContext }: { pageContext: PageContext }) {
}: {
category: Category
definitions: ServiceDefinition[]
}) {
}): JSX.Element {
const flattened = definitions.reduce((accum, current) => {
const { examples } = current
return accum.concat(examples)
@@ -117,7 +124,7 @@ export default function Main({ pageContext }: { pageContext: PageContext }) {
)
}
function renderMain() {
function renderMain(): JSX.Element | JSX.Element[] {
const { category } = pageContext
if (searchIsInProgress) {
+1 -1
View File
@@ -19,7 +19,7 @@ export function MarkupModal({
isBadgeSuggestion: boolean
baseUrl: string
onRequestClose: () => void
}) {
}): JSX.Element {
return (
<Modal
ariaHideApp={false}
@@ -22,7 +22,7 @@ export function MarkupModalContent({
example: RenderableExample
isBadgeSuggestion: boolean
baseUrl: string
}) {
}): JSX.Element {
let documentation: { __html: string } | undefined
let link: string | undefined
if (isBadgeSuggestion) {
+1 -1
View File
@@ -7,7 +7,7 @@ const description = `We serve fast and scalable informational images as badges
for GitHub, Travis CI, Jenkins, WordPress and many more services. Use them to
track the state of your projects, or for promotional purposes.`
export default function Meta() {
export default function Meta(): JSX.Element {
return (
<Helmet>
<title>
+1 -1
View File
@@ -50,7 +50,7 @@ export function Snippet({
snippet: string
truncate?: boolean
fontSize?: string
}) {
}): JSX.Element {
return (
<CodeContainer truncate={truncate}>
<ClickToSelect>
+5 -3
View File
@@ -5,7 +5,9 @@ import { InlineInput } from './common'
type StateKey = 'label' | 'message' | 'color'
type State = Record<StateKey, string>
export default function StaticBadgeMaker({ baseUrl = document.location.href }) {
export default function StaticBadgeMaker({
baseUrl = document.location.href,
}): JSX.Element {
const [values, setValues] = useState<State>({
label: '',
message: '',
@@ -16,14 +18,14 @@ export default function StaticBadgeMaker({ baseUrl = document.location.href }) {
function onChange({
target: { name, value },
}: ChangeEvent<HTMLInputElement | HTMLSelectElement>) {
}: ChangeEvent<HTMLInputElement | HTMLSelectElement>): void {
setValues({
...values,
[name]: value,
})
}
function onSubmit(e: React.FormEvent) {
function onSubmit(e: React.FormEvent): void {
e.preventDefault()
const { label, message, color } = values
@@ -32,7 +32,7 @@ export default function SuggestionAndSearch({
queryChanged: (query: string) => void
onBadgeClick: (example: RenderableExample, isSuggestion: boolean) => void
baseUrl: string
}) {
}): JSX.Element {
const queryChangedDebounced = useRef(
debounce(queryChanged, 50, { leading: true })
)
@@ -43,7 +43,7 @@ export default function SuggestionAndSearch({
function onQueryChanged({
target: { value: query },
}: ChangeEvent<HTMLInputElement>) {
}: ChangeEvent<HTMLInputElement>): void {
const isUrl = query.startsWith('https://') || query.startsWith('http://')
setIsUrl(isUrl)
setProjectUrl(isUrl ? query : undefined)
@@ -51,7 +51,7 @@ export default function SuggestionAndSearch({
queryChangedDebounced.current(query)
}
async function getSuggestions() {
async function getSuggestions(): Promise<void> {
if (!projectUrl) {
setSuggestions([])
return
@@ -77,7 +77,7 @@ export default function SuggestionAndSearch({
setSuggestions(suggestions)
}
function renderSuggestions() {
function renderSuggestions(): JSX.Element | null {
if (suggestions.length === 0) {
return null
}
+7 -7
View File
@@ -44,7 +44,7 @@ function QueryParam({
}: {
snippet: string
documentation: JSX.Element | JSX.Element[]
}) {
}): JSX.Element {
return (
<tr>
<QueryParamSyntax>
@@ -61,7 +61,7 @@ function EscapingConversion({
}: {
lhs: JSX.Element
rhs: JSX.Element
}) {
}): JSX.Element {
return (
<tr>
<Lhs>{lhs}</Lhs>
@@ -77,7 +77,7 @@ function ColorExamples({
}: {
baseUrl: string
colors: string[]
}) {
}): JSX.Element {
return (
<span>
{colors.map((color, i) => (
@@ -91,7 +91,7 @@ function ColorExamples({
)
}
function StyleExamples({ baseUrl }: { baseUrl: string }) {
function StyleExamples({ baseUrl }: { baseUrl: string }): JSX.Element {
return (
<QueryParamTable>
<tbody>
@@ -118,7 +118,7 @@ function StyleExamples({ baseUrl }: { baseUrl: string }) {
)
}
function NamedLogos() {
function NamedLogos(): JSX.Element {
const renderLogo = (logo: string): JSX.Element => (
<LogoName key={logo}>{logo}</LogoName>
)
@@ -132,7 +132,7 @@ function NamedLogos() {
return <>{result}</>
}
function StaticBadgeEscapingRules() {
function StaticBadgeEscapingRules(): JSX.Element {
return (
<EscapingRuleTable>
<tbody>
@@ -180,7 +180,7 @@ function StaticBadgeEscapingRules() {
)
}
export default function Usage({ baseUrl }: { baseUrl: string }) {
export default function Usage({ baseUrl }: { baseUrl: string }): JSX.Element {
return (
<section>
<H2 id="your-badge">Your Badge</H2>
+16 -8
View File
@@ -1,8 +1,8 @@
export function bareLink(badgeUrl: string, link?: string, title = '') {
export function bareLink(badgeUrl: string, link?: string, title = ''): string {
return badgeUrl
}
export function html(badgeUrl: string, link?: string, title?: string) {
export function html(badgeUrl: string, link?: string, title?: string): string {
// To be more robust, this should escape the title.
const alt = title ? ` alt="${title}"` : ''
const img = `<img${alt} src="${badgeUrl}">`
@@ -13,7 +13,11 @@ export function html(badgeUrl: string, link?: string, title?: string) {
}
}
export function markdown(badgeUrl: string, link?: string, title?: string) {
export function markdown(
badgeUrl: string,
link?: string,
title?: string
): string {
const withoutLink = `![${title || ''}](${badgeUrl})`
if (link) {
return `[${withoutLink}](${link})`
@@ -26,7 +30,7 @@ export function reStructuredText(
badgeUrl: string,
link?: string,
title?: string
) {
): string {
let result = `.. image:: ${badgeUrl}`
if (title) {
result += ` :alt: ${title}`
@@ -37,7 +41,7 @@ export function reStructuredText(
return result
}
function quoteAsciiDocAttribute(attr: string | null) {
function quoteAsciiDocAttribute(attr: string | null): string {
if (attr == null) {
return 'None'
} else {
@@ -61,7 +65,7 @@ function mapValues(
export function renderAsciiDocAttributes(
positional: string[],
named: { [k: string]: string | null }
) {
): string {
// http://asciidoc.org/userguide.html#X21
const needsQuoting =
positional.some(attr => attr && attr.includes(',')) ||
@@ -83,7 +87,11 @@ export function renderAsciiDocAttributes(
}
}
export function asciiDoc(badgeUrl: string, link?: string, title?: string) {
export function asciiDoc(
badgeUrl: string,
link?: string,
title?: string
): string {
const positional = title ? [title] : []
const named = link ? { link } : ({} as { [k: string]: string })
const attrs = renderAsciiDocAttributes(positional, named)
@@ -102,7 +110,7 @@ export function generateMarkup({
link?: string
title?: string
markupFormat: MarkupFormat
}) {
}): string {
const generatorFn = {
markdown,
rst: reStructuredText,
+1 -1
View File
@@ -1,6 +1,6 @@
import { navigate } from 'gatsby'
export default function redirectLegacyRoutes() {
export default function redirectLegacyRoutes(): void {
const { hash } = window.location
if (hash && hash.startsWith('#/examples/')) {
const category = hash.replace('#/examples/', '')
+5 -3
View File
@@ -53,13 +53,15 @@ export interface ServiceDefinition {
export const services = definitions.services as ServiceDefinition[]
export const categories = definitions.categories as Category[]
export function findCategory(category: string) {
export function findCategory(category: string): Category | undefined {
return categories.find(({ id }) => id === category)
}
const byCategory = groupBy(services, 'category')
export function getDefinitionsForCategory(category: string) {
return byCategory[category]
export function getDefinitionsForCategory(
category: string
): ServiceDefinition[] {
return byCategory[category] || []
}
export interface Suggestion {
@@ -3,10 +3,12 @@ import { predicateFromQuery } from './service-definition-set-helper'
import { Example } from '.'
describe('Badge example functions', function() {
const exampleMatchesQuery = (
function exampleMatchesQuery(
{ examples }: { examples: Example[] },
query: string
) => predicateFromQuery(query)({ examples })
): boolean {
return predicateFromQuery(query)({ examples })
}
test(exampleMatchesQuery, () => {
forCases([given({ examples: [{ title: 'node version' }] }, 'npm')]).expect(
@@ -1,13 +1,15 @@
import escapeStringRegexp from 'escape-string-regexp'
import { Example, ServiceDefinition } from '.'
export function exampleMatchesRegex(example: Example, regex: RegExp) {
export function exampleMatchesRegex(example: Example, regex: RegExp): boolean {
const { title, keywords } = example
const haystack = [title].concat(keywords).join(' ')
return regex.test(haystack)
}
export function predicateFromQuery(query: string) {
export function predicateFromQuery(
query: string
): ({ examples }: { examples: Example[] }) => boolean {
const escaped = escapeStringRegexp(query)
const regex = new RegExp(escaped, 'i') // Case-insensitive.
return ({ examples }: { examples: Example[] }) =>
@@ -21,30 +23,32 @@ export default class ServiceDefinitionSetHelper {
this.definitionData = definitionData
}
public static create(definitionData: ServiceDefinition[]) {
public static create(
definitionData: ServiceDefinition[]
): ServiceDefinitionSetHelper {
return new ServiceDefinitionSetHelper(definitionData)
}
public getCategory(wantedCategory: string) {
public getCategory(wantedCategory: string): ServiceDefinitionSetHelper {
return ServiceDefinitionSetHelper.create(
this.definitionData.filter(({ category }) => category === wantedCategory)
)
}
public search(query: string) {
public search(query: string): ServiceDefinitionSetHelper {
const predicate = predicateFromQuery(query)
return ServiceDefinitionSetHelper.create(
this.definitionData.filter(predicate)
)
}
public notDeprecated() {
public notDeprecated(): ServiceDefinitionSetHelper {
return ServiceDefinitionSetHelper.create(
this.definitionData.filter(({ isDeprecated }) => !isDeprecated)
)
}
public toArray() {
public toArray(): ServiceDefinition[] {
return this.definitionData
}
}
+168 -164
View File
@@ -1,5 +1,4 @@
import React from 'react'
import PropTypes from 'prop-types'
import styled, { css } from 'styled-components'
import { staticBadgeUrl } from '../../core/badge-urls/make-badge-url'
import { baseUrl } from '../constants'
@@ -44,11 +43,11 @@ const JsonExampleBlock = styled.code<JsonExampleBlockProps>`
white-space: pre;
`
const JsonExample = ({ data }: { [k: string]: any }) => (
<JsonExampleBlock>{JSON.stringify(data, undefined, 2)}</JsonExampleBlock>
)
JsonExample.propTypes = {
data: PropTypes.object.isRequired,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function JsonExample({ data }: { [k: string]: any }): JSX.Element {
return (
<JsonExampleBlock>{JSON.stringify(data, undefined, 2)}</JsonExampleBlock>
)
}
const Schema = styled.dl`
@@ -89,161 +88,166 @@ const Schema = styled.dl`
}
`
const EndpointPage = () => (
<MainContainer>
<GlobalStyle />
<Meta />
<Header />
<H3>Endpoint</H3>
<Snippet snippet={`${baseUrl}/endpoint?url=...&style=...`} />
<p>Endpoint response:</p>
<JsonExample
data={{
schemaVersion: 1,
label: 'hello',
message: 'sweet world',
color: 'orange',
}}
/>
<p>Shields response:</p>
<Badge
alt="hello | sweet world"
src={staticBadgeUrl({
baseUrl,
label: 'hello',
message: 'sweet world',
color: 'orange',
})}
/>
<Explanation>
<p>
Developers rely on Shields for visual consistency and powerful
customization options. As a service provider or data provider, you can
use the endpoint badge to provide content while giving users the full
power of Shields' badge customization.
</p>
<p>
Using the endpoint badge, you can provide content for a badge through a
JSON endpoint. The content can be prerendered, or generated on the fly.
To strike a balance between responsiveness and bandwidth utilization on
one hand, and freshness on the other, cache behavior is configurable,
subject to the Shields minimum. The endpoint URL is provided to Shields
through the query string. Shields fetches it and formats the badge.
</p>
<p>
The endpoint badge is a better alternative than redirecting to the
static badge enpoint or generating SVG on your server:
</p>
<ol>
<li>
<a href="https://en.wikipedia.org/wiki/Separation_of_content_and_presentation">
Content and presentation are separate.
</a>{' '}
The service provider authors the badge, and Shields takes input from
the user to format it. As a service provider you author the badge but
don't have to concern yourself with styling. You don't even have to
pass the formatting options through to Shields.
</li>
<li>
Badge formatting is always 100% up to date. There's no need to track
updates to the npm package, badge templates, or options.
</li>
<li>
A JSON response is easy to implement; easier than an HTTP redirect. It
is trivial in almost any framework, and is more compatible with
hosting environments such as{' '}
<a href="https://runkit.com/docs/endpoint">RunKit endpoints</a>.
</li>
<li>
As a service provider you can rely on the Shields CDN. There's no need
to study the HTTP headers. Adjusting cache behavior is as simple as
setting a property in the JSON response.
</li>
</ol>
</Explanation>
<h4>Schema</h4>
<Explanation>
<p>
Breaking changes to the schema will trigger an increment to the
`schemaVersion`.
</p>
</Explanation>
<Schema>
<dt>schemaVersion</dt>
<dd>
Required. Always the number <code>1</code>.
</dd>
<dt>label</dt>
<dd>
Required. The left text, or the empty string to omit the left side of
the badge. This can be overridden by the query string.
</dd>
<dt>message</dt>
<dd>Required. Can't be empty. The right text.</dd>
<dt>color</dt>
<dd>
Default: <code>lightgrey</code>. The right color. Supports the eight
named colors above, as well as hex, rgb, rgba, hsl, hsla and css named
colors. This can be overridden by the query string.
</dd>
<dt>labelColor</dt>
<dd>
Default: <code>grey</code>. The left color. This can be overridden by
the query string.
</dd>
<dt>isError</dt>
<dd>
Default: <code>false</code>. <code>true</code> to treat this as an error
badge. This prevents the user from overriding the color. In the future
it may affect cache behavior.
</dd>
<dt>namedLogo</dt>
<dd>
Default: none. One of the named logos supported by Shields or {}
<a href="https://simpleicons.org/">simple-icons</a>. Can be overridden
by the query string.
</dd>
<dt>logoSvg</dt>
<dd>Default: none. An SVG string containing a custom logo.</dd>
<dt>logoColor</dt>
<dd>
Default: none. Same meaning as the query string. Can be overridden by
the query string.
</dd>
<dt>logoWidth</dt>
<dd>
Default: none. Same meaning as the query string. Can be overridden by
the query string.
</dd>
<dt>logoPosition</dt>
<dd>
Default: none. Same meaning as the query string. Can be overridden by
the query string.
</dd>
<dt>style</dt>
<dd>
Default: <code>flat</code>. The default template to use. Can be
overridden by the query string.
</dd>
<dt>cacheSeconds</dt>
<dd>
Default: <code>300</code>, min <code>300</code>. Set the HTTP cache
lifetime in seconds, which should be respected by the Shields' CDN and
downstream users. Values below 300 will be ignored. This lets you tune
performance and traffic vs. responsiveness. The value you specify can be
overridden by the user via the query string, but only to a longer value.
</dd>
</Schema>
<h4>Customize and test</h4>
<Customizer
baseUrl={baseUrl}
exampleNamedParams={{}}
exampleQueryParams={{ url: 'https://shields.redsparr0w.com/2473/monday' }}
isPrefilled={false}
pattern="/endpoint"
title="Custom badge"
/>
<Footer baseUrl={baseUrl} />
</MainContainer>
)
export default EndpointPage
export default function EndpointPage(): JSX.Element {
return (
<MainContainer>
<GlobalStyle />
<Meta />
<Header />
<H3>Endpoint</H3>
<Snippet snippet={`${baseUrl}/endpoint?url=...&style=...`} />
<p>Endpoint response:</p>
<JsonExample
data={{
schemaVersion: 1,
label: 'hello',
message: 'sweet world',
color: 'orange',
}}
/>
<p>Shields response:</p>
<Badge
alt="hello | sweet world"
src={staticBadgeUrl({
baseUrl,
label: 'hello',
message: 'sweet world',
color: 'orange',
})}
/>
<Explanation>
<p>
Developers rely on Shields for visual consistency and powerful
customization options. As a service provider or data provider, you can
use the endpoint badge to provide content while giving users the full
power of Shields' badge customization.
</p>
<p>
Using the endpoint badge, you can provide content for a badge through
a JSON endpoint. The content can be prerendered, or generated on the
fly. To strike a balance between responsiveness and bandwidth
utilization on one hand, and freshness on the other, cache behavior is
configurable, subject to the Shields minimum. The endpoint URL is
provided to Shields through the query string. Shields fetches it and
formats the badge.
</p>
<p>
The endpoint badge is a better alternative than redirecting to the
static badge enpoint or generating SVG on your server:
</p>
<ol>
<li>
<a href="https://en.wikipedia.org/wiki/Separation_of_content_and_presentation">
Content and presentation are separate.
</a>{' '}
The service provider authors the badge, and Shields takes input from
the user to format it. As a service provider you author the badge
but don't have to concern yourself with styling. You don't even have
to pass the formatting options through to Shields.
</li>
<li>
Badge formatting is always 100% up to date. There's no need to track
updates to the npm package, badge templates, or options.
</li>
<li>
A JSON response is easy to implement; easier than an HTTP redirect.
It is trivial in almost any framework, and is more compatible with
hosting environments such as{' '}
<a href="https://runkit.com/docs/endpoint">RunKit endpoints</a>.
</li>
<li>
As a service provider you can rely on the Shields CDN. There's no
need to study the HTTP headers. Adjusting cache behavior is as
simple as setting a property in the JSON response.
</li>
</ol>
</Explanation>
<h4>Schema</h4>
<Explanation>
<p>
Breaking changes to the schema will trigger an increment to the
`schemaVersion`.
</p>
</Explanation>
<Schema>
<dt>schemaVersion</dt>
<dd>
Required. Always the number <code>1</code>.
</dd>
<dt>label</dt>
<dd>
Required. The left text, or the empty string to omit the left side of
the badge. This can be overridden by the query string.
</dd>
<dt>message</dt>
<dd>Required. Can't be empty. The right text.</dd>
<dt>color</dt>
<dd>
Default: <code>lightgrey</code>. The right color. Supports the eight
named colors above, as well as hex, rgb, rgba, hsl, hsla and css named
colors. This can be overridden by the query string.
</dd>
<dt>labelColor</dt>
<dd>
Default: <code>grey</code>. The left color. This can be overridden by
the query string.
</dd>
<dt>isError</dt>
<dd>
Default: <code>false</code>. <code>true</code> to treat this as an
error badge. This prevents the user from overriding the color. In the
future it may affect cache behavior.
</dd>
<dt>namedLogo</dt>
<dd>
Default: none. One of the named logos supported by Shields or {}
<a href="https://simpleicons.org/">simple-icons</a>. Can be overridden
by the query string.
</dd>
<dt>logoSvg</dt>
<dd>Default: none. An SVG string containing a custom logo.</dd>
<dt>logoColor</dt>
<dd>
Default: none. Same meaning as the query string. Can be overridden by
the query string.
</dd>
<dt>logoWidth</dt>
<dd>
Default: none. Same meaning as the query string. Can be overridden by
the query string.
</dd>
<dt>logoPosition</dt>
<dd>
Default: none. Same meaning as the query string. Can be overridden by
the query string.
</dd>
<dt>style</dt>
<dd>
Default: <code>flat</code>. The default template to use. Can be
overridden by the query string.
</dd>
<dt>cacheSeconds</dt>
<dd>
Default: <code>300</code>, min <code>300</code>. Set the HTTP cache
lifetime in seconds, which should be respected by the Shields' CDN and
downstream users. Values below 300 will be ignored. This lets you tune
performance and traffic vs. responsiveness. The value you specify can
be overridden by the user via the query string, but only to a longer
value.
</dd>
</Schema>
<h4>Customize and test</h4>
<Customizer
baseUrl={baseUrl}
exampleNamedParams={{}}
exampleQueryParams={{
url: 'https://shields.redsparr0w.com/2473/monday',
}}
isPrefilled={false}
pattern="/endpoint"
title="Custom badge"
/>
<Footer baseUrl={baseUrl} />
</MainContainer>
)
}
+1 -1
View File
@@ -10,7 +10,7 @@ describe('loadSimpleIcons', function() {
})
it('prepares three color themes', function() {
expect(simpleIcons['sentry'].base64).to.have.all.keys(
expect(simpleIcons.sentry.base64).to.have.all.keys(
'default',
'light',
'dark'
+1 -1
View File
@@ -19,7 +19,7 @@ describe('Logo helpers', function() {
})
test(isDataUrl, () => {
//valid input
// valid input
given('data:image/svg+xml;base64,PHN2ZyB4bWxu').expect(true)
// invalid inputs
+320 -203
View File
@@ -3760,106 +3760,97 @@
"dev": true
},
"@typescript-eslint/eslint-plugin": {
"version": "1.13.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-1.13.0.tgz",
"integrity": "sha512-WQHCozMnuNADiqMtsNzp96FNox5sOVpU8Xt4meaT4em8lOG1SrOv92/mUbEHQVh90sldKSfcOc/I0FOb/14G1g==",
"version": "2.21.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.21.0.tgz",
"integrity": "sha512-b5jjjDMxzcjh/Sbjuo7WyhrQmVJg0WipTHQgXh5Xwx10uYm6nPWqN1WGOsaNq4HR3Zh4wUx4IRQdDkCHwyewyw==",
"dev": true,
"requires": {
"@typescript-eslint/experimental-utils": "1.13.0",
"eslint-utils": "^1.3.1",
"@typescript-eslint/experimental-utils": "2.21.0",
"eslint-utils": "^1.4.3",
"functional-red-black-tree": "^1.0.1",
"regexpp": "^2.0.1",
"tsutils": "^3.7.0"
}
},
"@typescript-eslint/experimental-utils": {
"version": "1.13.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-1.13.0.tgz",
"integrity": "sha512-zmpS6SyqG4ZF64ffaJ6uah6tWWWgZ8m+c54XXgwFtUv0jNz8aJAVx8chMCvnk7yl6xwn8d+d96+tWp7fXzTuDg==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.3",
"@typescript-eslint/typescript-estree": "1.13.0",
"eslint-scope": "^4.0.0"
"regexpp": "^3.0.0",
"tsutils": "^3.17.1"
},
"dependencies": {
"eslint-scope": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz",
"integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==",
"dev": true,
"requires": {
"esrecurse": "^4.1.0",
"estraverse": "^4.1.1"
}
"regexpp": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.0.0.tgz",
"integrity": "sha512-Z+hNr7RAVWxznLPuA7DIh8UNX1j9CDrUQxskw9IrBE1Dxue2lyXT+shqEIeLUjrokxIP8CMy1WkjgG3rTsd5/g==",
"dev": true
}
}
},
"@typescript-eslint/experimental-utils": {
"version": "2.21.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.21.0.tgz",
"integrity": "sha512-olKw9JP/XUkav4lq0I7S1mhGgONJF9rHNhKFn9wJlpfRVjNo3PPjSvybxEldvCXnvD+WAshSzqH5cEjPp9CsBA==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.3",
"@typescript-eslint/typescript-estree": "2.21.0",
"eslint-scope": "^5.0.0"
}
},
"@typescript-eslint/parser": {
"version": "1.13.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-1.13.0.tgz",
"integrity": "sha512-ITMBs52PCPgLb2nGPoeT4iU3HdQZHcPaZVw+7CsFagRJHUhyeTgorEwHXhFf3e7Evzi8oujKNpHc8TONth8AdQ==",
"version": "2.21.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.21.0.tgz",
"integrity": "sha512-VrmbdrrrvvI6cPPOG7uOgGUFXNYTiSbnRq8ZMyuGa4+qmXJXVLEEz78hKuqupvkpwJQNk1Ucz1TenrRP90gmBg==",
"dev": true,
"requires": {
"@types/eslint-visitor-keys": "^1.0.0",
"@typescript-eslint/experimental-utils": "1.13.0",
"@typescript-eslint/typescript-estree": "1.13.0",
"eslint-visitor-keys": "^1.0.0"
"@typescript-eslint/experimental-utils": "2.21.0",
"@typescript-eslint/typescript-estree": "2.21.0",
"eslint-visitor-keys": "^1.1.0"
},
"dependencies": {
"@typescript-eslint/experimental-utils": {
"version": "1.13.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-1.13.0.tgz",
"integrity": "sha512-zmpS6SyqG4ZF64ffaJ6uah6tWWWgZ8m+c54XXgwFtUv0jNz8aJAVx8chMCvnk7yl6xwn8d+d96+tWp7fXzTuDg==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.3",
"@typescript-eslint/typescript-estree": "1.13.0",
"eslint-scope": "^4.0.0"
}
},
"@typescript-eslint/typescript-estree": {
"version": "1.13.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.13.0.tgz",
"integrity": "sha512-b5rCmd2e6DCC6tCTN9GSUAuxdYwCM/k/2wdjHGrIRGPSJotWMCe/dGpi66u42bhuh8q3QBzqM4TMA1GUUCJvdw==",
"dev": true,
"requires": {
"lodash.unescape": "4.0.1",
"semver": "5.5.0"
}
},
"eslint-scope": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz",
"integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==",
"dev": true,
"requires": {
"esrecurse": "^4.1.0",
"estraverse": "^4.1.1"
}
},
"semver": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
"integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==",
"eslint-visitor-keys": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz",
"integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==",
"dev": true
}
}
},
"@typescript-eslint/typescript-estree": {
"version": "1.13.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.13.0.tgz",
"integrity": "sha512-b5rCmd2e6DCC6tCTN9GSUAuxdYwCM/k/2wdjHGrIRGPSJotWMCe/dGpi66u42bhuh8q3QBzqM4TMA1GUUCJvdw==",
"version": "2.21.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.21.0.tgz",
"integrity": "sha512-NC/nogZNb9IK2MEFQqyDBAciOT8Lp8O3KgAfvHx2Skx6WBo+KmDqlU3R9KxHONaijfTIKtojRe3SZQyMjr3wBw==",
"dev": true,
"requires": {
"lodash.unescape": "4.0.1",
"semver": "5.5.0"
"debug": "^4.1.1",
"eslint-visitor-keys": "^1.1.0",
"glob": "^7.1.6",
"is-glob": "^4.0.1",
"lodash": "^4.17.15",
"semver": "^6.3.0",
"tsutils": "^3.17.1"
},
"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"
}
},
"eslint-visitor-keys": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz",
"integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==",
"dev": true
},
"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
},
"semver": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
"integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==",
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true
}
}
@@ -4098,9 +4089,9 @@
"dev": true
},
"acorn-jsx": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.1.tgz",
"integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==",
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz",
"integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==",
"dev": true
},
"address": {
@@ -10324,53 +10315,54 @@
}
},
"eslint": {
"version": "5.16.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz",
"integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==",
"version": "6.8.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz",
"integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
"ajv": "^6.9.1",
"ajv": "^6.10.0",
"chalk": "^2.1.0",
"cross-spawn": "^6.0.5",
"debug": "^4.0.1",
"doctrine": "^3.0.0",
"eslint-scope": "^4.0.3",
"eslint-utils": "^1.3.1",
"eslint-visitor-keys": "^1.0.0",
"espree": "^5.0.1",
"eslint-scope": "^5.0.0",
"eslint-utils": "^1.4.3",
"eslint-visitor-keys": "^1.1.0",
"espree": "^6.1.2",
"esquery": "^1.0.1",
"esutils": "^2.0.2",
"file-entry-cache": "^5.0.1",
"functional-red-black-tree": "^1.0.1",
"glob": "^7.1.2",
"globals": "^11.7.0",
"glob-parent": "^5.0.0",
"globals": "^12.1.0",
"ignore": "^4.0.6",
"import-fresh": "^3.0.0",
"imurmurhash": "^0.1.4",
"inquirer": "^6.2.2",
"js-yaml": "^3.13.0",
"inquirer": "^7.0.0",
"is-glob": "^4.0.0",
"js-yaml": "^3.13.1",
"json-stable-stringify-without-jsonify": "^1.0.1",
"levn": "^0.3.0",
"lodash": "^4.17.11",
"lodash": "^4.17.14",
"minimatch": "^3.0.4",
"mkdirp": "^0.5.1",
"natural-compare": "^1.4.0",
"optionator": "^0.8.2",
"path-is-inside": "^1.0.2",
"optionator": "^0.8.3",
"progress": "^2.0.0",
"regexpp": "^2.0.1",
"semver": "^5.5.1",
"strip-ansi": "^4.0.0",
"strip-json-comments": "^2.0.1",
"semver": "^6.1.2",
"strip-ansi": "^5.2.0",
"strip-json-comments": "^3.0.1",
"table": "^5.2.3",
"text-table": "^0.2.0"
"text-table": "^0.2.0",
"v8-compile-cache": "^2.0.3"
},
"dependencies": {
"ansi-regex": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
"dev": true
},
"ansi-styles": {
@@ -10404,6 +10396,14 @@
"semver": "^5.5.0",
"shebang-command": "^1.2.0",
"which": "^1.2.9"
},
"dependencies": {
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"dev": true
}
}
},
"debug": {
@@ -10430,42 +10430,40 @@
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
"dev": true
},
"eslint-scope": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz",
"integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==",
"dev": true,
"requires": {
"esrecurse": "^4.1.0",
"estraverse": "^4.1.1"
}
},
"esprima": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
"eslint-visitor-keys": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz",
"integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==",
"dev": true
},
"glob-parent": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz",
"integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==",
"dev": true,
"requires": {
"is-glob": "^4.0.1"
}
},
"globals": {
"version": "12.3.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-12.3.0.tgz",
"integrity": "sha512-wAfjdLgFsPZsklLJvOBUBmzYE8/CwhEqSBEMRXA3qxIiNtyqvjYurAtIfDh6chlEPUfmTY3MnZh5Hfh4q0UlIw==",
"dev": true,
"requires": {
"type-fest": "^0.8.1"
}
},
"import-fresh": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.0.0.tgz",
"integrity": "sha512-pOnA9tfM3Uwics+SaBLCNyZZZbK+4PTu0OPZtLlMIrv17EdBoC15S9Kn8ckJ9TZTyKb3ywNE5y1yeDxxGA7nTQ==",
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz",
"integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==",
"dev": true,
"requires": {
"parent-module": "^1.0.0",
"resolve-from": "^4.0.0"
}
},
"js-yaml": {
"version": "3.13.1",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
"integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
"dev": true,
"requires": {
"argparse": "^1.0.7",
"esprima": "^4.0.0"
}
},
"minimist": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
@@ -10482,25 +10480,57 @@
}
},
"ms": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
},
"optionator": {
"version": "0.8.3",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
"integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
"dev": true,
"requires": {
"deep-is": "~0.1.3",
"fast-levenshtein": "~2.0.6",
"levn": "~0.3.0",
"prelude-ls": "~1.1.2",
"type-check": "~0.3.2",
"word-wrap": "~1.2.3"
}
},
"semver": {
"version": "5.7.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz",
"integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==",
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true
},
"strip-ansi": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
"integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
"dev": true,
"requires": {
"ansi-regex": "^3.0.0"
"ansi-regex": "^4.1.0"
}
},
"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
},
"type-fest": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
"integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
"dev": true
},
"v8-compile-cache": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz",
"integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==",
"dev": true
}
}
},
@@ -10523,15 +10553,9 @@
}
},
"eslint-config-standard": {
"version": "12.0.0",
"resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-12.0.0.tgz",
"integrity": "sha512-COUz8FnXhqFitYj4DTqHzidjIL/t4mumGZto5c7DrBpvWoie+Sn3P4sLEzUGeYhRElWuFEf8K1S1EfvD1vixCQ==",
"dev": true
},
"eslint-config-standard-jsx": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-8.1.0.tgz",
"integrity": "sha512-ULVC8qH8qCqbU792ZOO6DaiaZyHNS/5CZt3hKqHkEhVlhPEPN3nfBqqxJCyp59XrjIBZPu1chMYe9T2DXZ7TMw==",
"version": "14.1.0",
"resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-14.1.0.tgz",
"integrity": "sha512-EF6XkrrGVbvv8hL/kYa/m6vnvmUT+K82pJJc4JJVMM6+Qgqh0pnwprSxdduDLB9p/7bIxD+YV5O0wfb8lmcPbA==",
"dev": true
},
"eslint-config-standard-react": {
@@ -11004,9 +11028,9 @@
"dev": true
},
"resolve": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.14.1.tgz",
"integrity": "sha512-fn5Wobh4cxbLzuHaE+nphztHy43/b++4M6SsGFC2gB8uYwf0C8LcarfCz1un7UTW8OFQg9iNjZ4xpcFVGebDPg==",
"version": "1.15.1",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz",
"integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==",
"dev": true,
"requires": {
"path-parse": "^1.0.6"
@@ -11210,9 +11234,9 @@
}
},
"eslint-plugin-react-hooks": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-2.5.0.tgz",
"integrity": "sha512-bzvdX47Jx847bgAYf0FPX3u1oxU+mKU8tqrpj4UX9A96SbAmj/HVEefEy6rJUog5u8QIlOPTKZcBpGn5kkKfAQ==",
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.7.0.tgz",
"integrity": "sha512-iXTCFcOmlWvw4+TOE8CLWj6yX1GwzT0Y6cUfHHZqWnSk144VmVIRcVGtUAzrLES7C798lmvnt02C7rxaOX1HNA==",
"dev": true
},
"eslint-plugin-sort-class-members": {
@@ -11238,12 +11262,20 @@
}
},
"eslint-utils": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz",
"integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==",
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz",
"integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==",
"dev": true,
"requires": {
"eslint-visitor-keys": "^1.0.0"
"eslint-visitor-keys": "^1.1.0"
},
"dependencies": {
"eslint-visitor-keys": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz",
"integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==",
"dev": true
}
}
},
"eslint-visitor-keys": {
@@ -11253,20 +11285,20 @@
"dev": true
},
"espree": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz",
"integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==",
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/espree/-/espree-6.1.2.tgz",
"integrity": "sha512-2iUPuuPP+yW1PZaMSDM9eyVf8D5P0Hi8h83YtZ5bPc/zHYjII5khoixIUTMO794NOY8F/ThF1Bo8ncZILarUTA==",
"dev": true,
"requires": {
"acorn": "^6.0.7",
"acorn-jsx": "^5.0.0",
"eslint-visitor-keys": "^1.0.0"
"acorn": "^7.1.0",
"acorn-jsx": "^5.1.0",
"eslint-visitor-keys": "^1.1.0"
},
"dependencies": {
"acorn": {
"version": "6.1.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz",
"integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==",
"eslint-visitor-keys": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz",
"integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==",
"dev": true
}
}
@@ -16975,36 +17007,39 @@
}
},
"inquirer": {
"version": "6.2.2",
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.2.2.tgz",
"integrity": "sha512-Z2rREiXA6cHRR9KBOarR3WuLlFzlIfAEIiB45ll5SSadMg7WqOh1MKEjjndfuH5ewXdixWCxqnVfGOQzPeiztA==",
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.0.4.tgz",
"integrity": "sha512-Bu5Td5+j11sCkqfqmUTiwv+tWisMtP0L7Q8WrqA2C/BbBhy1YTdFrvjjlrKq8oagA/tLQBski2Gcx/Sqyi2qSQ==",
"dev": true,
"requires": {
"ansi-escapes": "^3.2.0",
"ansi-escapes": "^4.2.1",
"chalk": "^2.4.2",
"cli-cursor": "^2.1.0",
"cli-cursor": "^3.1.0",
"cli-width": "^2.0.0",
"external-editor": "^3.0.3",
"figures": "^2.0.0",
"lodash": "^4.17.11",
"mute-stream": "0.0.7",
"figures": "^3.0.0",
"lodash": "^4.17.15",
"mute-stream": "0.0.8",
"run-async": "^2.2.0",
"rxjs": "^6.4.0",
"string-width": "^2.1.0",
"strip-ansi": "^5.0.0",
"rxjs": "^6.5.3",
"string-width": "^4.1.0",
"strip-ansi": "^5.1.0",
"through": "^2.3.6"
},
"dependencies": {
"ansi-escapes": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
"integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==",
"dev": true
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.0.tgz",
"integrity": "sha512-EiYhwo0v255HUL6eDyuLrXEkTi7WwVCLAw+SeOQ7M7qdun1z1pum4DEm/nuqIVbPvi9RPPc9k9LbyBv6H0DwVg==",
"dev": true,
"requires": {
"type-fest": "^0.8.1"
}
},
"ansi-regex": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.0.0.tgz",
"integrity": "sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w==",
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
"dev": true
},
"ansi-styles": {
@@ -17027,29 +17062,117 @@
"supports-color": "^5.3.0"
}
},
"cli-cursor": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
"integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
"dev": true,
"requires": {
"restore-cursor": "^3.1.0"
}
},
"emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true
},
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
"dev": true
},
"rxjs": {
"version": "6.4.0",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz",
"integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==",
"figures": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
"integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==",
"dev": true,
"requires": {
"tslib": "^1.9.0"
"escape-string-regexp": "^1.0.5"
}
},
"is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"dev": true
},
"mimic-fn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
"dev": true
},
"mute-stream": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
"integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
"dev": true
},
"onetime": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz",
"integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==",
"dev": true,
"requires": {
"mimic-fn": "^2.1.0"
}
},
"restore-cursor": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
"integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
"dev": true,
"requires": {
"onetime": "^5.1.0",
"signal-exit": "^3.0.2"
}
},
"string-width": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
"integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
"dev": true,
"requires": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.0"
},
"dependencies": {
"strip-ansi": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
"dev": true,
"requires": {
"ansi-regex": "^5.0.0"
}
}
}
},
"strip-ansi": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.0.0.tgz",
"integrity": "sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow==",
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
"dev": true,
"requires": {
"ansi-regex": "^4.0.0"
"ansi-regex": "^4.1.0"
},
"dependencies": {
"ansi-regex": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
"dev": true
}
}
},
"type-fest": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
"integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
"dev": true
}
}
},
@@ -19338,12 +19461,6 @@
"integrity": "sha1-JMS/zWsvuji/0FlNsRedjptlZWE=",
"dev": true
},
"lodash.unescape": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz",
"integrity": "sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw=",
"dev": true
},
"lodash.uniq": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
@@ -28412,9 +28529,9 @@
"integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ=="
},
"tsutils": {
"version": "3.14.0",
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.14.0.tgz",
"integrity": "sha512-SmzGbB0l+8I0QwsPgjooFRaRvHLBLNYM8SeQ0k6rtNDru5sCGeLJcZdwilNndN+GysuFjF5EIYgN8GfFG6UeUw==",
"version": "3.17.1",
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz",
"integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==",
"dev": true,
"requires": {
"tslib": "^1.8.1"
+6 -8
View File
@@ -162,9 +162,8 @@
"@types/react-modal": "^3.10.5",
"@types/react-select": "^3.0.10",
"@types/styled-components": "4.1.8",
"@typescript-eslint/eslint-plugin": "^1.13.0",
"@typescript-eslint/parser": "^1.13.0",
"acorn": "^7.1.0",
"@typescript-eslint/eslint-plugin": "^2.14.0",
"@typescript-eslint/parser": "^2.14.0",
"babel-plugin-inline-react-svg": "^1.1.1",
"babel-plugin-istanbul": "^6.0.0",
"babel-preset-gatsby": "^0.2.29",
@@ -182,10 +181,9 @@
"danger-plugin-no-test-shortcuts": "^2.0.0",
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.2",
"eslint": "^5.16.0",
"eslint-config-prettier": "^6.10.0",
"eslint-config-standard": "^12.0.0",
"eslint-config-standard-jsx": "^8.1.0",
"eslint": "^6.8.0",
"eslint-config-prettier": "^6.9.0",
"eslint-config-standard": "^14.1.0",
"eslint-config-standard-react": "^9.0.0",
"eslint-plugin-chai-friendly": "^0.5.0",
"eslint-plugin-cypress": "^2.10.3",
@@ -196,7 +194,7 @@
"eslint-plugin-node": "^11.0.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-react": "^7.18.3",
"eslint-plugin-react-hooks": "^2.5.0",
"eslint-plugin-react-hooks": "^1.7.0",
"eslint-plugin-sort-class-members": "^1.6.0",
"eslint-plugin-standard": "^4.0.1",
"fetch-ponyfill": "^6.1.0",
+1 -1
View File
@@ -16,7 +16,7 @@ Sentry.init({
const filtered = integrations.filter(
integration => !disabledIntegrations.includes(integration.name)
)
if (filtered.length != integrations.length - disabledIntegrations.length) {
if (filtered.length !== integrations.length - disabledIntegrations.length) {
throw Error(
`An error occurred while filtering integrations. The following inetgrations were found: ${integrations.map(
({ name }) => name
+1 -1
View File
@@ -31,7 +31,7 @@ module.exports = class AppVeyorBuild extends AppVeyorBase {
async handle({ user, repo, branch }) {
const data = await this.fetch({ user, repo, branch })
if (!data.hasOwnProperty('build')) {
if (!('build' in data)) {
// this project exists but no builds have been run on it yet
return this.constructor.render({ status: 'no builds found' })
}
@@ -39,7 +39,7 @@ module.exports = class AppVeyorJobBuild extends AppVeyorBase {
}
transform({ data, jobName }) {
if (!data.hasOwnProperty('build')) {
if (!('build' in data)) {
// this project exists but no builds have been run on it yet
return { status: 'no builds found' }
}
+4 -4
View File
@@ -144,13 +144,13 @@ module.exports = class AppVeyorTests extends AppVeyorBase {
const isCompact = compactMessage !== undefined
const data = await this.fetch({ user, repo, branch })
if (!data.hasOwnProperty('build')) {
if (!('build' in data)) {
return { message: 'no builds found' }
}
let total = 0,
passed = 0,
failed = 0
let total = 0
let passed = 0
let failed = 0
data.build.jobs.forEach(job => {
total += job.testsCount
passed += job.passedTestsCount
+1
View File
@@ -97,6 +97,7 @@ class AurVotes extends BaseAurService {
static get category() {
return 'rating'
}
static get route() {
return {
base: 'aur/votes',
+2 -2
View File
@@ -52,7 +52,7 @@ class CranLicense extends BaseCranService {
async handle({ packageName }) {
const data = await this.fetch({ packageName })
return this.constructor.render({ license: data['License'] })
return this.constructor.render({ license: data.License })
}
}
@@ -84,7 +84,7 @@ class CranVersion extends BaseCranService {
async handle({ packageName }) {
const data = await this.fetch({ packageName })
return this.constructor.render({ version: data['Version'] })
return this.constructor.render({ version: data.Version })
}
}
+2 -1
View File
@@ -45,6 +45,7 @@ module.exports = class FDroid extends BaseYamlService {
},
]
}
static get defaultBadgeData() {
return { label: 'f-droid' }
}
@@ -62,7 +63,7 @@ module.exports = class FDroid extends BaseYamlService {
url: `${url}.yml`,
...options,
})
return { version: yaml['CurrentVersion'] }
return { version: yaml.CurrentVersion }
}
async fetchText(url, options) {
@@ -53,7 +53,7 @@ module.exports = class GithubContributors extends GithubAuthV3Service {
errorMessages: errorMessagesFor('repo not found'),
})
const parsed = parseLinkHeader(res.headers['link'])
const parsed = parseLinkHeader(res.headers.link)
let contributorCount
if (parsed === null) {
const json = this._parseJson(buffer)
@@ -83,7 +83,7 @@ module.exports = class GithubDeployments extends GithubAuthV4Service {
}
let message
if (state == 'IN_PROGRESS') {
if (state === 'IN_PROGRESS') {
message = 'in progress'
} else {
message = state.toLowerCase()
@@ -96,7 +96,7 @@ module.exports = class GithubDeployments extends GithubAuthV4Service {
}
async fetch({ user, repo, environment }) {
return await this._requestGraphql({
return this._requestGraphql({
query: gql`
query($user: String!, $repo: String!, $environment: String!) {
repository(owner: $user, name: $repo) {
@@ -117,7 +117,7 @@ module.exports = class GithubDeployments extends GithubAuthV4Service {
}
transform({ data }) {
if (data.repository.deployments.nodes.length == 0) {
if (data.repository.deployments.nodes.length === 0) {
throw new NotFound({ prettyMessage: 'environment not found' })
}
// This happens for the brief moment a deployment is created, but no
@@ -29,7 +29,7 @@ const stateMap = {
transform: ({ json }) => ({
state: json.state,
// Because eslint will not be happy with this snake_case name :(
merged: json['merged_at'] !== null,
merged: json.merged_at !== null,
}),
render: ({ value, isPR, number }) => {
const state = value.state
@@ -219,7 +219,7 @@ module.exports = class GithubIssueDetail extends GithubAuthV3Service {
transform({ json, property, issueKind }) {
const value = propertyMap[property].transform({ json, property })
const isPR = json.hasOwnProperty('pull_request') || issueKind === 'pulls'
const isPR = 'pull_request' in json || issueKind === 'pulls'
return { value, isPR }
}
+1 -1
View File
@@ -36,7 +36,7 @@ t.create('Release (repo not found)')
.get('/v/release/badges/helmets.json')
.expectBadge({ label: 'release', message: 'no releases or repo not found' })
//redirects
// redirects
t.create('Release (legacy route: release)')
.get('/release/photonstorm/phaser.svg')
.expectRedirect('/github/v/release/photonstorm/phaser.svg')
+3 -2
View File
@@ -83,7 +83,7 @@ class GithubTag extends GithubAuthV4Service {
async fetch({ user, repo, sort }) {
const limit = sort === 'semver' ? 100 : 1
return await this._requestGraphql({
return this._requestGraphql({
query: gql`
query($user: String!, $repo: String!, $limit: Int!) {
repository(owner: $user, name: $repo) {
@@ -120,8 +120,9 @@ class GithubTag extends GithubAuthV4Service {
const json = await this.fetch({ user, repo, sort })
const tags = json.data.repository.refs.edges.map(edge => edge.node.name)
if (tags.length === 0)
if (tags.length === 0) {
throw new NotFound({ prettyMessage: 'no tags found' })
}
return this.constructor.render({
version: this.constructor.getLatestTag({
tags,
@@ -55,7 +55,7 @@ module.exports = class JetbrainsVersion extends JetbrainsBase {
async handle({ pluginId }) {
const pluginData = await this.fetchPackageData({ pluginId, schema })
const version =
pluginData['plugin-repository'].category['idea-plugin'][0]['version']
pluginData['plugin-repository'].category['idea-plugin'][0].version
return this.constructor.render({ version })
}
}
@@ -84,9 +84,7 @@ module.exports = class PackagistPhpVersion extends BasePackagistService {
server,
})
if (
!allData.packages[this.getPackageName(user, repo)].hasOwnProperty(version)
) {
if (!(version in allData.packages[this.getPackageName(user, repo)])) {
throw new NotFound({ prettyMessage: 'invalid version' })
}
+1 -1
View File
@@ -51,6 +51,6 @@ module.exports = class SpackVersion extends BaseJsonService {
async handle({ packageName }) {
const pkg = await this.fetch({ packageName })
return this.constructor.render({ version: pkg['latest_version'] })
return this.constructor.render({ version: pkg.latest_version })
}
}
+2 -2
View File
@@ -43,8 +43,8 @@ function currencyFromCode(code) {
}
function ordinalNumber(n) {
const s = ['ᵗʰ', 'ˢᵗ', 'ⁿᵈ', 'ʳᵈ'],
v = n % 100
const s = ['ᵗʰ', 'ˢᵗ', 'ⁿᵈ', 'ʳᵈ']
const v = n % 100
return n + (s[(v - 20) % 10] || s[v] || s[0])
}
+2 -2
View File
@@ -12,8 +12,8 @@ const { addv } = require('./text-formatters')
const { version: versionColor } = require('./color-formatters')
function listCompare(a, b) {
const alen = a.length,
blen = b.length
const alen = a.length
const blen = b.length
for (let i = 0; i < alen; i++) {
if (a[i] < b[i]) {
return -1
@@ -54,7 +54,7 @@ module.exports = class VisualStudioAppCenterBuilds extends BaseVisualStudioAppCe
schema,
url: `https://api.appcenter.ms/v0.1/apps/${owner}/${app}/branches/${branch}/builds`,
})
if (json[0] == undefined)
if (json[0] === undefined)
// Fetch will return a 200 with no data if no builds were found.
throw new NotFound({ prettyMessage: 'no builds found' })
return renderBuildStatusBadge({ status: json[0].result })