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:
co-authored by
Paul Melnikow
parent
fe70e75f3e
commit
0d8a2d5ca0
+12
-5
@@ -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'
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
|
||||
@@ -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'
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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',
|
||||
})
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 />
|
||||
|
||||
@@ -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{' '}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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="/">
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -50,7 +50,7 @@ export function Snippet({
|
||||
snippet: string
|
||||
truncate?: boolean
|
||||
fontSize?: string
|
||||
}) {
|
||||
}): JSX.Element {
|
||||
return (
|
||||
<CodeContainer truncate={truncate}>
|
||||
<ClickToSelect>
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 = ``
|
||||
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,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/', '')
|
||||
|
||||
@@ -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
@@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
Generated
+320
-203
@@ -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
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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' }
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -97,6 +97,7 @@ class AurVotes extends BaseAurService {
|
||||
static get category() {
|
||||
return 'rating'
|
||||
}
|
||||
|
||||
static get route() {
|
||||
return {
|
||||
base: 'aur/votes',
|
||||
|
||||
@@ -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 })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 }
|
||||
}
|
||||
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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' })
|
||||
}
|
||||
|
||||
|
||||
@@ -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 })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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 })
|
||||
|
||||
Reference in New Issue
Block a user