@@ -12,18 +12,28 @@ import {
1212} from '../constants' ;
1313import { DOMParser } from '@xmldom/xmldom' ;
1414import path from 'node:path' ;
15+ import type {
16+ AdditionalDriverDetails ,
17+ ChromedriverDetails ,
18+ ChromedriverDetailsMapping ,
19+ } from '../types' ;
1520
1621const log = logger . getLogger ( 'ChromedriverGoogleapisStorageClient' ) ;
1722const MAX_PARALLEL_DOWNLOADS = 5 ;
1823
1924/**
25+ * Finds a child node in an XML node by name and/or text content
2026 *
21- * @param { Node|Attr } parent
22- * @param { string? } childName
23- * @param { string? } text
24- * @returns
27+ * @param parent - The parent XML node to search in
28+ * @param childName - Optional child node name to match
29+ * @param text - Optional text content to match
30+ * @returns The matching child node or null if not found
2531 */
26- export function findChildNode ( parent , childName = null , text = null ) {
32+ export function findChildNode (
33+ parent : Node | Attr ,
34+ childName : string | null = null ,
35+ text : string | null = null
36+ ) : Node | Attr | null {
2737 if ( ! childName && ! text ) {
2838 return null ;
2939 }
@@ -32,7 +42,7 @@ export function findChildNode(parent, childName = null, text = null) {
3242 }
3343
3444 for ( let childNodeIdx = 0 ; childNodeIdx < parent . childNodes . length ; childNodeIdx ++ ) {
35- const childNode = /** @type { Element|Attr } */ ( parent . childNodes [ childNodeIdx ] ) ;
45+ const childNode = parent . childNodes [ childNodeIdx ] as Element | Attr ;
3646 if ( childName && ! text && childName === childNode . localName ) {
3747 return childNode ;
3848 }
@@ -52,26 +62,15 @@ export function findChildNode(parent, childName = null, text = null) {
5262 return null ;
5363}
5464
55- /**
56- *
57- * @param {Node? } node
58- * @returns
59- */
60- function extractNodeText ( node ) {
61- return ! node ?. firstChild || ! util . hasValue ( node . firstChild . nodeValue )
62- ? null
63- : node . firstChild . nodeValue ;
64- }
65-
6665/**
6766 * Gets additional chromedriver details from chromedriver
6867 * release notes
6968 *
70- * @param { string } content - Release notes of the corresponding chromedriver
71- * @returns { import('../types'). AdditionalDriverDetails}
69+ * @param content - Release notes of the corresponding chromedriver
70+ * @returns AdditionalDriverDetails
7271 */
73- export function parseNotes ( content ) {
74- const result = { } ;
72+ export function parseNotes ( content : string ) : AdditionalDriverDetails {
73+ const result : AdditionalDriverDetails = { } ;
7574 const versionMatch = / ^ \s * [ - ] + C h r o m e D r i v e r [ \D ] + ( [ \d . ] + ) / im. exec ( content ) ;
7675 if ( versionMatch ) {
7776 result . version = versionMatch [ 1 ] ;
@@ -87,27 +86,26 @@ export function parseNotes(content) {
8786 * Parses chromedriver storage XML and returns
8887 * the parsed results
8988 *
90- * @param { string } xml - The chromedriver storage XML
91- * @param { boolean } shouldParseNotes [true] - If set to `true`
89+ * @param xml - The chromedriver storage XML
90+ * @param shouldParseNotes [true] - If set to `true`
9291 * then additional drivers information is going to be parsed
9392 * and assigned to `this.mapping`
94- * @returns { Promise<ChromedriverDetailsMapping> }
93+ * @returns Promise<ChromedriverDetailsMapping>
9594 */
96- export async function parseGoogleapiStorageXml ( xml , shouldParseNotes = true ) {
95+ export async function parseGoogleapiStorageXml (
96+ xml : string ,
97+ shouldParseNotes = true
98+ ) : Promise < ChromedriverDetailsMapping > {
9799 const doc = new DOMParser ( ) . parseFromString ( xml , 'text/xml' ) ;
98- const driverNodes = /** @type {Array<Node|Attr> } */ (
99- // https://github.com/xmldom/xmldom/issues/724
100- xpathSelect ( `//*[local-name(.)='Contents']` , doc )
101- ) ;
100+ const driverNodes = xpathSelect ( `//*[local-name(.)='Contents']` , doc ) as Array < Node | Attr > ;
102101 log . debug ( `Parsed ${ driverNodes . length } entries from storage XML` ) ;
103102 if ( _ . isEmpty ( driverNodes ) ) {
104103 throw new Error ( 'Cannot retrieve any valid Chromedriver entries from the storage config' ) ;
105104 }
106105
107- const promises = [ ] ;
108- const chunk = [ ] ;
109- /** @type {ChromedriverDetailsMapping } */
110- const mapping = { } ;
106+ const promises : Promise < void > [ ] = [ ] ;
107+ const chunk : Promise < void > [ ] = [ ] ;
108+ const mapping : ChromedriverDetailsMapping = { } ;
111109 for ( const driverNode of driverNodes ) {
112110 const k = extractNodeText ( findChildNode ( driverNode , 'Key' ) ) ;
113111 if ( ! _ . includes ( k , '/chromedriver_' ) ) {
@@ -128,17 +126,16 @@ export async function parseGoogleapiStorageXml(xml, shouldParseNotes = true) {
128126 continue ;
129127 }
130128
131- /** @type {ChromedriverDetails } */
132- const cdInfo = {
129+ const cdInfo : ChromedriverDetails = {
133130 url : `${ GOOGLEAPIS_CDN } /${ key } ` ,
134131 etag : _ . trim ( etag , '"' ) ,
135- version : /** @type { string } */ ( _ . first ( key . split ( '/' ) ) ) ,
132+ version : _ . first ( key . split ( '/' ) ) as string ,
136133 minBrowserVersion : null ,
137134 os : {
138135 name : osNameMatch [ 1 ] ,
139136 arch : filename . includes ( ARCH . X64 ) ? ARCH . X64 : ARCH . X86 ,
140137 cpu : APPLE_ARM_SUFFIXES . some ( ( suffix ) => filename . includes ( suffix ) ) ? CPU . ARM : CPU . INTEL ,
141- }
138+ } ,
142139 } ;
143140 mapping [ key ] = cdInfo ;
144141
@@ -157,31 +154,36 @@ export async function parseGoogleapiStorageXml(xml, shouldParseNotes = true) {
157154 continue ;
158155 }
159156
160- const promise = B . resolve ( retrieveAdditionalDriverInfo ( key , `${ GOOGLEAPIS_CDN } /${ notesPath } ` , cdInfo ) ) ;
157+ const promise = B . resolve (
158+ retrieveAdditionalDriverInfo ( key , `${ GOOGLEAPIS_CDN } /${ notesPath } ` , cdInfo )
159+ ) ;
161160 promises . push ( promise ) ;
162161 chunk . push ( promise ) ;
163162 if ( chunk . length >= MAX_PARALLEL_DOWNLOADS ) {
164163 await B . any ( chunk ) ;
165164 }
166- _ . remove ( chunk , ( p ) => p . isFulfilled ( ) ) ;
165+ _ . remove ( chunk , ( p ) => ( p as B < void > ) . isFulfilled ( ) ) ;
167166 }
168167 await B . all ( promises ) ;
169168 log . info ( `The total count of entries in the mapping: ${ _ . size ( mapping ) } ` ) ;
170169 return mapping ;
171170}
172171
173172/**
174- * Downloads chromedriver release notes and puts them
175- * into the dictionary argument
173+ * Downloads chromedriver release notes and updates the driver info dictionary
176174 *
177- * The method call mutates by merging `AdditionalDriverDetails`
178- * @param {string } driverKey - Driver version plus archive name
179- * @param {string } notesUrl - The URL of chromedriver notes
180- * @param {ChromedriverDetails } infoDict - The dictionary containing driver info.
181- * @param {number } timeout
182- * @throws {Error } if the release notes cannot be downloaded
175+ * Mutates `infoDict` by setting `minBrowserVersion` if found in notes
176+ * @param driverKey - Driver version plus archive name
177+ * @param notesUrl - The URL of chromedriver notes
178+ * @param infoDict - The dictionary containing driver info (will be mutated)
179+ * @param timeout - Request timeout in milliseconds
183180 */
184- async function retrieveAdditionalDriverInfo ( driverKey , notesUrl , infoDict , timeout = STORAGE_REQ_TIMEOUT_MS ) {
181+ async function retrieveAdditionalDriverInfo (
182+ driverKey : string ,
183+ notesUrl : string ,
184+ infoDict : ChromedriverDetails ,
185+ timeout = STORAGE_REQ_TIMEOUT_MS
186+ ) : Promise < void > {
185187 const notes = await retrieveData (
186188 notesUrl ,
187189 {
@@ -201,9 +203,8 @@ async function retrieveAdditionalDriverInfo(driverKey, notesUrl, infoDict, timeo
201203 infoDict . minBrowserVersion = minBrowserVersion ;
202204}
203205
204- /**
205- * @typedef {import('../types').SyncOptions } SyncOptions
206- * @typedef {import('../types').OSInfo } OSInfo
207- * @typedef {import('../types').ChromedriverDetails } ChromedriverDetails
208- * @typedef {import('../types').ChromedriverDetailsMapping } ChromedriverDetailsMapping
209- */
206+ function extractNodeText ( node : Node | null | undefined ) : string | null {
207+ return ! node ?. firstChild || ! util . hasValue ( node . firstChild . nodeValue )
208+ ? null
209+ : node . firstChild . nodeValue ;
210+ }
0 commit comments