@@ -15,7 +15,7 @@ import * as MarkdownItType from 'markdown-it';
1515import { languages , workspace , Disposable , TextDocument , Uri , Diagnostic , Range , DiagnosticSeverity , Position , env } from 'vscode' ;
1616
1717const product = JSON . parse ( fs . readFileSync ( path . join ( env . appRoot , 'product.json' ) , { encoding : 'utf-8' } ) ) ;
18- const allowedBadgeProviders : string [ ] = ( product . extensionAllowedBadgeProviders || [ ] ) . map ( s => s . toLowerCase ( ) ) ;
18+ const allowedBadgeProviders : string [ ] = ( product . extensionAllowedBadgeProviders || [ ] ) . map ( ( s : string ) => s . toLowerCase ( ) ) ;
1919
2020const httpsRequired = localize ( 'httpsRequired' , "Images must use the HTTPS protocol." ) ;
2121const svgsNotValid = localize ( 'svgsNotValid' , "SVGs are not a valid image source." ) ;
@@ -52,8 +52,8 @@ export class ExtensionLinter {
5252 private folderToPackageJsonInfo : Record < string , PackageJsonInfo > = { } ;
5353 private packageJsonQ = new Set < TextDocument > ( ) ;
5454 private readmeQ = new Set < TextDocument > ( ) ;
55- private timer : NodeJS . Timer ;
56- private markdownIt : MarkdownItType . MarkdownIt ;
55+ private timer : NodeJS . Timer | undefined ;
56+ private markdownIt : MarkdownItType . MarkdownIt | undefined ;
5757
5858 constructor ( ) {
5959 this . disposables . push (
@@ -118,10 +118,10 @@ export class ExtensionLinter {
118118 }
119119
120120 const badges = findNodeAtLocation ( tree , [ 'badges' ] ) ;
121- if ( badges && badges . type === 'array' ) {
121+ if ( badges && badges . type === 'array' && badges . children ) {
122122 badges . children . map ( child => findNodeAtLocation ( child , [ 'url' ] ) )
123123 . filter ( url => url && url . type === 'string' )
124- . map ( url => this . addDiagnostics ( diagnostics , document , url . offset + 1 , url . offset + url . length - 1 , url . value , Context . BADGE , info ) ) ;
124+ . map ( url => this . addDiagnostics ( diagnostics , document , url ! . offset + 1 , url ! . offset + url ! . length - 1 , url ! . value , Context . BADGE , info ) ) ;
125125 }
126126
127127 }
@@ -152,7 +152,7 @@ export class ExtensionLinter {
152152 this . markdownIt = new ( await import ( 'markdown-it' ) ) ;
153153 }
154154 const tokens = this . markdownIt . parse ( text , { } ) ;
155- const tokensAndPositions = ( function toTokensAndPositions ( this : ExtensionLinter , tokens : MarkdownItType . Token [ ] , begin = 0 , end = text . length ) : TokenAndPosition [ ] {
155+ const tokensAndPositions : TokenAndPosition [ ] = ( function toTokensAndPositions ( this : ExtensionLinter , tokens : MarkdownItType . Token [ ] , begin = 0 , end = text . length ) : TokenAndPosition [ ] {
156156 const tokensAndPositions = tokens . map < TokenAndPosition > ( token => {
157157 if ( token . map ) {
158158 const tokenBegin = document . offsetAt ( new Position ( token . map [ 0 ] , 0 ) ) ;
@@ -181,7 +181,7 @@ export class ExtensionLinter {
181181
182182 tokensAndPositions . filter ( tnp => tnp . token . type === 'image' && tnp . token . attrGet ( 'src' ) )
183183 . map ( inp => {
184- const src = inp . token . attrGet ( 'src' ) ;
184+ const src = inp . token . attrGet ( 'src' ) ! ;
185185 const begin = text . indexOf ( src , inp . begin ) ;
186186 if ( begin !== - 1 && begin < inp . end ) {
187187 this . addDiagnostics ( diagnostics , document , begin , begin + src . length , src , Context . MARKDOWN , info ) ;
@@ -199,16 +199,16 @@ export class ExtensionLinter {
199199 if ( tnp . token . type === 'text' && tnp . token . content ) {
200200 const parse5 = await import ( 'parse5' ) ;
201201 const parser = new parse5 . SAXParser ( { locationInfo : true } ) ;
202- parser . on ( 'startTag' , ( name , attrs , selfClosing , location ) => {
202+ parser . on ( 'startTag' , ( name , attrs , _selfClosing , location ) => {
203203 if ( name === 'img' ) {
204204 const src = attrs . find ( a => a . name === 'src' ) ;
205- if ( src && src . value ) {
205+ if ( src && src . value && location ) {
206206 const begin = text . indexOf ( src . value , tnp . begin + location . startOffset ) ;
207207 if ( begin !== - 1 && begin < tnp . end ) {
208208 this . addDiagnostics ( diagnostics , document , begin , begin + src . value . length , src . value , Context . MARKDOWN , info ) ;
209209 }
210210 }
211- } else if ( name === 'svg' ) {
211+ } else if ( name === 'svg' && location ) {
212212 const begin = tnp . begin + location . startOffset ;
213213 const end = tnp . begin + location . endOffset ;
214214 const range = new Range ( document . positionAt ( begin ) , document . positionAt ( end ) ) ;
@@ -217,7 +217,7 @@ export class ExtensionLinter {
217217 }
218218 } ) ;
219219 parser . on ( 'endTag' , ( name , location ) => {
220- if ( name === 'svg' && svgStart ) {
220+ if ( name === 'svg' && svgStart && location ) {
221221 const end = tnp . begin + location . endOffset ;
222222 svgStart . range = new Range ( svgStart . range . start , document . positionAt ( end ) ) ;
223223 }
@@ -231,7 +231,7 @@ export class ExtensionLinter {
231231 }
232232 }
233233
234- private locateToken ( text : string , begin : number , end : number , token : MarkdownItType . Token , content : string ) {
234+ private locateToken ( text : string , begin : number , end : number , token : MarkdownItType . Token , content : string | null ) {
235235 if ( content ) {
236236 const tokenBegin = text . indexOf ( content , begin ) ;
237237 if ( tokenBegin !== - 1 ) {
@@ -246,16 +246,17 @@ export class ExtensionLinter {
246246 }
247247 }
248248 }
249+ return undefined ;
249250 }
250251
251- private readPackageJsonInfo ( folder : Uri , tree : JsonNode ) {
252+ private readPackageJsonInfo ( folder : Uri , tree : JsonNode | undefined ) {
252253 const engine = tree && findNodeAtLocation ( tree , [ 'engines' , 'vscode' ] ) ;
253254 const repo = tree && findNodeAtLocation ( tree , [ 'repository' , 'url' ] ) ;
254255 const uri = repo && parseUri ( repo . value ) ;
255256 const info : PackageJsonInfo = {
256257 isExtension : ! ! ( engine && engine . type === 'string' ) ,
257258 hasHttpsRepository : ! ! ( repo && repo . type === 'string' && repo . value && uri && uri . scheme . toLowerCase ( ) === 'https' ) ,
258- repository : uri
259+ repository : uri !
259260 } ;
260261 const str = folder . toString ( ) ;
261262 const oldInfo = this . folderToPackageJsonInfo [ str ] ;
@@ -348,7 +349,7 @@ function endsWith(haystack: string, needle: string): boolean {
348349 }
349350}
350351
351- function parseUri ( src : string , base ?: string , retry : boolean = true ) : Uri {
352+ function parseUri ( src : string , base ?: string , retry : boolean = true ) : Uri | null {
352353 try {
353354 let url = new URL ( src , base ) ;
354355 return Uri . parse ( url . toString ( ) ) ;
0 commit comments