-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
executable file
·98 lines (84 loc) · 3.01 KB
/
index.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
import { tap, pickBy, zipObj, always, map, cond, andThen, pipe, mapObjIndexed, converge, applyTo, identity, equals, both} from "ramda"
import { getFile, getFormat } from "./src/getFile.js"
import parsers from "./src/parsers.js"
import { readdir } from "node:fs/promises"
import { lstatSync } from "node:fs"
import parsePath from "parse-path"
const loaders = mapObjIndexed
( (parser) => pipe(getFile, andThen(parser))
, parsers
)
const getLoader = (x) => loaders[getFormat(x)]
//
// A Parser takes content in one format, returns in another
//
export const parseYaml = parsers.yaml
export const parseJson = parsers.json
export const parseToml = parsers.toml
export const parseHtml = parsers.html
export const parseXml = parsers.xml
export const parseMd = parsers.md
export const parseCbor = parsers.cbor
export const parseDhall = parsers.dhall
//
// A Loader takes a URI, downloads it, parses it, returns it
//
export const loadYAML = loaders.yaml
export const loadJSON = loaders.json
export const loadTOML = loaders.toml
export const loadHTML =
(url, parser ) => parser
? pipe(getFile, andThen(parser))(url)
: pipe(getFile, andThen(parseHtml))(url)
export const loadXML = loaders.xml
export const loadMD = loaders.md
export const loadCBOR = loaders.cbor
export const loadDHALL = loaders.dhall
//export const load = converge(applyTo, [identity, getLoader])
const isFormat =
(format,options) => (url) => options.formats.includes(getFormat(url)) && equals(getFormat(url),format)
const isLocal =
(url) => ["file"].includes(parsePath(url).protocol)
const isDirectory =
(url) => lstatSync(url).isDirectory()
const loadDirectory =
/*
pipe
( readdir
, andThen( x => x.val )
, andThen(map(async p => await load(url + "/" + p)))
, andThen(tap(console.log))
, andThen(Promise.all)
, andThen(zipObj)
)
*/
(options) => async (url) => {
let paths = (await readdir(url))
let loadPath = async p => await load(url + "/" + p,options)
let vals = await Promise.all(map(loadPath,paths))
let obj = zipObj(paths,vals)
obj = pickBy( (val,key) => val !== undefined, obj )
return obj/// await readdir(url)
}
export const load =
(url, customOptions) => {
let defaultOptions =
{ formats: [ "html", "xml", "json", "toml", "yaml", "yml", "md", "dhall", "cbor" ]
, parsers: { html: "parse5", }
}
let options = { ...defaultOptions, ...customOptions }
return cond(
[ [ both(isLocal,isDirectory) , loadDirectory(options) ]
, [ isFormat("html", options) , loadHTML ]
, [ isFormat("xml", options) , loadXML ]
, [ isFormat("json", options) , loadJSON ]
, [ isFormat("toml", options) , loadTOML ]
, [ isFormat("yaml", options) , loadYAML ]
, [ isFormat("yml", options) , loadYAML ]
, [ isFormat("md", options) , loadMD ]
, [ isFormat("dhall", options) , loadDHALL ]
, [ isFormat("cbor", options) , loadCBOR ]
, [ always(true, options) , x => undefined ]
]
) (url)
}