Skip to content

Commit

Permalink
feat: getDir can parse different types of files in a dir
Browse files Browse the repository at this point in the history
- feat: all file readers now have load and loadPromise, so that
  a feature like getDir can safely use the nicer promise API
- chore: require syntax, prefix node builtins with `node:`
- es6
  - add several uses of `...` (spread operator / param collection)
  - replace `for i` with `for ... of`
  - consolidate all cases of type detection into configfile.getType
  - replace `new Promise` with async/await
  - use shortened array function syntax
  • Loading branch information
msimerson committed Apr 15, 2024
1 parent f575840 commit 6591af8
Show file tree
Hide file tree
Showing 17 changed files with 255 additions and 225 deletions.
3 changes: 0 additions & 3 deletions .eslintrc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,3 @@ env:
es2022: true

extends: ['@haraka']

rules:
no-extra-semi: 1
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@

### [1.2.0] - 2024-04-14

- feat: getDir can parse different types of files in a dir
- feat: all file readers now have load and loadPromise, so that
a feature like getDir can safely use the nicer promise API
- chore: require syntax, prefix node builtins with `node:`
- es6
- add several uses of `...` (spread operator / param collection)
- replace `for i` with `for ... of`
- consolidate all cases of type detection into configfile.getType
- replace `new Promise` with async/await
- use shortened array function syntax
- ci: update to shared haraka/.github
- dep: eslint-plugin-haraka -> @haraka/eslint-config
- lint: remove duplicate / stale rules from .eslintrc
Expand Down
63 changes: 23 additions & 40 deletions config.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,23 @@ class Config {
}
}

