@@ -87,6 +87,34 @@ if (Number.isNaN(issueNumber)) {
8787 throw new TypeError ( 'SHOWCASE_ISSUE must be a valid number' )
8888}
8989
90+ function parseProxyOption ( args : string [ ] ) : { enabled : boolean , url ?: string } {
91+ for ( let index = 0 ; index < args . length ; index += 1 ) {
92+ const arg = args [ index ]
93+ if ( ! arg ) {
94+ continue
95+ }
96+
97+ if ( arg === '--no-proxy' ) {
98+ return { enabled : false }
99+ }
100+
101+ if ( arg === '--proxy' ) {
102+ const next = args [ index + 1 ]
103+ if ( next && ! next . startsWith ( '-' ) ) {
104+ return { enabled : true , url : next }
105+ }
106+ return { enabled : true }
107+ }
108+
109+ if ( arg . startsWith ( '--proxy=' ) ) {
110+ const url = arg . slice ( '--proxy=' . length ) . trim ( )
111+ return url ? { enabled : true , url } : { enabled : true }
112+ }
113+ }
114+
115+ return { enabled : false }
116+ }
117+
90118const apiBase = `https://api.github.com/repos/${ repo } `
91119const issueApiUrl = `${ apiBase } /issues/${ issueNumber } `
92120const commentsApiUrl = `${ issueApiUrl } /comments`
@@ -95,13 +123,15 @@ const imageTimeoutMs = Number.isFinite(parsedTimeout) && parsedTimeout > 0 ? par
95123const parsedAttempts = Number ( process . env . SHOWCASE_IMAGE_RETRY ?? '3' )
96124const maxDownloadAttempts = Number . isFinite ( parsedAttempts ) && parsedAttempts > 0 ? parsedAttempts : 3
97125const skipImageDownload = / ^ 1 | t r u e $ / i. test ( process . env . SHOWCASE_SKIP_IMAGES ?? '' )
98- const proxyUrl
126+ const proxyOption = parseProxyOption ( process . argv . slice ( 2 ) )
127+ const defaultProxyUrl
99128 = process . env . SHOWCASE_PROXY
100129 ?? process . env . HTTPS_PROXY
101130 ?? process . env . HTTP_PROXY
102131 ?? 'http://127.0.0.1:7890'
132+ const proxyUrl = proxyOption . enabled ? ( proxyOption . url ?. trim ( ) || defaultProxyUrl ) : null
103133
104- if ( proxyUrl ) {
134+ if ( proxyUrl && proxyOption . enabled ) {
105135 try {
106136 const agent = new ProxyAgent ( proxyUrl )
107137 setGlobalDispatcher ( agent )
@@ -245,7 +275,8 @@ function stripImages(body: string): { text: string, images: RemoteImage[] } {
245275 continue
246276 }
247277 if ( ! seen . has ( url ) ) {
248- images . push ( { url, alt : match [ 1 ] ?. trim ( ) } )
278+ const alt = match [ 1 ] ?. trim ( )
279+ images . push ( alt ? { url, alt } : { url } )
249280 seen . add ( url )
250281 }
251282 const start = match . index ?? 0
@@ -261,7 +292,8 @@ function stripImages(body: string): { text: string, images: RemoteImage[] } {
261292 }
262293 if ( ! seen . has ( url ) ) {
263294 const altMatch = raw . match ( / a l t = [ " ' ] ( [ ^ " ' ] * ) [ " ' ] / i)
264- images . push ( { url, alt : altMatch ?. [ 1 ] ?. trim ( ) } )
295+ const alt = altMatch ?. [ 1 ] ?. trim ( )
296+ images . push ( alt ? { url, alt } : { url } )
265297 seen . add ( url )
266298 }
267299 const start = match . index ?? 0
@@ -345,16 +377,17 @@ function parseDisplayValue(value: string): DisplayValue | undefined {
345377
346378 const markdownLinkMatch = trimmed . match ( / \[ ( [ ^ \] ] + ) \] \( ( [ ^ ) ] + ) \) / )
347379 if ( markdownLinkMatch ) {
348- const url = sanitizeUrl ( markdownLinkMatch [ 2 ] ) ?? undefined
349- const text = markdownLinkMatch [ 1 ] . trim ( ) || url || trimmed
350- return { text, url }
380+ const url = sanitizeUrl ( markdownLinkMatch [ 2 ] )
381+ const urlText = url ?? ''
382+ const text = markdownLinkMatch [ 1 ] ?. trim ( ) || urlText || trimmed
383+ return url ? { text, url } : { text }
351384 }
352385
353386 const urlMatch = trimmed . match ( / h t t p s ? : \/ \/ \S + / )
354387 if ( urlMatch ) {
355- const url = sanitizeUrl ( urlMatch [ 0 ] ) ?? undefined
388+ const url = sanitizeUrl ( urlMatch [ 0 ] )
356389 const text = trimmed . replace ( urlMatch [ 0 ] , '' ) . trim ( ) || urlMatch [ 0 ]
357- return { text, url }
390+ return url ? { text, url } : { text }
358391 }
359392
360393 return { text : trimmed }
@@ -390,22 +423,28 @@ function parseComment(comment: GitHubComment): ParsedEntry | null {
390423 const keyValueMatch = line . match ( / ^ ( [ ^ : : ] + ) [ : : ] ( .* ) $ / )
391424
392425 if ( keyValueMatch ) {
393- const [ , rawLabel , rawValue ] = keyValueMatch
426+ const rawLabel = keyValueMatch [ 1 ] ?. trim ( )
427+ const rawValue = keyValueMatch [ 2 ]
428+ if ( ! rawLabel || rawValue == null ) {
429+ extra . push ( originalLine )
430+ continue
431+ }
394432 const normalized = normalizeLabel ( rawLabel )
433+ const value = rawValue . trim ( )
395434 if ( normalized === 'name' && ! name ) {
396- name = rawValue . trim ( )
435+ name = value
397436 continue
398437 }
399438 if ( normalized === 'link' && ! link ) {
400- link = parseDisplayValue ( rawValue . trim ( ) )
439+ link = parseDisplayValue ( value )
401440 continue
402441 }
403442 if ( normalized === 'github' && ! github ) {
404- github = parseDisplayValue ( rawValue . trim ( ) )
443+ github = parseDisplayValue ( value )
405444 continue
406445 }
407446 if ( normalized === 'description' && ! description ) {
408- description = rawValue . trim ( )
447+ description = value
409448 continue
410449 }
411450 }
@@ -429,22 +468,32 @@ function parseComment(comment: GitHubComment): ParsedEntry | null {
429468 return null
430469 }
431470
432- const descriptionText = descriptionParts . length
471+ const normalizedDescription = descriptionParts . length
433472 ? sanitizeDescriptionContent ( descriptionParts . join ( '\n\n' ) )
434- : undefined
473+ : ''
474+ const descriptionText = normalizedDescription || undefined
435475
436- return {
476+ const parsedEntry : ParsedEntry = {
437477 id : comment . id ,
438478 commentUrl : comment . html_url ,
439479 createdAt : comment . created_at ,
440480 author : comment . user ,
441481 name : programName ,
442- link,
443- github,
444- description : descriptionText ,
445482 remoteImages : images ,
446483 slugSource : programName ,
447484 }
485+
486+ if ( link ) {
487+ parsedEntry . link = link
488+ }
489+ if ( github ) {
490+ parsedEntry . github = github
491+ }
492+ if ( descriptionText ) {
493+ parsedEntry . description = descriptionText
494+ }
495+
496+ return parsedEntry
448497}
449498
450499function slugifySegment ( value : string , fallback : string ) : string {
@@ -507,7 +556,10 @@ function resolveImageExtension(contentType: string | null, url: string): string
507556 const { pathname } = new URL ( url )
508557 const extMatch = pathname . match ( / \. ( [ a - z 0 - 9 ] + ) $ / i)
509558 if ( extMatch ) {
510- return extMatch [ 1 ] . toLowerCase ( )
559+ const ext = extMatch [ 1 ]
560+ if ( ext ) {
561+ return ext . toLowerCase ( )
562+ }
511563 }
512564 }
513565 catch ( _error ) {
@@ -743,6 +795,9 @@ async function main() {
743795 }
744796
745797 const fallback = entry . remoteImages [ idx ]
798+ if ( ! fallback ) {
799+ return
800+ }
746801 allImages . push ( {
747802 alt : fallback . alt ?. trim ( ) || '' ,
748803 src : fallback . url ,
0 commit comments