-
Notifications
You must be signed in to change notification settings - Fork 102
Expand file tree
/
Copy pathparseList.ts
More file actions
59 lines (52 loc) · 1.94 KB
/
Copy pathparseList.ts
File metadata and controls
59 lines (52 loc) · 1.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import { FileInfo } from "./FileInfo"
import * as dosParser from "./parseListDOS"
import * as unixParser from "./parseListUnix"
import * as mlsdParser from "./parseListMLSD"
import * as eplParser from "./parseListEPLF"
interface Parser {
testLine(line: string): boolean
parseLine(line: string): FileInfo | undefined
transformList(files: FileInfo[]): FileInfo[]
}
/**
* Available directory listing parsers. These are candidates that will be tested
* in the order presented. The first candidate will be used to parse the whole list.
*/
const availableParsers: Parser[] = [
dosParser,
unixParser,
eplParser,
mlsdParser // Keep MLSD last, may accept filename only
]
function firstCompatibleParser(line: string, parsers: Parser[]) {
return parsers.find(parser => parser.testLine(line) === true)
}
function isNotBlank(str: string) {
return str.trim() !== ""
}
function isNotMeta(str: string) {
return !str.startsWith("total")
}
const REGEX_NEWLINE = /\r?\n/
/**
* Parse raw directory listing.
*/
export function parseList(rawList: string): FileInfo[] {
const lines = rawList
.split(REGEX_NEWLINE)
.filter(isNotBlank)
.filter(isNotMeta)
if (lines.length === 0) {
return []
}
const testLine = lines[lines.length - 1]
const parser = firstCompatibleParser(testLine, availableParsers)
if (!parser) {
console.debug("DEBUG:", { testLine: testLine, availableParsers: availableParsers } )
throw new Error("This library only supports MLSD, Unix-, DOS-, or EPLF-style directory listing. Your FTP server seems to be using another format. You can see the transmitted listing when setting `client.ftp.verbose = true`. You can then provide a custom parser to `client.parseList`, see the documentation for details.")
}
const files = lines
.map(parser.parseLine)
.filter((info): info is FileInfo => info !== undefined)
return parser.transformList(files)
}