| 109 | } |
| 110 | |
| 111 | function parseListXml(xml) { |
| 112 | const doc = new DOMParser().parseFromString(xml, 'application/xml'); |
| 113 | const ns = 'http://s3.amazonaws.com/doc/2006-03-01/'; |
| 114 | |
| 115 | // Some S3-compatible services omit the AWS namespace; fall back to no-namespace. |
| 116 | function elsByTag(parent, tag) { |
| 117 | const r = [...parent.getElementsByTagNameNS(ns, tag)]; |
| 118 | return r.length ? r : [...parent.getElementsByTagName(tag)]; |
| 119 | } |
| 120 | function elByTag(parent, tag) { |
| 121 | return parent.getElementsByTagNameNS(ns, tag)[0] |
| 122 | || parent.getElementsByTagName(tag)[0]; |
| 123 | } |
| 124 | |
| 125 | const items = elsByTag(doc, 'Contents').map((el) => { |
| 126 | const key = elByTag(el, 'Key')?.textContent || ''; |
| 127 | const name = key.split('/').pop(); |
| 128 | if (!isScriptFile(name)) return null; |
| 129 | const size = +(elByTag(el, 'Size')?.textContent || 0); |
| 130 | return normalize({ name, size }); |
| 131 | }).filter(Boolean); |
| 132 | |
| 133 | const nextToken = elByTag(doc, 'NextContinuationToken')?.textContent; |
| 134 | return { items, nextToken }; |
| 135 | } |
| 136 | |
| 137 | const S3 = BaseService.extend({ |
| 138 | name: 's3', |