Update TSLint (#3148)

Brings with it quite a few really useful rules that detect e.g. always-true/false expressions, noop casts, rxjs antipatterns and more.

I left most as warnings for now, we can turn them into errors when all instances are fixed.
This commit is contained in:
Felix Becker 2019-04-02 04:00:10 +02:00 committed by GitHub
parent 4d6d476a4c
commit 75b0ae9e2f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
100 changed files with 359 additions and 349 deletions

View File

@ -20,7 +20,6 @@ testdata
.github/*
doc/
shared/src/types/abort-controller/index.d.ts
client/browser/src/extension/*.json
cmd/management-console/assets/
**/.cache
shared/dev/**/*.js

View File

@ -3,8 +3,7 @@
"version": "0.0.0",
"name": "Sourcegraph",
"manifest_version": 2,
"description":
"Code intelligence for your code host and code reviews: hovers, documentation, definitions, and references in files, PRs, and diffs",
"description": "Code intelligence for your code host and code reviews: hovers, documentation, definitions, and references in files, PRs, and diffs",
"browser_action": {
"default_title": "Sourcegraph",
"default_icon": {
@ -30,7 +29,7 @@
},
"optional_permissions": ["tabs", "http://*/*", "https://*/*"],
"content_security_policy": "script-src 'self' blob:; object-src 'self'",
"web_accessible_resources": ["img/*", "css/style.bundle.css"],
"web_accessible_resources": ["img/*", "css/style.bundle.css"],
"omnibox": {
"keyword": "src"
},
@ -64,8 +63,7 @@
"https://sourcegraph.com/*",
"http://localhost:32773/*"
],
"key":
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvyGmcOkw4cTnhO0bgl3fQLAdv1jZp8T1ZHYI+4d8FgwwVKLYWE+pAuJ/0LrI69ibed4Nnnw5YleB1xCpI+mzB56xfXWboKp6lljevKqWJ5TpJk/Vam3kSSoZwpmJRXnzmcM3qKpL6viUhTfwGmQO6WVTsN4YCx+KWXv97IyF6yDTgd6hwFsvCZY2n1ADgurrQkE6AcJ3kK4xZ14jaHllXEdFcqwh0+Am5qLcIJ1cNo5iFD35exXsjwdQbmpt8sEk5f95pK5FEEbJFmOTguu2fOZycqIoTgoDrbbhT5k9TUogZaN5Lup0Iwh0Cv60i4C1f7IdPrxHuaYmYCfoUezXnQIDAQAB"
"key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvyGmcOkw4cTnhO0bgl3fQLAdv1jZp8T1ZHYI+4d8FgwwVKLYWE+pAuJ/0LrI69ibed4Nnnw5YleB1xCpI+mzB56xfXWboKp6lljevKqWJ5TpJk/Vam3kSSoZwpmJRXnzmcM3qKpL6viUhTfwGmQO6WVTsN4YCx+KWXv97IyF6yDTgd6hwFsvCZY2n1ADgurrQkE6AcJ3kK4xZ14jaHllXEdFcqwh0+Am5qLcIJ1cNo5iFD35exXsjwdQbmpt8sEk5f95pK5FEEbJFmOTguu2fOZycqIoTgoDrbbhT5k9TUogZaN5Lup0Iwh0Cv60i4C1f7IdPrxHuaYmYCfoUezXnQIDAQAB"
},
"prod": {
"content_scripts": [

View File

@ -262,7 +262,7 @@ runtime.onMessage((message, _, cb) => {
runtime.openOptionsPage()
return true
case 'createBlobURL':
createBlobURLForBundle(message.payload! as string)
createBlobURLForBundle(message.payload)
.then(url => {
if (cb) {
cb(url)

View File

@ -59,7 +59,7 @@ function observe(): void {
Boolean(items.enterpriseUrls.find(url => url === window.location.origin))
const isGitHub = /^https?:\/\/(www.)?github.com/.test(href)
const ogSiteName = document.head!.querySelector(`meta[property='og:site_name']`) as HTMLMetaElement
const ogSiteName = document.head.querySelector(`meta[property='og:site_name']`) as HTMLMetaElement
const isGitHubEnterprise = ogSiteName ? ogSiteName.content === 'GitHub Enterprise' : false
const isBitbucket =
document.querySelector('.bitbucket-header-logo') ||
@ -68,12 +68,12 @@ function observe(): void {
if (!isSourcegraphServer && !document.getElementById('ext-style-sheet')) {
if (isPhabricator || isGitHub || isGitHubEnterprise || isBitbucket || isGitlab) {
const styleSheet = document.createElement('link') as HTMLLinkElement
const styleSheet = document.createElement('link')
styleSheet.id = 'ext-style-sheet'
styleSheet.rel = 'stylesheet'
styleSheet.type = 'text/css'
styleSheet.href = getURL('css/style.bundle.css')
document.head!.appendChild(styleSheet)
document.head.appendChild(styleSheet)
}
}

View File

@ -157,7 +157,7 @@ function getCommandPaletteMount(): HTMLElement {
const createCommandList = (): HTMLElement => {
const commandListElem = document.createElement('li')
commandListElem.className = commandListClasses.join(' ')
headerElem!.insertAdjacentElement('beforeend', commandListElem)
headerElem.insertAdjacentElement('beforeend', commandListElem)
return commandListElem
}
@ -170,7 +170,7 @@ function getViewContextOnSourcegraphMount(): HTMLElement | null {
if (!branchSelectorButtons) {
return null
}
const preexisting = branchSelectorButtons.querySelector('#open-on-sourcegraph') as HTMLElement | null
const preexisting = branchSelectorButtons.querySelector<HTMLElement>('#open-on-sourcegraph')
if (preexisting) {
return preexisting
}

View File

@ -36,9 +36,8 @@ function getRevSpecFromRevisionSelector(): RevSpec {
return {
rev: revisionRefInfo.latestCommit,
}
} else {
throw new Error(`revisionRefInfo is empty or has no latestCommit (revisionRefStr: ${revisionRefStr})`)
}
throw new Error(`revisionRefInfo is empty or has no latestCommit (revisionRefStr: ${revisionRefStr})`)
}
export function getContext(): CodeHostContext {

View File

@ -32,7 +32,7 @@ const getFileInfoFromLinkInSingleFileView = (
const errors: Error[] = []
for (const selector of LINK_SELECTORS) {
try {
const linkElement = codeView.querySelector(selector) as HTMLLinkElement | null
const linkElement = codeView.querySelector<HTMLLinkElement>(selector)
if (!linkElement) {
throw new Error(`Could not find selector ${selector} in code view`)
}

View File

@ -302,10 +302,7 @@ export function initCodeIntelligence({
map(([, hoverOverlayElement]) => ({ hoverOverlayElement, relativeElement })),
filter(propertyIsDefined('hoverOverlayElement'))
),
getHover: ({ line, character, part, ...rest }) =>
getHover({ ...rest, position: { line, character } }).pipe(
map(hover => (hover ? (hover as HoverMerged) : hover))
),
getHover: ({ line, character, part, ...rest }) => getHover({ ...rest, position: { line, character } }),
getActions: context => getHoverActions({ extensionsController, platformContext }, context),
})
@ -369,8 +366,8 @@ export function initCodeIntelligence({
<HoverOverlay
{...hoverOverlayProps}
hoverRef={nextOverlayElement}
extensionsController={extensionsController!}
platformContext={platformContext!}
extensionsController={extensionsController}
platformContext={platformContext}
location={H.createLocation(window.location)}
onCloseButtonClick={nextCloseButtonClick}
/>,
@ -598,6 +595,9 @@ export function handleCodeHost({
codeViewState.subscriptions.add(
extensionsController.services.textDocumentDecoration
.getDecorations(toTextDocumentIdentifier(fileInfo))
// The nested subscribe cannot be replaced with a switchMap()
// We manage the subscription correctly.
// tslint:disable-next-line: rxjs-no-nested-subscribe
.subscribe(decorations => {
decoratedLines = applyDecorations(
domFunctions,

View File

@ -31,9 +31,8 @@ export const ensureRevisionsAreCloned = (files: Observable<FileInfo>): Observabl
catchError(err => {
if (err.code === ERPRIVATEREPOPUBLICSOURCEGRAPHCOM) {
return [{ repoName, commitID, baseCommitID, ...rest }]
} else {
throw err
}
throw err
})
)
})

View File

@ -163,7 +163,7 @@ function checkIsGithub(): boolean {
const href = window.location.href
const isGithub = /^https?:\/\/(www.)?github.com/.test(href)
const ogSiteName = document.head!.querySelector(`meta[property='og:site_name']`) as HTMLMetaElement
const ogSiteName = document.head.querySelector(`meta[property='og:site_name']`) as HTMLMetaElement
const isGitHubEnterprise = ogSiteName ? ogSiteName.content === 'GitHub Enterprise' : false
return isGithub || isGitHubEnterprise

View File

@ -9,7 +9,7 @@ export function getCommandPaletteMount(): HTMLElement {
const createCommandList = (): HTMLElement => {
const commandListElem = document.createElement('div')
commandListElem.className = commandListClass
headerElem!.insertAdjacentElement('afterbegin', commandListElem)
headerElem.insertAdjacentElement('afterbegin', commandListElem)
return commandListElem
}

View File

@ -81,7 +81,7 @@ function injectInlineSearch(): void {
const className = 'symbols-autocomplete'
const existingMount = parentDiv.querySelector(`.${className}`) as HTMLDivElement | null
const existingMount = parentDiv.querySelector<HTMLDivElement>(`.${className}`)
if (existingMount) {
return existingMount
}

View File

@ -64,10 +64,9 @@ export function getDeltaFileName(container: HTMLElement): { headFilePath: string
if (info.title) {
// for PR conversation snippets
return getPathNamesFromElement(info)
} else {
const link = info.querySelector('a') as HTMLElement
return getPathNamesFromElement(link)
}
const link = info.querySelector('a') as HTMLElement
return getPathNamesFromElement(link)
}
function getPathNamesFromElement(element: HTMLElement): { headFilePath: string; baseFilePath: string | null } {
@ -99,20 +98,18 @@ export function isDomSplitDiff(): boolean {
(disabledToggle && !disabledToggle.href.includes('diff=split')) ||
!!document.querySelector('.file-diff-split')
)
} else {
// delta for a commit view
const headerBar = document.getElementsByClassName('details-collapse table-of-contents js-details-container')
if (!headerBar || headerBar.length !== 1) {
return false
}
const diffToggles = headerBar[0].getElementsByClassName('BtnGroup float-right')
const selectedToggle = diffToggles[0].querySelector('.selected') as HTMLAnchorElement
return (
(selectedToggle && selectedToggle.href.includes('diff=split')) ||
!!document.querySelector('.file-diff-split')
)
}
// delta for a commit view
const headerBar = document.getElementsByClassName('details-collapse table-of-contents js-details-container')
if (!headerBar || headerBar.length !== 1) {
return false
}
const diffToggles = headerBar[0].getElementsByClassName('BtnGroup float-right')
const selectedToggle = diffToggles[0].querySelector('.selected') as HTMLAnchorElement
return (
(selectedToggle && selectedToggle.href.includes('diff=split')) || !!document.querySelector('.file-diff-split')
)
}
/**
@ -193,7 +190,7 @@ export function getDiffResolvedRev(codeView: HTMLElement): DiffResolvedRevSpec |
}
if (baseCommitID === '' || headCommitID === '') {
return getDiffResolvedRevFromPageSource(document.documentElement!.innerHTML, isPullRequest!)
return getDiffResolvedRevFromPageSource(document.documentElement.innerHTML, isPullRequest!)
}
return { baseCommitID, headCommitID }
}
@ -216,7 +213,7 @@ function getResolvedDiffFromCommentedSnippet(codeView: HTMLElement): DiffResolve
}
const headCommitID = match[3]
// The file header may not contain the base commit ID, so we get it from the page source.
const resolvedRevFromPageSource = getDiffResolvedRevFromPageSource(document.documentElement!.innerHTML, true)
const resolvedRevFromPageSource = getDiffResolvedRevFromPageSource(document.documentElement.innerHTML, true)
return headCommitID && resolvedRevFromPageSource
? {
...resolvedRevFromPageSource,
@ -226,9 +223,7 @@ function getResolvedDiffFromCommentedSnippet(codeView: HTMLElement): DiffResolve
}
function getResolvedDiffForCompare(): DiffResolvedRevSpec | undefined {
const branchElements = document.querySelectorAll('.commitish-suggester .select-menu-button span') as NodeListOf<
HTMLSpanElement
>
const branchElements = document.querySelectorAll<HTMLElement>('.commitish-suggester .select-menu-button span')
if (branchElements && branchElements.length === 2) {
return { baseCommitID: branchElements[0].innerText, headCommitID: branchElements[1].innerText }
}
@ -344,7 +339,7 @@ function getBranchName(): string | null {
return null
}
// otherwise, the branch name is fully rendered in the button
return (innerButtonEls[0] as HTMLElement).innerText as string
return (innerButtonEls[0] as HTMLElement).innerText
}
function getRevOrBranch(revAndPath: string): string | null {

View File

@ -10,7 +10,7 @@ const toolbarButtonProps = {
}
export function checkIsGitlab(): boolean {
return !!document.head!.querySelector('meta[content="GitLab"]')
return !!document.head.querySelector('meta[content="GitLab"]')
}
const adjustOverlayPosition: CodeHost['adjustOverlayPosition'] = ({ top, left }) => {

View File

@ -157,7 +157,7 @@ export function getHeadCommitIDFromCodeView(codeView: HTMLElement): FileInfo['co
throw buildFileError('no-commit-sha')
}
const commitAnchor = commitSHA.closest('a')! as HTMLAnchorElement
const commitAnchor = commitSHA.closest('a')!
const revMatch = new URL(commitAnchor.href).pathname.match(/blob\/(.*?)\//)
if (!revMatch) {
throw new Error('Unable to determine head revision from code view')

View File

@ -102,13 +102,13 @@ interface ConduitDiffDetailsResponse {
}
function createConduitRequestForm(): FormData {
const searchForm = document.querySelector('.phabricator-search-menu form') as any
const searchForm = document.querySelector('.phabricator-search-menu form')
if (!searchForm) {
throw new Error('cannot create conduit request form')
}
const form = new FormData()
form.set('__csrf__', searchForm.querySelector('input[name=__csrf__]')!.value)
form.set('__form__', searchForm.querySelector('input[name=__form__]')!.value)
form.set('__csrf__', searchForm.querySelector<HTMLInputElement>('input[name=__csrf__]')!.value)
form.set('__form__', searchForm.querySelector<HTMLInputElement>('input[name=__form__]')!.value)
return form
}
@ -316,9 +316,8 @@ export function getRepoDetailsFromCallsign(callsign: string): Promise<Phabricato
repoName: details.repoName,
phabricatorURL: window.location.origin,
}).subscribe(() => resolve(details))
} else {
return reject(new Error('could not parse repo details'))
}
return reject(new Error('could not parse repo details'))
})
})
.catch(reject)
@ -394,9 +393,8 @@ function getRepoDetailsFromRepoPHID(phid: string): Promise<PhabricatorRepoDetail
.subscribe(() => {
resolve(details)
})
} else {
return reject(new Error('could not parse repo details'))
}
return reject(new Error('could not parse repo details'))
})
})
.catch(reject)
@ -423,29 +421,28 @@ function convertConduitRepoToRepoDetails(repo: ConduitRepo): Promise<Phabricator
}
return resolve(convertToDetails(repo))
})
} else {
// The path to a phabricator repository on a Sourcegraph instance may differ than it's URI / name from the
// phabricator conduit API. Since we do not currently send the PHID with the Phabricator repository this a
// backwards work around configuration setting to ensure mappings are correct. This logic currently exists
// in the browser extension options menu.
type Mappings = { callsign: string; path: string }[]
const mappingsString = window.localStorage.getItem('PHABRICATOR_CALLSIGN_MAPPINGS')
const callsignMappings = mappingsString
? (JSON.parse(mappingsString) as Mappings)
: window.PHABRICATOR_CALLSIGN_MAPPINGS || []
const details = convertToDetails(repo)
if (callsignMappings) {
for (const mapping of callsignMappings) {
if (mapping.callsign === repo.fields.callsign) {
return resolve({
callsign: repo.fields.callsign,
repoName: mapping.path,
})
}
}
// The path to a phabricator repository on a Sourcegraph instance may differ than it's URI / name from the
// phabricator conduit API. Since we do not currently send the PHID with the Phabricator repository this a
// backwards work around configuration setting to ensure mappings are correct. This logic currently exists
// in the browser extension options menu.
type Mappings = { callsign: string; path: string }[]
const mappingsString = window.localStorage.getItem('PHABRICATOR_CALLSIGN_MAPPINGS')
const callsignMappings = mappingsString
? (JSON.parse(mappingsString) as Mappings)
: window.PHABRICATOR_CALLSIGN_MAPPINGS || []
const details = convertToDetails(repo)
if (callsignMappings) {
for (const mapping of callsignMappings) {
if (mapping.callsign === repo.fields.callsign) {
return resolve({
callsign: repo.fields.callsign,
repoName: mapping.path,
})
}
}
return resolve(details)
}
return resolve(details)
})
}

View File

@ -45,7 +45,7 @@ function init(): void {
.then(sourcegraphUrl => {
getPhabricatorCSS()
.then(css => {
const style = document.createElement('style') as HTMLStyleElement
const style = document.createElement('style')
style.setAttribute('type', 'text/css')
style.id = 'sourcegraph-styles'
style.textContent = css

View File

@ -23,7 +23,7 @@ export const resolveRevisionFileInfo = (codeView: HTMLElement): Observable<FileI
switchMap(info => {
const fetchingBaseFile = fetchBlobContentLines({
repoName: info.repoName,
filePath: info.filePath || info.filePath,
filePath: info.filePath,
commitID: info.baseCommitID,
})
@ -151,7 +151,7 @@ export const resolveDiffusionFileInfo = (codeView: HTMLElement): Observable<File
switchMap(info => {
const fetchingBaseFile = fetchBlobContentLines({
repoName: info.repoName,
filePath: info.filePath || info.filePath,
filePath: info.filePath,
commitID: info.commitID,
})

View File

@ -71,7 +71,7 @@ function getMaxDiffFromTabView(): { diffID: number; revDescription: string } | n
continue
}
const revDescription = (link.parentNode!.parentNode!.childNodes[2].childNodes[0] as any).href
const shaMatch = TAG_PATTERN.exec(revDescription!)
const shaMatch = TAG_PATTERN.exec(revDescription)
if (!shaMatch) {
continue
}

View File

@ -40,7 +40,7 @@ export const queryRepositoryComparisonFileDiffs = memoizeObservable(
if (!data || !data.repository) {
throw createAggregateError(errors)
}
const repo = data.repository as GQL.IRepository
const repo = data.repository
if (!repo.comparison || !repo.comparison.fileDiffs || errors) {
throw createAggregateError(errors)
}

View File

@ -121,7 +121,7 @@ describe('requestGraphQL()', () => {
})
it('errors if the repository is private and the user is logged out of his private instance', async () => {
const ajaxRequest = () => throwError({ status: 401 })
const ajaxRequest = () => throwError(Object.assign(new Error(), { status: 401 }))
await expect(
requestGraphQL({
ctx: MOCK_CONTEXT_PRIVATE,
@ -137,7 +137,7 @@ describe('requestGraphQL()', () => {
})
it('errors without retrying the user is logged out of his private instance and retry is false', async () => {
const ajaxRequest = () => throwError({ status: 401 })
const ajaxRequest = () => throwError(Object.assign(new Error(), { status: 401 }))
await expect(
requestGraphQL({
ctx: MOCK_CONTEXT_PRIVATE,

View File

@ -19,7 +19,7 @@ export const toTextDocumentIdentifier = (pos: RepoSpec & ResolvedRevSpec & FileS
const toTextDocumentPositionParams = (pos: AbsoluteRepoFilePosition): TextDocumentPositionParams => ({
textDocument: toTextDocumentIdentifier(pos),
position: {
character: pos.position.character! - 1,
character: pos.position.character - 1,
line: pos.position.line - 1,
},
})

View File

@ -1,7 +1,6 @@
import { Observable } from 'rxjs'
import { catchError, map } from 'rxjs/operators'
import * as GQL from '../../../../../shared/src/graphql/schema'
import { IClientConfigurationDetails } from '../../../../../shared/src/graphql/schema'
import { isOptions } from '../../context'
import { sourcegraphUrl } from '../util/context'
import { getContext } from './context'
@ -11,7 +10,7 @@ import { queryGraphQL } from './graphql'
* @return Observable that emits the client configuration details.
* Errors
*/
export const resolveClientConfiguration = (): Observable<IClientConfigurationDetails> =>
export const resolveClientConfiguration = (): Observable<GQL.IClientConfigurationDetails> =>
queryGraphQL({
ctx: getContext({ repoKey: '' }),
request: `query ClientConfiguration() {

View File

@ -24,11 +24,13 @@ export const logUserEvent = (event: string, uid: string): void => {
}`,
variables: { event, userCookieID: uid },
retry: false,
}).subscribe(undefined, error => {
// Swallow errors. If a Sourcegraph instance isn't upgraded, this request may fail
// (e.g., if CODEINTELINTEGRATION user events aren't yet supported).
// However, end users shouldn't experience this failure, as their admin is
// responsible for updating the instance, and has been (or will be) notified
// that an upgrade is available via site-admin messaging.
}).subscribe({
error: error => {
// Swallow errors. If a Sourcegraph instance isn't upgraded, this request may fail
// (e.g., if CODEINTELINTEGRATION user events aren't yet supported).
// However, end users shouldn't experience this failure, as their admin is
// responsible for updating the instance, and has been (or will be) notified
// that an upgrade is available via site-admin messaging.
},
})
}

View File

@ -141,7 +141,7 @@ export const fetchBlobContentLines = memoizeObservable(
) {
return []
}
return data.repository.commit.file!.content.split('\n')
return data.repository.commit.file.content.split('\n')
}),
catchError(({ errors, ...rest }) => {
if (errors && errors.length === 1) {

View File

@ -41,7 +41,7 @@
"@sourcegraph/prettierrc": "^2.2.0",
"@sourcegraph/stylelint-config": "^1.1.2",
"@sourcegraph/tsconfig": "^4.0.0",
"@sourcegraph/tslint-config": "^12.3.1",
"@sourcegraph/tslint-config": "^13.0.0",
"@storybook/addon-actions": "^4.1.4",
"@storybook/addon-console": "^1.1.0",
"@storybook/addon-info": "^4.1.4",
@ -173,7 +173,7 @@
"ts-jest": "^24.0.0",
"ts-loader": "^5.3.2",
"ts-node": "^7.0.1",
"tslint": "^5.12.0",
"tslint": "^5.15.0",
"tslint-language-service": "^0.9.9",
"typedoc": "^0.14.0",
"typescript": "^3.4.1",

View File

@ -39,6 +39,7 @@ export class ClientCodeEditor implements ClientCodeEditorAPI {
}
public $setDecorations(resource: string, decorationType: string, decorations: TextDocumentDecoration[]): void {
// tslint:disable-next-line: rxjs-no-ignored-observable
this.getDecorationsSubject(resource, decorationType, decorations)
}

View File

@ -316,7 +316,8 @@ export class Lexer {
if (ch === quote) {
terminated = true
break
} else if (ch === '\\') {
}
if (ch === '\\') {
str += backslashEscapeCodeString(this.getNextChar())
} else {
str += ch
@ -356,7 +357,8 @@ export class Lexer {
tail = true
terminated = true
break
} else if (ch === '\\') {
}
if (ch === '\\') {
str += backslashEscapeCodeString(this.getNextChar())
} else {
if (ch === '$') {

View File

@ -1,5 +1,4 @@
import { Observable, of } from 'rxjs'
import { Subscription } from 'rxjs'
import { Observable, of, Subscription } from 'rxjs'
import { TestScheduler } from 'rxjs/testing'
import { EMPTY_SETTINGS_CASCADE, SettingsCascadeOrError } from '../../../settings/settings'
import { ContributableMenu, Contributions, EvaluatedContributions } from '../../protocol'

View File

@ -106,7 +106,7 @@ describe('getDecorations', () => {
FIXTURE.TextDocumentIdentifier
)
).toBe('-a-|', {
a: [...FIXTURE_RESULT!, ...FIXTURE_RESULT!],
a: [...FIXTURE_RESULT, ...FIXTURE_RESULT],
})
))
})

View File

@ -173,7 +173,7 @@ describe('activeExtensions', () => {
},
enabledExtensions => enabledExtensions,
cold('a-|', { a: 'bar' }),
() => throwError('baz')
() => throwError(new Error('baz'))
).activeExtensions
)
).toBe('a-|', {

View File

@ -185,10 +185,12 @@ function extensionsWithMatchedActivationEvent(
console.warn(`Extension ${x.id} was not found. Remove it from settings to suppress this warning.`)
}
return false
} else if (isErrorLike(x.manifest)) {
}
if (isErrorLike(x.manifest)) {
console.warn(x.manifest)
return false
} else if (!x.manifest.activationEvents) {
}
if (!x.manifest.activationEvents) {
console.warn(`Extension ${x.id} has no activation events, so it will never be activated.`)
return false
}

View File

@ -87,7 +87,7 @@ describe('getHover', () => {
expectObservable(
getHover(
cold<ProvideTextDocumentHoverSignature[]>('-a-|', {
a: [() => of(FIXTURE_RESULT), () => throwError('err')],
a: [() => of(FIXTURE_RESULT), () => throwError(new Error('err'))],
}),
FIXTURE.TextDocumentPositionParams,
false

View File

@ -143,7 +143,7 @@ describe('getLocationsFromProviders', () => {
expectObservable(
getLocationsFromProviders(
cold<ProvideTextDocumentLocationSignature[]>('-a-|', {
a: [() => of([FIXTURE_LOCATION]), () => throwError('x')],
a: [() => of([FIXTURE_LOCATION]), () => throwError(new Error('x'))],
}),
FIXTURE.TextDocumentPositionParams,
false

View File

@ -109,7 +109,7 @@ describe('getViews', () => {
a: [
{
registrationOptions: { container: FIXTURE_CONTAINER, id: 'err' },
provider: throwError('err'),
provider: throwError(new Error('err')),
},
FIXTURE_ENTRY_1,
],

View File

@ -80,11 +80,11 @@ function score1(selector: DocumentSelector[0], candidateUri: string, candidateLa
// Shorthand notation: "mylang" -> {language: "mylang"}, "*" -> {language: "*""}.
if (selector === '*') {
return 5
} else if (selector === candidateLanguage) {
return 10
} else {
return 0
}
if (selector === candidateLanguage) {
return 10
}
return 0
}
const { language, scheme, pattern } = selector

View File

@ -1,7 +1,6 @@
export function illegalArgument(name?: string): Error {
if (name) {
return new Error(`Illegal argument: ${name}`)
} else {
return new Error('Illegal argument')
}
return new Error('Illegal argument')
}

View File

@ -103,19 +103,19 @@ export class Position {
public compareTo(other: sourcegraph.Position): number {
if (this._line < other.line) {
return -1
} else if (this._line > other.line) {
return 1
} else {
// equal line
if (this._character < other.character) {
return -1
} else if (this._character > other.character) {
return 1
} else {
// equal line and character
return 0
}
}
if (this._line > other.line) {
return 1
}
// equal line
if (this._character < other.character) {
return -1
}
if (this._character > other.character) {
return 1
}
// equal line and character
return 0
}
public translate(lineDelta?: number, characterDelta?: number): sourcegraph.Position

View File

@ -65,7 +65,8 @@ export class Range implements sourcegraph.Range {
public contains(positionOrRange: sourcegraph.Position | sourcegraph.Range): boolean {
if (positionOrRange instanceof Range) {
return this.contains(positionOrRange._start) && this.contains(positionOrRange._end)
} else if (positionOrRange instanceof Position) {
}
if (positionOrRange instanceof Position) {
if (positionOrRange.isBefore(this._start)) {
return false
}
@ -96,7 +97,8 @@ export class Range implements sourcegraph.Range {
public union(other: sourcegraph.Range): sourcegraph.Range {
if (this.contains(other)) {
return this
} else if (other.contains(this)) {
}
if (other.contains(this)) {
return other
}
const start = Position.min(other.start, this._start)

View File

@ -2,7 +2,6 @@ import { Location } from '@sourcegraph/extension-api-types'
import { asyncScheduler, Observable, of } from 'rxjs'
import { observeOn, switchMap, take, toArray } from 'rxjs/operators'
import * as sourcegraph from 'sourcegraph'
import { languages as sourcegraphLanguages } from 'sourcegraph'
import { Services } from '../client/services'
import { assertToJSON } from '../extension/types/testHelpers'
import { createBarrier, integrationTestContext } from './testHelpers'
@ -107,7 +106,7 @@ function testLocationProvider<P>({
providerWithImplementation,
getResult,
}: {
name: keyof typeof sourcegraphLanguages
name: keyof typeof sourcegraph.languages
registerProvider: (
extensionAPI: typeof sourcegraph
) => (selector: sourcegraph.DocumentSelector, provider: P) => sourcegraph.Unsubscribable

View File

@ -95,7 +95,7 @@ export const FileMatchChildren: React.FunctionComponent<FileMatchProps> = props
</Link>
))}
{groupsOfItems.map(items => {
const item = items[0]!
const item = items[0]
const position = { line: item.line + 1, character: item.character + 1 }
return (
<Link

View File

@ -1,23 +1,12 @@
import { isEqual } from 'lodash'
import { from, Observable, of, throwError } from 'rxjs'
import {
catchError,
distinctUntilChanged,
filter,
map,
publishReplay,
refCount,
startWith,
switchMap,
} from 'rxjs/operators'
import { catchError, distinctUntilChanged, map, publishReplay, refCount, switchMap } from 'rxjs/operators'
import { gql, graphQLContent } from '../graphql/graphql'
import * as GQL from '../graphql/schema'
import { PlatformContext } from '../platform/context'
import { asError, createAggregateError, ErrorLike, isErrorLike } from '../util/errors'
import { asError, createAggregateError } from '../util/errors'
import { ConfiguredRegistryExtension, extensionIDsFromSettings, toConfiguredRegistryExtension } from './extension'
const LOADING: 'loading' = 'loading'
/**
* @returns An observable that emits the list of extensions configured in the viewer's final settings upon
* subscription and each time it changes.
@ -29,12 +18,8 @@ export function viewerConfiguredExtensions({
return from(settings).pipe(
map(settings => extensionIDsFromSettings(settings)),
distinctUntilChanged((a, b) => isEqual(a, b)),
switchMap(extensionIDs =>
queryConfiguredRegistryExtensions({ queryGraphQL }, extensionIDs).pipe(startWith(LOADING))
),
catchError(error => [asError(error) as ErrorLike]),
filter((extensions): extensions is ConfiguredRegistryExtension[] | ErrorLike => extensions !== LOADING),
switchMap(extensions => (isErrorLike(extensions) ? throwError(extensions) : [extensions])),
switchMap(extensionIDs => queryConfiguredRegistryExtensions({ queryGraphQL }, extensionIDs)),
catchError(error => throwError(asError(error))),
publishReplay(),
refCount()
)
@ -52,6 +37,10 @@ export function queryConfiguredRegistryExtensions(
if (extensionIDs.length === 0) {
return of([])
}
const variables: GQL.IExtensionsOnExtensionRegistryArguments = {
first: extensionIDs.length,
prioritizeExtensionIDs: extensionIDs,
}
return from(
queryGraphQL<GQL.IQuery>(
gql`
@ -71,10 +60,7 @@ export function queryConfiguredRegistryExtensions(
}
}
`[graphQLContent],
{
first: extensionIDs.length,
prioritizeExtensionIDs: extensionIDs,
} as GQL.IExtensionsOnExtensionRegistryArguments,
variables,
false
)
).pipe(

View File

@ -16,6 +16,7 @@ export function registerHighlightContributions(): void {
return
}
registered = true
// tslint:disable no-require-imports
registerLanguage('go', require('highlight.js/lib/languages/go'))
registerLanguage('javascript', require('highlight.js/lib/languages/javascript'))
registerLanguage('typescript', require('highlight.js/lib/languages/typescript'))
@ -43,4 +44,5 @@ export function registerHighlightContributions(): void {
registerLanguage('yaml', require('highlight.js/lib/languages/yaml'))
registerLanguage('kotlin', require('highlight.js/lib/languages/kotlin'))
registerLanguage('dart', require('highlight.js/lib/languages/dart'))
// tslint:enable no-require-imports
}

View File

@ -139,8 +139,7 @@ export function getHoverActionsContext(
definitionURLOrError !== LOADING &&
!isErrorLike(definitionURLOrError) &&
definitionURLOrError === null,
'goToDefinition.error':
isErrorLike(definitionURLOrError) && ((definitionURLOrError as any).stack as any),
'goToDefinition.error': isErrorLike(definitionURLOrError) && (definitionURLOrError as any).stack,
'findReferences.url':
hasReferenceProvider && showFindReferences

View File

@ -11,8 +11,7 @@ import { FetchFileCtx } from '../../components/CodeExcerpt'
import { FileMatch, IFileMatch, ILineMatch } from '../../components/FileMatch'
import { VirtualList } from '../../components/VirtualList'
import { SettingsCascadeProps } from '../../settings/settings'
import { asError } from '../../util/errors'
import { ErrorLike, isErrorLike } from '../../util/errors'
import { asError, ErrorLike, isErrorLike } from '../../util/errors'
import { propertyIsDefined } from '../../util/types'
import { parseRepoURI, toPrettyBlobURL } from '../../util/url'

View File

@ -10,8 +10,7 @@ import { RepoLink } from '../../components/RepoLink'
import { Resizable } from '../../components/Resizable'
import { ExtensionsControllerProps } from '../../extensions/controller'
import { SettingsCascadeProps } from '../../settings/settings'
import { ErrorLike, isErrorLike } from '../../util/errors'
import { asError } from '../../util/errors'
import { asError, ErrorLike, isErrorLike } from '../../util/errors'
import { parseRepoURI } from '../../util/url'
import { registerPanelToolbarContributions } from './contributions'
import { FileLocations, FileLocationsError, FileLocationsNotFound } from './FileLocations'

View File

@ -1,4 +1,4 @@
import { createAggregateError, ErrorLike, isErrorLike } from '../util/errors'
import { createAggregateError, isErrorLike } from '../util/errors'
import {
CustomMergeFunctions,
gqlToCascade,
@ -39,18 +39,20 @@ const FIXTURE_USER_WITH_SETTINGS_ERROR: SettingsSubject & SubjectSettingsContent
const SETTINGS_ERROR_FOR_FIXTURE_USER = createAggregateError([new Error('parse error (code: 0, offset: 0, length: 1)')])
describe('gqlToCascade', () => {
test('converts a value', () =>
expect(
gqlToCascade({
subjects: [FIXTURE_ORG, FIXTURE_USER],
})
).toEqual({
test('converts a value', () => {
const expected: SettingsCascade = {
subjects: [
{ subject: FIXTURE_ORG, settings: { a: 1 }, lastID: 1 },
{ subject: FIXTURE_USER, settings: { b: 2 }, lastID: 2 },
],
final: { a: 1, b: 2 },
} as SettingsCascade))
}
expect(
gqlToCascade({
subjects: [FIXTURE_ORG, FIXTURE_USER],
})
).toEqual(expected)
})
test('preserves errors', () => {
const value = gqlToCascade({
subjects: [FIXTURE_ORG, FIXTURE_USER_WITH_SETTINGS_ERROR, FIXTURE_USER],
@ -60,7 +62,7 @@ describe('gqlToCascade', () => {
value.subjects &&
!isErrorLike(value.subjects) &&
isErrorLike(value.subjects[1].settings) &&
(value.subjects[1].settings as ErrorLike).message
value.subjects[1].settings.message
).toBe(SETTINGS_ERROR_FOR_FIXTURE_USER.message)
})
})

View File

@ -134,10 +134,9 @@ function highlightNodeHelper(
)
if (res.highlightingCompleted) {
return res
} else {
currOffset += res.charsConsumed
charsHighlighted += res.charsHighlighted
}
currOffset += res.charsConsumed
charsHighlighted += res.charsHighlighted
break
}
}

View File

@ -42,8 +42,10 @@ export function memoizeObservable<P, T>(
const obs = func(params).pipe(
publishReplay(),
refCount(),
tap(undefined as any, e => {
cache.delete(key)
tap({
error: () => {
cache.delete(key)
},
})
)
cache.set(key, obs)

View File

@ -159,16 +159,11 @@ export class SourcegraphWebApp extends React.Component<SourcegraphWebAppProps, S
this.setState(() => {
if (authenticatedUser) {
return { viewerSubject: authenticatedUser }
} else if (
cascade &&
!isErrorLike(cascade) &&
cascade.subjects &&
cascade.subjects.length > 0
) {
return { viewerSubject: cascade.subjects[0].subject }
} else {
return { viewerSubject: SITE_SUBJECT_NO_ADMIN }
}
if (cascade && !isErrorLike(cascade) && cascade.subjects && cascade.subjects.length > 0) {
return { viewerSubject: cascade.subjects[0].subject }
}
return { viewerSubject: SITE_SUBJECT_NO_ADMIN }
})
}
)

View File

@ -5,8 +5,7 @@ import { upperFirst } from 'lodash'
import * as React from 'react'
import { Link } from 'react-router-dom'
import { from as fromPromise, Subject, Subscription } from 'rxjs'
import { catchError } from 'rxjs/operators'
import { debounceTime } from 'rxjs/operators'
import { catchError, debounceTime } from 'rxjs/operators'
import { asError, ErrorLike, isErrorLike } from '../../../shared/src/util/errors'
import { eventLogger } from '../tracking/eventLogger'

View File

@ -224,7 +224,7 @@ export class ResetPasswordPage extends React.PureComponent<ResetPasswordPageProp
if (searchParams.has('code') || searchParams.has('userID')) {
const code = searchParams.get('code')
const userID = parseInt(searchParams.get('userID') || '', 10)
if (code && typeof userID === 'number' && !isNaN(userID)) {
if (code && !isNaN(userID)) {
body = <ResetPasswordCodeForm code={code} userID={userID} />
} else {
body = <div className="alert alert-danger">The password reset link you followed is invalid.</div>

View File

@ -4,8 +4,7 @@ import { upperFirst } from 'lodash'
import HelpCircleOutlineIcon from 'mdi-react/HelpCircleOutlineIcon'
import UserIcon from 'mdi-react/UserIcon'
import * as React from 'react'
import { Redirect } from 'react-router-dom'
import { Link } from 'react-router-dom'
import { Link, Redirect } from 'react-router-dom'
import { from, Subscription } from 'rxjs'
import * as GQL from '../../../shared/src/graphql/schema'
import { asError } from '../../../shared/src/util/errors'

View File

@ -43,7 +43,7 @@ export function requestGraphQL<R extends GQL.IGraphQLResponseRoot>(
* @return Observable That emits the result or errors if the HTTP request failed
*/
export function queryGraphQL(query: GraphQLDocument, variables: any = {}): Observable<GraphQLResult<GQL.IQuery>> {
return requestGraphQL(query, variables) as Observable<GraphQLResult<GQL.IQuery>>
return requestGraphQL(query, variables)
}
/**
@ -57,5 +57,5 @@ export function mutateGraphQL(
mutation: GraphQLDocument,
variables: any = {}
): Observable<GraphQLResult<GQL.IMutation>> {
return requestGraphQL(mutation, variables) as Observable<GraphQLResult<GQL.IMutation>>
return requestGraphQL(mutation, variables)
}

View File

@ -22,7 +22,7 @@ export class DismissibleAlert extends React.PureComponent<Props, State> {
constructor(props: Props) {
super(props)
this.key = 'DismissibleAlert/' + props.partialStorageKey + '/dismissed'
this.key = `DismissibleAlert/${props.partialStorageKey}/dismissed`
this.state = {
dismissed: localStorage.getItem(this.key) === 'true',

View File

@ -60,8 +60,7 @@ export class ExternalServiceCard extends React.PureComponent<ExternalServiceCard
{cardContent}
</LinkOrButton>
)
} else {
return <div className={`external-service-card--${this.props.iconBrandColor}`}>{cardContent}</div>
}
return <div className={`external-service-card--${this.props.iconBrandColor}`}>{cardContent}</div>
}
}

View File

@ -507,12 +507,11 @@ export class FilteredConnection<N, NP = {}, C extends Connection<N> = Connection
.pipe(
catchError(error => [asError(error)]),
map(
c =>
({
connectionOrError: c,
connectionQuery: query,
loading: false,
} as PartialStateUpdate)
(c): PartialStateUpdate => ({
connectionOrError: c,
connectionQuery: query,
loading: false,
})
),
publishReplay<PartialStateUpdate>(),
refCount()

View File

@ -98,17 +98,16 @@ export class OverviewItem extends React.Component<Props, State> {
)}
</Link>
)
} else {
return (
<div className={`overview-item ${this.props.list && 'list'}`}>
<div className="overview-item__header">{e}</div>
{actions}
{this.props.children && this.state.expanded && (
<div className="overview-item__children">{this.props.children}</div>
)}
</div>
)
}
return (
<div className={`overview-item ${this.props.list && 'list'}`}>
<div className="overview-item__header">{e}</div>
{actions}
{this.props.children && this.state.expanded && (
<div className="overview-item__children">{this.props.children}</div>
)}
</div>
)
}
private toggleExpand = () => this.setState(prevState => ({ expanded: !prevState.expanded }))

View File

@ -1,8 +1,6 @@
import { LoadingSpinner } from '@sourcegraph/react-loading-spinner'
import { decode } from 'he'
import { isEqual } from 'lodash'
import { range } from 'lodash'
import { escapeRegExp } from 'lodash'
import { escapeRegExp, isEqual, range } from 'lodash'
import React from 'react'
import { Link } from 'react-router-dom'
import VisibilitySensor from 'react-visibility-sensor'

View File

@ -85,7 +85,7 @@ export class BarChart<T extends BarChartSeries> extends React.Component<Props<T>
.range(barColors)
const xAxis = axisBottom(x)
const svg = select(this.svgRef!)
const svg = select(this.svgRef)
svg.selectAll('*').remove()
const barWidth = width / columns - 2
@ -139,7 +139,7 @@ export class BarChart<T extends BarChartSeries> extends React.Component<Props<T>
barHolder
.append<AxisContainerElement>('g')
.classed('axis', true)
.attr('transform', 'translate(0,' + height + ')')
.attr('transform', `translate(0, ${height})`)
.call(xAxis)
.selectAll('.tick text')
.call(wrapLabel, barWidth)

View File

@ -31,8 +31,7 @@ export class Tooltip extends React.PureComponent<Props, State> {
const instance = Tooltip.INSTANCE
if (instance) {
instance.setState(prevState => {
const subject =
prevState.lastEventTarget && instance.getSubject(prevState.lastEventTarget as HTMLElement)
const subject = prevState.lastEventTarget && instance.getSubject(prevState.lastEventTarget)
return {
subject,
content: subject ? instance.getContent(subject) : undefined,

View File

@ -1,11 +1,9 @@
import { Observable, of } from 'rxjs'
import { map, mapTo, switchMap } from 'rxjs/operators'
import { gql } from '../../../../../shared/src/graphql/graphql'
import { RegistryPublisher } from '../../../../../shared/src/graphql/schema'
import * as GQL from '../../../../../shared/src/graphql/schema'
import { createAggregateError } from '../../../../../shared/src/util/errors'
import { queryGraphQL } from '../../../backend/graphql'
import { mutateGraphQL } from '../../../backend/graphql'
import { mutateGraphQL, queryGraphQL } from '../../../backend/graphql'
export function deleteRegistryExtensionWithConfirmation(extension: GQL.ID): Observable<boolean> {
return of(window.confirm('Really delete this extension from the extension registry?')).pipe(
@ -41,7 +39,7 @@ export function deleteRegistryExtensionWithConfirmation(extension: GQL.ID): Obse
)
}
export function queryViewerRegistryPublishers(): Observable<RegistryPublisher[]> {
export function queryViewerRegistryPublishers(): Observable<GQL.RegistryPublisher[]> {
return queryGraphQL(gql`
query ViewerRegistryPublishers {
extensionRegistry {

View File

@ -165,7 +165,7 @@ export class SiteAdminProductSubscriptionPage extends React.Component<Props, Sta
<button
className="btn btn-outline-danger"
onClick={this.archiveProductSubscription}
disabled={this.state.archivalOrError === undefined}
disabled={this.state.archivalOrError === null}
>
Archive
</button>

View File

@ -1,6 +1,5 @@
import { LoadingSpinner } from '@sourcegraph/react-loading-spinner'
import { upperFirst } from 'lodash'
import { isEqual } from 'lodash'
import { isEqual, upperFirst } from 'lodash'
import * as React from 'react'
import { Link } from 'react-router-dom'
import { ReactStripeElements } from 'react-stripe-elements'

View File

@ -110,20 +110,20 @@ export class UserSubscriptionsProductSubscriptionPage extends React.Component<Pr
productNameWithBrand={
this.state.productSubscriptionOrError.activeLicense &&
this.state.productSubscriptionOrError.activeLicense.info
? this.state.productSubscriptionOrError.activeLicense!.info!
? this.state.productSubscriptionOrError.activeLicense.info
.productNameWithBrand
: this.state.productSubscriptionOrError.invoiceItem!.plan.nameWithBrand
}
userCount={
this.state.productSubscriptionOrError.activeLicense &&
this.state.productSubscriptionOrError.activeLicense.info
? this.state.productSubscriptionOrError.activeLicense!.info!.userCount
? this.state.productSubscriptionOrError.activeLicense.info.userCount
: this.state.productSubscriptionOrError.invoiceItem!.userCount
}
expiresAt={
this.state.productSubscriptionOrError.activeLicense &&
this.state.productSubscriptionOrError.activeLicense.info
? this.state.productSubscriptionOrError.activeLicense!.info!.expiresAt
? this.state.productSubscriptionOrError.activeLicense.info.expiresAt
: this.state.productSubscriptionOrError.invoiceItem!.expiresAt
}
licenseKey={

View File

@ -5,7 +5,6 @@ import { LinkOrSpan } from '../../../shared/src/components/LinkOrSpan'
import { Path } from '../../../shared/src/components/Path'
import { ConfiguredRegistryExtension, isExtensionEnabled } from '../../../shared/src/extensions/extension'
import * as GQL from '../../../shared/src/graphql/schema'
import { SettingsSubject } from '../../../shared/src/graphql/schema'
import { PlatformContextProps } from '../../../shared/src/platform/context'
import { ExtensionManifest } from '../../../shared/src/schema/extension.schema'
import { SettingsCascadeProps } from '../../../shared/src/settings/settings'
@ -25,7 +24,7 @@ interface Props extends SettingsCascadeProps, PlatformContextProps<'updateSettin
>,
'id' | 'manifest' | 'registryExtension'
>
subject: Pick<SettingsSubject, 'id' | 'viewerCanAdminister'>
subject: Pick<GQL.SettingsSubject, 'id' | 'viewerCanAdminister'>
}
/** Displays an extension as a card. */

View File

@ -111,11 +111,12 @@ function confirmAddExtension(extensionID: string): boolean {
function extractErrors(c: SettingsCascadeOrError): SettingsCascade | ErrorLike {
if (c.subjects === null) {
return new Error('Subjects was ' + c.subjects)
} else if (c.final === null || isErrorLike(c.final)) {
return new Error('Merged was ' + c.final)
} else if (c.subjects.find(isErrorLike)) {
return new Error('One of the subjects was ' + c.subjects.find(isErrorLike))
} else {
return c as SettingsCascade
}
if (c.final === null || isErrorLike(c.final)) {
return new Error('Merged was ' + c.final)
}
if (c.subjects.find(isErrorLike)) {
return new Error('One of the subjects was ' + c.subjects.find(isErrorLike))
}
return c as SettingsCascade
}

View File

@ -11,8 +11,7 @@ import { gql } from '../../../../shared/src/graphql/graphql'
import * as GQL from '../../../../shared/src/graphql/schema'
import { PlatformContextProps } from '../../../../shared/src/platform/context'
import { SettingsCascadeProps } from '../../../../shared/src/settings/settings'
import { ErrorLike, isErrorLike } from '../../../../shared/src/util/errors'
import { createAggregateError } from '../../../../shared/src/util/errors'
import { createAggregateError, ErrorLike, isErrorLike } from '../../../../shared/src/util/errors'
import { queryGraphQL } from '../../backend/graphql'
import { ErrorBoundary } from '../../components/ErrorBoundary'
import { HeroPage } from '../../components/HeroPage'
@ -134,7 +133,7 @@ export class ExtensionArea extends React.Component<ExtensionAreaProps> {
type PartialStateUpdate = Pick<ExtensionAreaState, 'extensionOrError'>
return queryExtension(extensionID).pipe(
catchError(error => [error]),
map(c => ({ extensionOrError: c } as PartialStateUpdate)),
map((c): PartialStateUpdate => ({ extensionOrError: c })),
// Don't clear old data while we reload, to avoid unmounting all components during
// loading.

View File

@ -137,8 +137,10 @@ export const submitTrialRequest = (email: string): void => {
map(dataOrThrowErrors),
map(() => undefined)
)
.subscribe(undefined, error => {
// Swallow errors since the form submission is a non-blocking request that happens during site-init
// if a trial license key is requested.
.subscribe({
error: error => {
// Swallow errors since the form submission is a non-blocking request that happens during site-init
// if a trial license key is requested.
},
})
}

View File

@ -19,16 +19,18 @@ const renderShallow = (element: React.ReactElement<NavLinks['props']>): any => {
const getDisplayName = (element: React.ReactChild): string | string[] => {
if (element === null) {
return []
} else if (typeof element === 'string' || typeof element === 'number') {
}
if (typeof element === 'string' || typeof element === 'number') {
return element.toString()
} else if (element.type === 'li' && (element.props.children.props.href || element.props.children.props.to)) {
}
if (element.type === 'li' && (element.props.children.props.href || element.props.children.props.to)) {
return `${element.props.children.props.children} ${element.props.children.props.href ||
element.props.children.props.to}`
} else if (typeof element.type === 'symbol' || typeof element.type === 'string') {
return flatten(React.Children.map(element.props.children, element => getDisplayName(element)))
} else {
return (element.type as any).displayName || element.type.name || 'Unknown'
}
if (typeof element.type === 'symbol' || typeof element.type === 'string') {
return flatten(React.Children.map(element.props.children, element => getDisplayName(element)))
}
return (element.type as any).displayName || element.type.name || 'Unknown'
}
return flatten(

View File

@ -118,7 +118,7 @@ export class OrgArea extends React.Component<Props> {
type PartialStateUpdate = Pick<State, 'orgOrError'>
return queryOrganization({ name }).pipe(
catchError(error => [error]),
map(c => ({ orgOrError: c } as PartialStateUpdate)),
map((c): PartialStateUpdate => ({ orgOrError: c })),
// Don't clear old org data while we reload, to avoid unmounting all components during
// loading.

View File

@ -1,7 +1,6 @@
import * as React from 'react'
import { LinkOrSpan } from '../../../shared/src/components/LinkOrSpan'
import { toPrettyBlobURL } from '../../../shared/src/util/url'
import { RepoRev } from '../../../shared/src/util/url'
import { RepoRev, toPrettyBlobURL } from '../../../shared/src/util/url'
import { toTreeURL } from '../util/url'
interface Props {

View File

@ -3,8 +3,7 @@ import AlertCircleIcon from 'mdi-react/AlertCircleIcon'
import * as React from 'react'
import { defer, Subject, Subscription } from 'rxjs'
import { catchError, delay, distinctUntilChanged, map, retryWhen, switchMap, tap } from 'rxjs/operators'
import { RepoQuestionIcon } from '../../../shared/src/components/icons'
import { RepositoryIcon } from '../../../shared/src/components/icons' // TODO: Switch to mdi icon
import { RepoQuestionIcon, RepositoryIcon } from '../../../shared/src/components/icons' // TODO: Switch to mdi icon
import { displayRepoName } from '../../../shared/src/components/RepoFileLink'
import { ErrorLike, isErrorLike } from '../../../shared/src/util/errors'
import { HeroPage } from '../components/HeroPage'

View File

@ -387,7 +387,7 @@ export class Blob extends React.Component<BlobProps, BlobState> {
}
if (decoration.after) {
const codeCell = row.cells[1]!
const codeCell = row.cells[1]
this.createLineDecorationAttachmentDOMNode(line, codeCell)
}
}

View File

@ -103,7 +103,7 @@ export class DiscussionsCreate extends React.PureComponent<Props, State> {
this.props.history.push(location.pathname + location.search + '#' + hash.toString())
}),
map(thread => undefined),
catchError(e => throwError('Error creating thread: ' + asError(e).message))
catchError(e => throwError(new Error('Error creating thread: ' + asError(e).message)))
)
}

View File

@ -164,7 +164,7 @@ export class DiscussionsThread extends React.PureComponent<Props, State> {
return addCommentToThread(this.props.threadID, contents).pipe(
tap(thread => this.setState({ thread })),
map(thread => undefined),
catchError(e => throwError('Error creating comment: ' + asError(e).message))
catchError(e => throwError(new Error('Error creating comment: ' + asError(e).message)))
)
}

View File

@ -92,7 +92,7 @@ export class RepositoryBranchesOverviewPage extends React.PureComponent<Props, S
type PartialStateUpdate = Pick<State, 'dataOrError'>
return queryGitBranches({ repo: repo.id, first: 10 }).pipe(
catchError(error => [error]),
map(c => ({ dataOrError: c } as PartialStateUpdate)),
map((c): PartialStateUpdate => ({ dataOrError: c })),
startWith<PartialStateUpdate>({ dataOrError: undefined })
)
})

View File

@ -84,7 +84,7 @@ describe('QueryBuilder', () => {
const onChange = sinon.spy()
const { container } = render(<QueryBuilder onFieldsQueryChange={onChange} isSourcegraphDotCom={false} />)
const typeField = getBySelectText(container, 'Code (default)')!
const typeField = getBySelectText(container, 'Code (default)')
fireEvent.change(typeField, { target: { value: 'diff' } })
await wait(() => queryByTestId(container, 'test-author'))
@ -101,7 +101,7 @@ describe('QueryBuilder', () => {
const onChange = sinon.spy()
const { container } = render(<QueryBuilder onFieldsQueryChange={onChange} isSourcegraphDotCom={false} />)
const typeField = getBySelectText(container, 'Code (default)')!
const typeField = getBySelectText(container, 'Code (default)')
fireEvent.change(typeField, { target: { value: 'commit' } })
await wait(() => queryByTestId(container, 'test-author'))
@ -118,7 +118,7 @@ describe('QueryBuilder', () => {
const onChange = sinon.spy()
const { container } = render(<QueryBuilder onFieldsQueryChange={onChange} isSourcegraphDotCom={false} />)
const typeField = getBySelectText(container, 'Code (default)')!
const typeField = getBySelectText(container, 'Code (default)')
fireEvent.change(typeField, { target: { value: 'diff' } })
await wait(() => queryByTestId(container, 'test-author'))
@ -132,7 +132,7 @@ describe('QueryBuilder', () => {
const onChange = sinon.spy()
const { container } = render(<QueryBuilder onFieldsQueryChange={onChange} isSourcegraphDotCom={false} />)
const typeField = getBySelectText(container, 'Code (default)')!
const typeField = getBySelectText(container, 'Code (default)')
fireEvent.change(typeField, { target: { value: 'diff' } })
await wait(() => queryByTestId(container, 'test-after'))
@ -147,7 +147,7 @@ describe('QueryBuilder', () => {
const onChange = sinon.spy()
const { container } = render(<QueryBuilder onFieldsQueryChange={onChange} isSourcegraphDotCom={false} />)
const typeField = getBySelectText(container, 'Code (default)')!
const typeField = getBySelectText(container, 'Code (default)')
fireEvent.change(typeField, { target: { value: 'diff' } })
await wait(() => queryByTestId(container, 'test-before'))
@ -162,7 +162,7 @@ describe('QueryBuilder', () => {
const onChange = sinon.spy()
const { container } = render(<QueryBuilder onFieldsQueryChange={onChange} isSourcegraphDotCom={false} />)
const typeField = getBySelectText(container, 'Code (default)')!
const typeField = getBySelectText(container, 'Code (default)')
fireEvent.change(typeField, { target: { value: 'diff' } })
await wait(() => queryByTestId(container, 'test-message'))

View File

@ -402,7 +402,7 @@ function formatFieldForQuery(field: string, value: string, alwaysQuote?: boolean
// if they do, then be helpful and remove it for them to avoid double fields like
// 'repo:repo:foo'.
if (field) {
value = value.replace(new RegExp('^' + field + ':', 'g'), '')
value = value.replace(new RegExp(`^${field}:`, 'g'), '')
}
// See if we need to double-quote value.

View File

@ -16,8 +16,7 @@ import { SearchScope, Settings } from '../../schema/settings.schema'
import { eventLogger } from '../../tracking/eventLogger'
import { fetchReposByQuery } from '../backend'
import { submitSearch } from '../helpers'
import { queryUpdates } from './QueryInput'
import { QueryInput } from './QueryInput'
import { QueryInput, queryUpdates } from './QueryInput'
import { SearchButton } from './SearchButton'
const ScopeNotFound = () => (

View File

@ -54,7 +54,7 @@ export function createSuggestion(item: GQL.SearchSuggestion): Suggestion {
case 'File': {
const descriptionParts = []
const dir = dirname(item.path)
if (dir !== undefined && dir !== '.') {
if (dir !== '.') {
descriptionParts.push(`${dir}/`)
}
descriptionParts.push(basename(item.repository.name))

View File

@ -76,8 +76,8 @@ export const CommitSearchResult: React.FunctionComponent<Props> = (props: Props)
onClick={stopPropagationToCollapseOrExpand}
onMouseDown={logClickOnPerson}
>
<UserAvatar user={props.result.commit.author.person!} size={32} className="mr-1 icon-inline" />
{props.result.commit.author.person!.displayName}
<UserAvatar user={props.result.commit.author.person} size={32} className="mr-1 icon-inline" />
{props.result.commit.author.person.displayName}
</Link>
<Link
to={props.result.commit.url}
@ -159,9 +159,8 @@ export const CommitSearchResult: React.FunctionComponent<Props> = (props: Props)
if (ignoreUntilAtAt && !line.startsWith('@@')) {
lineClasses.push({ line: i + 1, className: 'hidden' })
continue
} else {
ignoreUntilAtAt = false
}
ignoreUntilAtAt = false
if (line.startsWith('diff ')) {
ignoreUntilAtAt = true

View File

@ -136,11 +136,9 @@ export class SearchResultsList extends React.PureComponent<SearchResultsListProp
// Update the `at` query param with the latest first visible item
this.subscriptions.add(
firstVisibleItemChanges
.pipe(
// Skip page load
skip(1)
)
.subscribe(this.setCheckpoint)
// Skip page load
.pipe(skip(1))
.subscribe(checkpoint => this.setCheckpoint(checkpoint))
)
// Remove the "Jump to top" button when the user starts scrolling

View File

@ -95,7 +95,7 @@ export class SavedQueryForm extends React.Component<Props, State> {
try {
const settings = subject.settings
if (settings && settings['notifications.slack']) {
slackWebhookURL = settings['notifications.slack']!.webhookURL
slackWebhookURL = settings['notifications.slack'].webhookURL
}
} catch (e) {
slackWebhookURL = null
@ -328,7 +328,7 @@ export class SavedQueryForm extends React.Component<Props, State> {
return []
})
)
.subscribe(this.props.onDidCommit)
.subscribe(() => this.props.onDidCommit())
)
}

View File

@ -33,7 +33,7 @@ export class Sparkline extends React.PureComponent<Props, State> {
.x((d, i) => x(i))
.y((d, i) => y(Number(d)))
const svg = select(ref!)
const svg = select(ref)
svg.selectAll('*').remove()
const strokeColor = this.props.isLightTheme ? '#cad2e2' : '#566e9f'

View File

@ -8,7 +8,6 @@ import { catchError, distinctUntilChanged, map, startWith, switchMap } from 'rxj
import { extensionIDsFromSettings } from '../../../shared/src/extensions/extension'
import { queryConfiguredRegistryExtensions } from '../../../shared/src/extensions/helpers'
import { gql } from '../../../shared/src/graphql/graphql'
import { ISettingsCascade } from '../../../shared/src/graphql/schema'
import * as GQL from '../../../shared/src/graphql/schema'
import { PlatformContextProps } from '../../../shared/src/platform/context'
import { gqlToCascade, SettingsCascadeProps } from '../../../shared/src/settings/settings'
@ -19,6 +18,7 @@ import { ThemeProps } from '../theme'
import { eventLogger } from '../tracking/eventLogger'
import { mergeSettingsSchemas } from './configuration'
import { SettingsPage } from './SettingsPage'
const NotFoundPage = () => <HeroPage icon={MapSearchIcon} title="404: Not Found" />
/** Props shared by SettingsArea and its sub-pages. */
@ -180,7 +180,7 @@ export class SettingsArea extends React.Component<Props, State> {
}
}
function fetchSettingsCascade(subject: GQL.ID): Observable<Pick<ISettingsCascade, 'subjects'>> {
function fetchSettingsCascade(subject: GQL.ID): Observable<Pick<GQL.ISettingsCascade, 'subjects'>> {
return queryGraphQL(
gql`
query SettingsCascade($subject: ID!) {

View File

@ -3,7 +3,6 @@ import React from 'react'
import { Observable, Subject, Subscription } from 'rxjs'
import { catchError, map, switchMap, tap } from 'rxjs/operators'
import { gql } from '../../../shared/src/graphql/graphql'
import { ExternalServiceKind } from '../../../shared/src/graphql/schema'
import * as GQL from '../../../shared/src/graphql/schema'
import { createAggregateError } from '../../../shared/src/util/errors'
import { mutateGraphQL } from '../backend/graphql'
@ -16,7 +15,7 @@ import { SiteAdminExternalServiceForm } from './SiteAdminExternalServiceForm'
interface Props extends ThemeProps {
history: H.History
kind: ExternalServiceKind
kind: GQL.ExternalServiceKind
variant?: ExternalServiceVariant
eventLogger: {
logViewEvent: (event: 'AddExternalService') => void
@ -67,7 +66,7 @@ export class SiteAdminAddExternalServicePage extends React.Component<Props, Stat
map(() => {
// Refresh site flags so that global site alerts
// reflect the latest configuration.
refreshSiteFlags().subscribe(undefined, err => console.error(err))
refreshSiteFlags().subscribe({ error: err => console.error(err) })
this.setState({ loading: false })
this.props.history.push(`/site-admin/external-services`)

View File

@ -58,22 +58,18 @@ export class SiteAdminAddExternalServicesPage extends React.Component<Props> {
const { kind, variant } = this.getExternalServiceKind()
if (kind) {
return <SiteAdminAddExternalServicePage {...this.props} kind={kind} variant={variant} />
} else {
return (
<div className="add-external-services-page mt-3">
<PageTitle title="Choose an external service type to add" />
<h1>Add external service</h1>
<p>Choose an external service to add to Sourcegraph.</p>
{ALL_EXTERNAL_SERVICE_ADD_VARIANTS.map((service, i) => (
<div className="add-external-services-page__card" key={i}>
<ExternalServiceCard
to={SiteAdminAddExternalServicesPage.getAddURL(service)}
{...service}
/>
</div>
))}
</div>
)
}
return (
<div className="add-external-services-page mt-3">
<PageTitle title="Choose an external service type to add" />
<h1>Add external service</h1>
<p>Choose an external service to add to Sourcegraph.</p>
{ALL_EXTERNAL_SERVICE_ADD_VARIANTS.map((service, i) => (
<div className="add-external-services-page__card" key={i}>
<ExternalServiceCard to={SiteAdminAddExternalServicesPage.getAddURL(service)} {...service} />
</div>
))}
</div>
)
}
}

View File

@ -82,7 +82,7 @@ export class SiteAdminConfigurationPage extends React.Component<Props, State> {
} else {
// Refresh site flags so that global site alerts
// reflect the latest configuration.
refreshSiteFlags().subscribe(undefined, err => console.error(err))
refreshSiteFlags().subscribe({ error: err => console.error(err) })
}
this.setState({ restartToApply })
this.remoteRefreshes.next()

View File

@ -80,7 +80,7 @@ class ExternalServiceNode extends React.PureComponent<ExternalServiceNodeProps,
() => {
// Refresh site flags so that global site alerts
// reflect the latest configuration.
refreshSiteFlags().subscribe(undefined, err => console.error(err))
refreshSiteFlags().subscribe({ error: err => console.error(err) })
this.setState({ loading: false })
if (this.props.onDidUpdate) {
@ -163,7 +163,7 @@ export class SiteAdminExternalServicesPage extends React.PureComponent<Props, {}
}
return data.externalServices
}),
tap(this.completeConnectedCodeHostActivation)
tap(externalServices => this.completeConnectedCodeHostActivation(externalServices))
)
public render(): JSX.Element | null {

View File

@ -143,11 +143,11 @@ export class SiteAdminOverviewPage extends React.Component<Props, State> {
<OverviewItem
link="/site-admin/repositories"
actions="View all repositories"
title={`${numberWithCommas(this.state.info.repositories)} ${
this.state.info.repositories !== null
? pluralize('repository', this.state.info.repositories, 'repositories')
: '?'
}`}
title={`${numberWithCommas(this.state.info.repositories)} ${pluralize(
'repository',
this.state.info.repositories,
'repositories'
)}`}
/>
)}
{this.state.info.users > 1 && (

View File

@ -394,7 +394,7 @@ export function updateSiteConfiguration(lastID: number, input: string): Observab
{ lastID, input }
).pipe(
map(dataOrThrowErrors),
map(data => data.updateSiteConfiguration as boolean)
map(data => data.updateSiteConfiguration)
)
}

View File

@ -96,9 +96,8 @@ class TelligentWrapper {
const match = window.document.cookie.match(matcher)
if (match && match[1]) {
return match[1].split('.')
} else {
return null
}
return null
}
}

View File

@ -103,7 +103,7 @@ const fetchReferencesLink = (): Observable<string | null> =>
}
const repositoryURLs = data.repositories.nodes
.filter(r => r.gitRefs && r.gitRefs.totalCount > 0)
.sort((r1, r2) => r2.gitRefs!.totalCount! - r1.gitRefs!.totalCount)
.sort((r1, r2) => r2.gitRefs.totalCount - r1.gitRefs.totalCount)
.map(r => r.url)
if (repositoryURLs.length === 0) {
return null

View File

@ -1,8 +1,7 @@
import * as H from 'history'
import { isEqual } from 'lodash'
import * as React from 'react'
import { Subscription } from 'rxjs'
import { Subject } from 'rxjs'
import { Subject, Subscription } from 'rxjs'
import { distinctUntilChanged, startWith } from 'rxjs/operators'
import { Key } from 'ts-key-enum'
import { AbsoluteRepo } from '../../../shared/src/util/url'

View File

@ -37,7 +37,7 @@ export function scrollIntoView(el: Element, scrollRoot: Element): void {
export const getDomElement = (path: string): Element | null => document.querySelector(`[data-tree-path='${path}']`)
export const treePadding = (depth: number, isTree: boolean) => ({
marginLeft: depth * 12 + (isTree ? 0 : 12) + 12 + 'px',
marginLeft: `${depth * 12 + (isTree ? 0 : 12) + 12}px`,
paddingRight: '16px',
})

View File

@ -57,7 +57,7 @@ export class UserAccountPasswordPage extends React.Component<Props, State> {
}).pipe(
// Change URL after updating to trigger Chrome to show "Update password?" dialog.
tap(() => this.props.history.replace({ hash: 'updated' })),
catchError(this.handleError)
catchError(err => this.handleError(err))
)
)
)
@ -71,7 +71,7 @@ export class UserAccountPasswordPage extends React.Component<Props, State> {
newPasswordConfirmation: '',
saved: true,
}),
this.handleError
err => this.handleError(err)
)
)
}

View File

@ -99,7 +99,7 @@ export class UserAccountProfilePage extends React.Component<Props, State> {
switchMap(([user]) =>
queryUser(user.id).pipe(
catchError(error => [asError(error)]),
map(c => ({ userOrError: c } as Pick<State, 'userOrError'>))
map((c): Pick<State, 'userOrError'> => ({ userOrError: c }))
)
)
)
@ -120,7 +120,7 @@ export class UserAccountProfilePage extends React.Component<Props, State> {
username: this.state.username === undefined ? null : this.state.username,
displayName: this.state.displayName === undefined ? null : this.state.displayName,
avatarURL: this.state.avatarURL === undefined ? null : this.state.avatarURL,
}).pipe(catchError(this.handleError))
}).pipe(catchError(err => this.handleError(err)))
),
tap(() => {
this.setState({ loading: false, saved: true })
@ -139,7 +139,7 @@ export class UserAccountProfilePage extends React.Component<Props, State> {
// In case the edited user is the current user, immediately reflect the changes in the UI.
mergeMap(() => concat(refreshAuthenticatedUser(), [null]))
)
.subscribe(undefined, this.handleError)
.subscribe({ error: err => this.handleError(err) })
)
this.componentUpdates.next(this.props)
}

View File

@ -143,7 +143,7 @@ export class UserArea extends React.Component<UserAreaProps, UserAreaState> {
type PartialStateUpdate = Pick<UserAreaState, 'userOrError'>
return fetchUser({ username }).pipe(
catchError(error => [error]),
map(c => ({ userOrError: c } as PartialStateUpdate)),
map((c): PartialStateUpdate => ({ userOrError: c })),
// Don't clear old user data while we reload, to avoid unmounting all components during
// loading.

118
yarn.lock
View File

@ -853,6 +853,14 @@
"@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-transform-typescript" "^7.1.0"
"@babel/runtime-corejs2@^7.2.0":
version "7.4.2"
resolved "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.4.2.tgz#a0cec2c41717fa415e9c204f32b603d88b1796c2"
integrity sha512-y/Br/9uQnumcqcakkmobFqOTzYCWSS6Kuy1b2o7LTXR4lpeU0AhaOcPqIHW85LCxRWUDW5Vg0pU1KlE3YkORlg==
dependencies:
core-js "^2.6.5"
regenerator-runtime "^0.13.2"
"@babel/runtime@7.0.0":
version "7.0.0"
resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.0.0.tgz#adeb78fedfc855aa05bc041640f3f6f98e85424c"
@ -1436,7 +1444,8 @@
integrity sha512-Te7F1RQJLBH4C8wQ2xz0nPC2vpe13F80V+Yv+c3GySOoh4DcLNN4P5u51Kh4aZPqeS5DJ7CKvHyX2SM/1EBXNg==
"@sourcegraph/extension-api-types@link:packages/@sourcegraph/extension-api-types":
version "2.0.0"
version "0.0.0"
uid ""
"@sourcegraph/prettierrc@^2.2.0":
version "2.2.0"
@ -1462,14 +1471,14 @@
resolved "https://registry.npmjs.org/@sourcegraph/tsconfig/-/tsconfig-4.0.0.tgz#dd2a406f90760bb789fd89fde4bd0a8d681f2767"
integrity sha512-jxrhKbek4yu1HUDpUhqR9hAGFiUgaJ9NIM+c8JEkAnvpW67ab1AUFWb82aSVfZWX1UVqfR84AMr7xP3E8LlL+A==
"@sourcegraph/tslint-config@^12.3.1":
version "12.3.1"
resolved "https://registry.npmjs.org/@sourcegraph/tslint-config/-/tslint-config-12.3.1.tgz#54570f56255c3c4139105fd18ea542e847e0710f"
integrity sha512-XG/H+QPARCTIXtL4bLBP1W93MniqBYIkDEkld6gdbRT3i4sBMXw+IwZwC3NdroEjEe5OKgXNBh1Y8edxBL/hdw==
"@sourcegraph/tslint-config@^13.0.0":
version "13.0.0"
resolved "https://registry.npmjs.org/@sourcegraph/tslint-config/-/tslint-config-13.0.0.tgz#f75d2ea51972c9f8cab233de98824b954457729b"
integrity sha512-kDWngKXc7Qu8rdtsUP1pics0vOIx37e1ygjyrxMfhav722dhByxYowK3AxcbyECyaKEYt0wCp+bCqeVQX+XksQ==
dependencies:
rxjs-tslint-rules "^4.12.0"
tslint-config-prettier "^1.6.0"
tslint-react "^3.2.0"
rxjs-tslint-rules "^4.19.1"
tslint-config-prettier "^1.18.0"
tslint-react "^4.0.0"
"@sqs/jsonc-parser@^1.0.3":
version "1.0.3"
@ -4990,6 +4999,11 @@ core-js@^2.4.0, core-js@^2.5.7:
resolved "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e"
integrity sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==
core-js@^2.6.5:
version "2.6.5"
resolved "https://registry.npmjs.org/core-js/-/core-js-2.6.5.tgz#44bc8d249e7fb2ff5d00e0341a7ffb94fbf67895"
integrity sha512-klh/kDpwX8hryYL14M9w/xei6vrv6sE8gTHDG7/T/+SEovB/G4ejwcfE/CBzO6Edsu+OETZMZ3wcX/EjUkrl5A==
core-util-is@1.0.2, core-util-is@~1.0.0:
version "1.0.2"
resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
@ -5558,6 +5572,13 @@ decamelize@^2.0.0:
dependencies:
xregexp "4.0.0"
decamelize@^3.0.0:
version "3.1.1"
resolved "https://registry.npmjs.org/decamelize/-/decamelize-3.1.1.tgz#ebf473c6f8607bd70fd9ed6d892da27c5eb8539e"
integrity sha512-pSJTQCBDZxv8siK5p/M42ZdhThhTtx3JU/OKli0yQSKebfM9q92op6zF7krYrWVKRtsE/RwTDiZLliMV3ECkXQ==
dependencies:
xregexp "^4.2.4"
decode-uri-component@^0.2.0:
version "0.2.0"
resolved "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
@ -8851,7 +8872,7 @@ js-tokens@^3.0.2:
resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls=
js-yaml@^3.10.0, js-yaml@^3.12.0, js-yaml@^3.7.0, js-yaml@^3.9.0:
js-yaml@^3.10.0, js-yaml@^3.12.0, js-yaml@^3.9.0:
version "3.12.0"
resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1"
integrity sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==
@ -8859,6 +8880,14 @@ js-yaml@^3.10.0, js-yaml@^3.12.0, js-yaml@^3.7.0, js-yaml@^3.9.0:
argparse "^1.0.7"
esprima "^4.0.0"
js-yaml@^3.13.0:
version "3.13.0"
resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.0.tgz#38ee7178ac0eea2c97ff6d96fff4b18c7d8cf98e"
integrity sha512-pZZoSxcCYco+DIKBTimr67J6Hy+EYGZDY/HCWC+iAEA9h1ByhMXAIVUXMcMFpOCxQ/xjXmPI2MkDL5HRm5eFrQ==
dependencies:
argparse "^1.0.7"
esprima "^4.0.0"
jsbn@~0.1.0:
version "0.1.1"
resolved "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
@ -12261,6 +12290,11 @@ regenerator-runtime@^0.13.1:
resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.1.tgz#522ea2aafd9200a00eee143dc14219a35a0f3991"
integrity sha512-5KzMIyPLvfdPmvsdlYsHqITrDfK9k7bmvf97HvHSN4810i254ponbxCQ1NukpRWlu6en2MBWzAlhDExEKISwAA==
regenerator-runtime@^0.13.2:
version "0.13.2"
resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz#32e59c9a6fb9b1a4aff09b4930ca2d4477343447"
integrity sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA==
regenerator-transform@^0.13.3:
version "0.13.3"
resolved "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.13.3.tgz#264bd9ff38a8ce24b06e0636496b2c856b57bcbb"
@ -12679,16 +12713,17 @@ run-queue@^1.0.0, run-queue@^1.0.3:
dependencies:
aproba "^1.1.1"
rxjs-tslint-rules@^4.12.0:
version "4.12.0"
resolved "https://registry.npmjs.org/rxjs-tslint-rules/-/rxjs-tslint-rules-4.12.0.tgz#92cf4c26d53163afdc32d4d8a23c7c13faa9e988"
integrity sha512-JaCcoy7m4r/uktKjAdh70e+ijcTqozwKEU82N66tJ1dhSfzBgUX7bxopv/yQiHZ2BOeqRN61VfRMagqXTuzgdg==
rxjs-tslint-rules@^4.19.1:
version "4.19.1"
resolved "https://registry.npmjs.org/rxjs-tslint-rules/-/rxjs-tslint-rules-4.19.1.tgz#e5328cface0a0d0b52f2601082fa1ffd617f7869"
integrity sha512-TwosfLg5HgG6vSq6uHM49cUMJxX6ZfF8Cd4/r7TPc/h4hV2vm675T7zwO49MD2YxNpQbge4Xi8EOzn8XvJwYAA==
dependencies:
"@phenomnomnominal/tsquery" "^3.0.0"
decamelize "^2.0.0"
decamelize "^3.0.0"
resolve "^1.4.0"
tslib "^1.8.0"
tsutils "^3.0.0"
tsutils-etc "^1.1.0"
rxjs@^6.0.0, rxjs@^6.1.0, rxjs@^6.3.2, rxjs@^6.3.3, rxjs@^6.4.0:
version "6.4.0"
@ -13249,7 +13284,8 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1:
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
"sourcegraph@link:packages/sourcegraph-extension-api":
version "23.0.0"
version "0.0.0"
uid ""
space-separated-tokens@^1.0.0:
version "1.1.2"
@ -14185,10 +14221,10 @@ tslib@^1, tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3:
resolved "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286"
integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==
tslint-config-prettier@^1.6.0:
version "1.15.0"
resolved "https://registry.npmjs.org/tslint-config-prettier/-/tslint-config-prettier-1.15.0.tgz#76b9714399004ab6831fdcf76d89b73691c812cf"
integrity sha512-06CgrHJxJmNYVgsmeMoa1KXzQRoOdvfkqnJth6XUkNeOz707qxN0WfxfhYwhL5kXHHbYJRby2bqAPKwThlZPhw==
tslint-config-prettier@^1.18.0:
version "1.18.0"
resolved "https://registry.npmjs.org/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz#75f140bde947d35d8f0d238e0ebf809d64592c37"
integrity sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg==
tslint-language-service@^0.9.9:
version "0.9.9"
@ -14197,17 +14233,17 @@ tslint-language-service@^0.9.9:
dependencies:
mock-require "^2.0.2"
tslint-react@^3.2.0:
version "3.6.0"
resolved "https://registry.npmjs.org/tslint-react/-/tslint-react-3.6.0.tgz#7f462c95c4a0afaae82507f06517ff02942196a1"
integrity sha512-AIv1QcsSnj7e9pFir6cJ6vIncTqxfqeFF3Lzh8SuuBljueYzEAtByuB6zMaD27BL0xhMEqsZ9s5eHuCONydjBw==
tslint-react@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/tslint-react/-/tslint-react-4.0.0.tgz#b4bb4c01c32448cb14d23f143a2f5e4989bb961e"
integrity sha512-9fNE0fm9zNDx1+b6hgy8rgDN2WsQLRiIrn3+fbqm0tazBVF6jiaCFAITxmU+WSFWYE03Xhp1joCircXOe1WVAQ==
dependencies:
tsutils "^2.13.1"
tsutils "^3.9.1"
tslint@^5.12.0:
version "5.12.0"
resolved "https://registry.npmjs.org/tslint/-/tslint-5.12.0.tgz#47f2dba291ed3d580752d109866fb640768fca36"
integrity sha512-CKEcH1MHUBhoV43SA/Jmy1l24HJJgI0eyLbBNSRyFlsQvb9v6Zdq+Nz2vEOH00nC5SUx4SneJ59PZUS/ARcokQ==
tslint@^5.15.0:
version "5.15.0"
resolved "https://registry.npmjs.org/tslint/-/tslint-5.15.0.tgz#6ffb180986d63afa1e531feb2a134dbf961e27d3"
integrity sha512-6bIEujKR21/3nyeoX2uBnE8s+tMXCQXhqMmaIPJpHmXJoBJPTLcI7/VHRtUwMhnLVdwLqqY3zmd8Dxqa5CVdJA==
dependencies:
babel-code-frame "^6.22.0"
builtin-modules "^1.1.1"
@ -14215,14 +14251,20 @@ tslint@^5.12.0:
commander "^2.12.1"
diff "^3.2.0"
glob "^7.1.1"
js-yaml "^3.7.0"
js-yaml "^3.13.0"
minimatch "^3.0.4"
mkdirp "^0.5.1"
resolve "^1.3.2"
semver "^5.3.0"
tslib "^1.8.0"
tsutils "^2.27.2"
tsutils "^2.29.0"
tsutils@^2.13.1, tsutils@^2.27.2:
tsutils-etc@^1.1.0:
version "1.1.0"
resolved "https://registry.npmjs.org/tsutils-etc/-/tsutils-etc-1.1.0.tgz#82ce1c92da29e07d3cde95692d5c5e8dbdc92fd0"
integrity sha512-pJlLtLmQPUyGHqY/Pq6EGnpGmQCnnTDZetQ7eWkeQ5xaw4GtfcR1Zt7HMKFHGDDp53HzQfbqQ+7ps6iJbfa9Hw==
tsutils@^2.29.0:
version "2.29.0"
resolved "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99"
integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==
@ -14236,6 +14278,13 @@ tsutils@^3.0.0:
dependencies:
tslib "^1.8.1"
tsutils@^3.9.1:
version "3.9.1"
resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.9.1.tgz#2a40dc742943c71eca6d5c1994fcf999956be387"
integrity sha512-hrxVtLtPqQr//p8/msPT1X1UYXUjizqSit5d9AQ5k38TcV38NyecL5xODNxa73cLe/5sdiJ+w1FqzDhRBA/anA==
dependencies:
tslib "^1.8.1"
tty-browserify@0.0.0:
version "0.0.0"
resolved "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6"
@ -15140,6 +15189,13 @@ xregexp@4.0.0:
resolved "https://registry.npmjs.org/xregexp/-/xregexp-4.0.0.tgz#e698189de49dd2a18cc5687b05e17c8e43943020"
integrity sha512-PHyM+sQouu7xspQQwELlGwwd05mXUFqwFYfqPO0cC7x4fxyHnnuetmQr6CjJiafIDoH4MogHb9dOoJzR/Y4rFg==
xregexp@^4.2.4:
version "4.2.4"
resolved "https://registry.npmjs.org/xregexp/-/xregexp-4.2.4.tgz#02a4aea056d65a42632c02f0233eab8e4d7e57ed"
integrity sha512-sO0bYdYeJAJBcJA8g7MJJX7UrOZIfJPd8U2SC7B2Dd/J24U0aQNoGp33shCaBSWeb0rD5rh6VBUIXOkGal1TZA==
dependencies:
"@babel/runtime-corejs2" "^7.2.0"
xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.0, xtend@~4.0.1:
version "4.0.1"
resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"