get(name, type, cb, options) {
const a = this.arrange_args([name, type, cb, options])
if (!a[1]) a[1] = 'value'
get(...args) {
/* eslint prefer-const: 0 */
let [name, type, cb, options] = this.arrange_args(args)
if (!type) type = 'value'

const full_path = path.isAbsolute(name)
? name
: path.resolve(this.root_path, a[0])
: path.resolve(this.root_path, name)

let results = cfreader.read_config(full_path, a[1], a[2], a[3])
let results = cfreader.read_config(full_path, type, cb, options)

if (this.overrides_path) {
const overrides_path = path.resolve(this.overrides_path, a[0])
const overrides_path = path.resolve(this.overrides_path, name)

const overrides = cfreader.read_config(overrides_path, a[1], a[2], a[3])
const overrides = cfreader.read_config(overrides_path, type, cb, options)

results = merge_config(results, overrides, a[1])
results = merge_config(results, overrides, type)
}

// Pass arrays by value to prevent config being modified accidentally.
Expand Down Expand Up @@ -77,45 +78,27 @@ class Config {
let cb
let options

for (let i = 0; i < args.length; i++) {
if (args[i] === undefined) continue
switch (
typeof args[i] // what is it?
) {
for (const arg of args) {
if ([undefined, null].includes(arg)) continue
switch (typeof arg) {
case 'function':
cb = args[i]
break
cb = arg
continue
case 'object':
options = args[i]
break
options = arg
continue
case 'string':
if (/^(ini|value|list|data|h?json|js|yaml|binary)$/.test(args[i])) {
fs_type = args[i]
break
if (/^(ini|value|list|data|h?json|js|yaml|binary)$/.test(arg)) {
fs_type = arg
continue
}
console.log(`unknown string: ${args[i]}`)
break
console.log(`unknown string: ${arg}`)
continue
}
// console.log(`unknown arg: ${args[i]}, typeof: ${typeof args[i]}`);
// console.log(`unknown arg: ${arg}, typeof: ${typeof arg}`);
}

if (!fs_type) {
const fs_ext = path.extname(fs_name).substring(1)

switch (fs_ext) {
case 'hjson':
case 'json':
case 'yaml':
case 'js':
case 'ini':
fs_type = fs_ext
break

default:
fs_type = 'value'
break
}
}
if (!fs_type) fs_type = cfreader.getType(fs_name)

return [fs_name, fs_type, cb, options]
}
Expand Down
77 changes: 39 additions & 38 deletions configfile.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
'use strict'

const fs = require('fs')
const path = require('path')
const fs = require('node:fs')
const fsp = require('node:fs/promises')
const path = require('node:path')

let config_dir_candidates = [
// these work when this file is loaded as require('./config.js')
Expand Down Expand Up @@ -71,6 +72,28 @@ class cfreader {
}
}

getType(fileName) {
const ext = path.extname(fileName).substring(1).toLowerCase()
switch (ext) {
case 'hjson':
case 'json':
case 'yaml':
case 'js':
case 'ini':
case 'list':
case 'data':
return ext
case 'yml':
return 'yaml'
case 'pem':
case 'bin':
case 'binary':
return 'binary'
default:
return 'value'
}
}

on_watch_event(name, type, options, cb) {
return (fse) => {
if (this._sedation_timers[name]) {
Expand Down Expand Up @@ -220,27 +243,25 @@ class cfreader {
return result
}

read_dir(name, opts) {
read_dir(name, opts = {}) {
return new Promise((resolve, reject) => {
this._read_args[name] = { opts }
const type = opts.type || 'binary'

isDirectory(name)
.then(() => {
return fsReadDir(name)
})
.then((fileList) => {
const reader = require(path.resolve(__dirname, 'readers', type))
const promises = []
fsp
.stat(name)
.then((stat) => stat.isDirectory())
.then(() => fsp.readdir(name))
.then(async (fileList) => {
const contents = []
for (const file of fileList) {
promises.push(reader.loadPromise(path.resolve(name, file)))
const type = opts.type ?? this.getType(file)
contents.push(
this.load_config(path.resolve(name, file), type, opts),
)
}
return Promise.all(promises)
})
.then((fileList) => {
// console.log(fileList);
resolve(fileList)
return contents
})
.then(resolve)
.catch(reject)

if (opts.watchCb) this.fsWatchDir(name)
Expand Down Expand Up @@ -283,9 +304,7 @@ class cfreader {
load_config(name, type, options) {
let result

if (!type) {
type = path.extname(name).toLowerCase().substring(1)
}
if (!type) type = this.getType(name)

let cfrType = this.get_filetype_reader(type)

Expand Down Expand Up @@ -380,21 +399,3 @@ class cfreader {
}

module.exports = new cfreader()

function isDirectory(filepath) {
return new Promise((resolve, reject) => {
fs.stat(filepath, (err, stat) => {
if (err) return reject(err)
resolve(stat.isDirectory())
})
})
}

function fsReadDir(filepath) {
return new Promise((resolve, reject) => {
fs.readdir(filepath, (err, fileList) => {
if (err) return reject(err)
resolve(fileList)
})
})
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"hjson": "^3.2.2"
},
"devDependencies": {
"@haraka/eslint-config": "^1.1.1"
"@haraka/eslint-config": "^1.1.3"
},
"bugs": {
"mail": "[email protected]",
Expand Down
16 changes: 6 additions & 10 deletions readers/binary.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
'use strict'

const fs = require('fs')

exports.load = (name) => {
return fs.readFileSync(name)
return require('node:fs').readFileSync(name)
}

exports.loadPromise = (name) => {
return new Promise((resolve, reject) => {
fs.readFile(name, (err, content) => {
if (err) return reject(err)
resolve({ path: name, data: content })
})
})
exports.loadPromise = async (name) => {
return {
path: name,
data: await require('node:fs/promises').readFile(name),
}
}

exports.empty = () => {
Expand Down
30 changes: 20 additions & 10 deletions readers/flat.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
'use strict'

const fs = require('fs')
exports.load = (...args) => {
return this.parseValue(
...args,
require('node:fs').readFileSync(args[0], 'UTF-8'),
)
}

exports.loadPromise = async (...args) => {
return this.parseValue(
...args,
await require('node:fs/promises').readFile(args[0], 'UTF-8'),
)
}

exports.load = (name, type, options, regex) => {
exports.parseValue = (name, type, options, regex, data) => {
let result = []

let data = fs.readFileSync(name, 'UTF-8')
if (type === 'data') {
while (data.length > 0) {
const match = data.match(/^([^\r\n]*)\r?\n?/)
Expand All @@ -15,15 +26,15 @@ exports.load = (name, type, options, regex) => {
return result
}

data.split(/\r\n|\r|\n/).forEach((line) => {
if (regex.comment.test(line)) return
if (regex.blank.test(line)) return
for (const line of data.split(/\r\n|\r|\n/)) {
if (regex.comment.test(line)) continue
if (regex.blank.test(line)) continue

const line_data = regex.line.exec(line)
if (!line_data) return
if (!line_data) continue

result.push(line_data[1].trim())
})
}

if (result.length && type !== 'list' && type !== 'data') {
result = result[0]
Expand Down Expand Up @@ -63,7 +74,6 @@ exports.empty = (options, type) => {
}

function in_array(item, array) {
if (!array) return false
if (!Array.isArray(array)) return false
return array.indexOf(item) !== -1
return array.includes(item)
}
7 changes: 5 additions & 2 deletions readers/hjson.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
'use strict'

const fs = require('fs')
const hjson = require('hjson')

exports.load = (name) => {
return hjson.parse(fs.readFileSync(name, 'utf8'))
return hjson.parse(require('node:fs').readFileSync(name, 'UTF-8'))
}

exports.loadPromise = async (name) => {
return hjson.parse(await require('node:fs/promises').readFile(name, 'UTF-8'))
}

exports.empty = () => {
Expand Down
Loading

0 comments on commit 6591af8

Please sign in to comment.