-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathMetadataBuilder.js
More file actions
87 lines (66 loc) · 2.31 KB
/
MetadataBuilder.js
File metadata and controls
87 lines (66 loc) · 2.31 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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
const fs = require('fs')
const encodeURIComponent = require('strict-uri-encode')
class MetadataBuilder {
static readFirstLine (filename) {
const stream = fs.createReadStream(filename)
const chunks = []
return new Promise((resolve, reject) => {
const next = () => {
if (stream.closed) {
return reject(new Error('reached end of file before line break'))
}
const chunk = stream.read()
if (chunk === null) {
return setTimeout(next, 10)
}
chunks.push(chunk)
if (chunk.toString().indexOf('\n') !== -1) {
return resolve(Buffer.concat(chunks).toString().split('\n')[0])
}
setTimeout(next, 10)
}
next()
})
}
static detectDelimiter (line) {
const commaCount = line.split(',').length
const tabCount = line.split('\t').length
return commaCount > tabCount ? ',' : '\t'
}
static extractHeaders (line, delimiter) {
return line.split(delimiter).map(header => {
return header.split('"').join('').trim()
})
}
static build (baseIri, headers, { aboutUrl, delimiter = ',', propertyBaseIri = baseIri } = {}) {
const metadata = { '@context': 'http://www.w3.org/ns/csvw' }
if (delimiter !== ',') {
metadata.dialect = {
delimiter
}
}
aboutUrl = aboutUrl || `${baseIri}{${encodeURIComponent(headers[0])}}`
const columns = headers.map(header => {
return {
titles: header,
propertyUrl: `${propertyBaseIri}${encodeURIComponent(header)}`
}
})
metadata.tableSchema = {
aboutUrl,
columns
}
return metadata
}
static fromHeaderLine (firstLine, { aboutUrl, baseIri, delimiter, headers, propertyBaseIri } = {}) {
delimiter = delimiter || MetadataBuilder.detectDelimiter(firstLine)
headers = headers || MetadataBuilder.extractHeaders(firstLine, delimiter)
return MetadataBuilder.build(baseIri, headers, { delimiter, propertyBaseIri })
}
static fromFile (filename, { aboutUrl, baseIri = `file:///${filename}/`, delimiter, headers, propertyBaseIri } = {}) {
return MetadataBuilder.readFirstLine(filename).then(firstLine => {
return MetadataBuilder.fromHeaderLine(firstLine, { aboutUrl, baseIri, delimiter, headers, propertyBaseIri })
})
}
}
module.exports = MetadataBuilder