103 lines
2.8 KiB
JavaScript
103 lines
2.8 KiB
JavaScript
const fs = require('fs')
|
|
const readline = require('readline')
|
|
|
|
const paramParser = (line) => {
|
|
switch (true) {
|
|
case line === 'true': return true
|
|
case line === 'false': return false
|
|
case line === 'null': return null
|
|
case /^[0-9-]+\.?[0-9]*$/.test(line): return Number(line)
|
|
case /;/.test(line):
|
|
line = line.split(';')
|
|
line.pop()
|
|
return line.map(l => paramParser(l))
|
|
default: return line
|
|
}
|
|
}
|
|
|
|
const paramReducer = (acc, cur, idx, src) => {
|
|
if (/^_/.test(cur)) return acc
|
|
switch (typeof src[cur]) {
|
|
case 'object':
|
|
if (Array.isArray(src[cur])) acc += `${cur}=${src[cur].join(';')};\n`
|
|
else {
|
|
acc += `\n[${cur}]\n`
|
|
acc += Object.keys(src[cur]).reduce((acc0, cur0, idx0) => paramReducer(acc0, cur0, idx0, src[cur]), '')
|
|
}
|
|
break
|
|
default:
|
|
acc = `${cur}=${String(src[cur])}\n` + acc
|
|
}
|
|
return acc
|
|
}
|
|
|
|
class PP3 {
|
|
static load (file) {
|
|
return new Promise((resolve, reject) => {
|
|
if (!file) return reject(new Error('Filename is mandatory.'))
|
|
if (!fs.existsSync(file)) return reject(new Error(`${file} didn't exists.`))
|
|
if (!/\.pp3$/i.test(file)) return reject(new Error('Filename have a bad extension.'))
|
|
const rl = readline.createInterface({
|
|
input: fs.createReadStream(file),
|
|
output: process.stdout,
|
|
terminal: false
|
|
})
|
|
let rub
|
|
const tree = {}
|
|
rl.on('line', (line) => {
|
|
const isRub = /^\[(.+)\]$/.exec(line)
|
|
if (isRub) {
|
|
rub = isRub[1]
|
|
tree[rub] = {}
|
|
}
|
|
const isParam = /^(.+)=(.+)$/.exec(line)
|
|
if (isParam) {
|
|
const p = paramParser(isParam[2].trim())
|
|
if (rub) tree[rub][isParam[1].trim()] = p
|
|
else tree[isParam[1].trim()] = p
|
|
}
|
|
})
|
|
rl.on('close', () => {
|
|
const out = new PP3(tree)
|
|
out._pp3 = {
|
|
source: {
|
|
url: file,
|
|
date: new Date()
|
|
}
|
|
}
|
|
resolve(out)
|
|
})
|
|
})
|
|
}
|
|
|
|
constructor (tree) {
|
|
if (tree) {
|
|
Object.keys(tree).forEach(k => {
|
|
this[k] = tree[k]
|
|
})
|
|
}
|
|
}
|
|
|
|
toString () {
|
|
return Object.keys(this).reduce((acc, cur, idx) => paramReducer(acc, cur, idx, this), '')
|
|
}
|
|
|
|
save (file) {
|
|
return new Promise((resolve, reject) => {
|
|
if (!file && (!this._pp3 || this._pp3.source || this._pp3.source.url)) return reject(new Error('You need to specify an output destination.'))
|
|
if (!file) file = this._pp3.source.url
|
|
const out = this.toString()
|
|
fs.writeFileSync(file, out, 'utf8')
|
|
if (!this._pp3) this._pp3 = {}
|
|
if (!this._pp3.saved) this._pp3.saved = []
|
|
this._pp3.saved.push({
|
|
url: file,
|
|
date: new Date()
|
|
})
|
|
resolve(out)
|
|
})
|
|
}
|
|
}
|
|
|
|
module.exports = PP3
|