| 177 | url: serverUrl, |
| 178 | }); |
| 179 | const readdir = () => |
| 180 | this.loadData({ |
| 181 | method: 'PROPFIND', |
| 182 | url: serverUrl, |
| 183 | headers: { |
| 184 | depth: '1', |
| 185 | }, |
| 186 | }).then((xml) => { |
| 187 | const doc = XNode.fromXML(xml); |
| 188 | const items = doc |
| 189 | .children()[0] |
| 190 | .map((node) => { |
| 191 | const prop = node.find('DAV:propstat').find('DAV:prop'); |
| 192 | const type = prop.find('DAV:resourcetype').find('DAV:collection') |
| 193 | ? 'directory' |
| 194 | : 'file'; |
| 195 | if (type === 'file') { |
| 196 | const displayNameNode = prop.find('DAV:displayname'); |
| 197 | const displayName = decodeURIComponent( |
| 198 | displayNameNode |
| 199 | ? displayNameNode.text() // some servers also encode DAV:displayname |
| 200 | : node.find('DAV:href').text().split('/').pop(), // extracting file name |
| 201 | ); |
| 202 | if (isScriptFile(displayName)) { |
| 203 | const size = prop.find('DAV:getcontentlength'); |
| 204 | return normalize({ |
| 205 | name: displayName, |
| 206 | size: size ? +size.text() : 0, |
| 207 | }); |
| 208 | } |
| 209 | } |
| 210 | return null; |
| 211 | }) |
| 212 | .filter(Boolean); |
| 213 | return items; |
| 214 | }); |
| 215 | return readdir().catch((err) => { |
| 216 | if (err.status === 404) { |
| 217 | return mkdir().then(readdir); |