-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathfs.js
118 lines (105 loc) · 3.5 KB
/
fs.js
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
'use strict'
const fs = require('fs')
const { join, relative } = require('path')
const { Readable } = require('stream')
const glob = require('glob')
const loadJSON = require('load-json-file')
const writeJSON = require('write-json-file')
module.exports = createDatabase
const objectPathRegexp = /^\/((?:[^/]+?))\/((?:[^/]+?))\/((?:[^/]+?))(?:\/(?=$))?$/i
const pagePathRegexp = /^\/((?:[^/]+?))(?:\/((?:[^/]+?)))?(?:\/(?=$))?$/i
function createDatabase ({ prefix = 'data' }) {
const load = path => loadJSON(path).catch(() => null)
const save = (path, data) => writeJSON(path, data, { indent: 2 })
return {
getGlobals ({ language }) {
language = language || 'not_localized'
return load(join(prefix, language + '.json'))
},
getPage ({ language, name }) {
language = language || 'not_localized'
return load(join(prefix, language, name) + '.json')
},
getObject ({ language, type, id }) {
language = language || 'not_localized'
return load(join(prefix, language, type, id) + '.json')
},
saveGlobals (data, { language }) {
language = language || 'not_localized'
return save(join(prefix, language + '.json'), data)
},
savePage (data, { language, name }) {
language = language || 'not_localized'
return save(join(prefix, language, name) + '.json', data)
},
saveObject (data, { language, type, id }) {
language = language || 'not_localized'
return save(join(prefix, language, type, id) + '.json', data)
},
destroyObject ({ type, id }) {
return Promise.all(
glob.sync(join(prefix, '*', type, id + '.json'))
.map(p =>
new Promise((resolve, reject) => {
fs.unlink(p, err => err ? reject(err) : resolve())
})
)
)
},
getPages ({ language = '*' }) {
const s = language === null ? 'not_localized' : language
const pattern = join(prefix, s, '*.json')
return createReadStream(pattern, {
transform (o) {
const match = o.key.match(pagePathRegexp)
return Object.assign({}, o, {
language: match[1],
page: { name: match[2] }
})
}
})
},
getObjects ({ language = '*', type = '*' }) {
const s = language === null ? 'not_localized' : language
const pattern = join(prefix, s, type, '*.json')
return createReadStream(pattern, {
transform (o) {
const match = o.key.match(objectPathRegexp)
return Object.assign({}, o, {
language: match[1],
object: { type: match[2], id: match[3] }
})
}
})
}
}
function createReadStream (pattern, { transform = f => f }) {
let i = 0
let eof = false
const files = glob.sync(pattern).filter(file => {
return !(relative(prefix, file).startsWith('not_localized/'))
})
return new Readable({
objectMode: true,
read (n) {
const ps = []
for (let j = 0; j < n && i < files.length; ++i, ++j) {
const file = files[i]
const p =
loadJSON(file)
.then(o => {
this.push(transform({
key: '/' + relative(prefix, file).replace(/\.json$/, ''),
value: o
}))
})
.catch(err => this.emit('error', err))
ps.push(p)
}
if (eof) return
eof = i === files.length
Promise.all(ps).then(() => { if (eof) this.push(null) })
}
})
}
}