-
Notifications
You must be signed in to change notification settings - Fork 2
/
js_lib.nim
73 lines (53 loc) · 2.39 KB
/
js_lib.nim
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
import jsffi, async, strutils, sequtils, strformat, macros, json
type
JSONLib = ref object
stringify: proc(c: js): cstring
parse: proc(c: cstring): js
WriteDirEffect = object of WriteIOEffect
ReadDirEffect = object of ReadIOEffect
FS* = ref object
readFileSync*: proc(path: cstring, options: js): cstring
writeFileSync*: proc(path: cstring, raw: cstring, options: js)
mkdirSync*: proc(path: cstring) {.tags: [WriteDirEffect].}
readdirSync*: proc(path: cstring): seq[cstring] {.tags: [ReadDirEffect].}
existsSync*: proc(path: cstring): bool {.tags: [ReadIOEffect].}
Process = ref object
argv*: seq[cstring]
Path = ref object
join*: proc: cstring {.varargs.}
PathComponent* = enum ## Enumeration specifying a path component.
pcFile, ## path refers to a file
pcLinkToFile, ## path refers to a symbolic link to a file
pcDir, ## path refers to a directory
pcLinkToDir ## path refers to a symbolic link to a directory
var require {.importc.}: proc(lib: cstring): js
var JSON {.importc.}: JSONLib
var fs* = cast[FS](require("fs"))
var process {.importc.}: Process
var path = cast[Path](require("path"))
proc `$`*(a: SomeUnsignedInt): string =
$(a.int)
proc `$$`*[T](e: T): string =
$JSON.stringify(cast[js](e))
proc to*[T](e: string): T =
cast[T](JSON.parse(cstring(e)))
proc readFile*(path: string): string =
$fs.readFileSync(cstring(path), js{encoding: cstring"utf8"})
proc writeFile*(path: string, raw: string) =
fs.writeFileSync(cstring(path), cstring(raw), js{encoding: cstring"utf8"})
proc createDir*(dir: string) {.tags: [WriteDirEffect, ReadDirEffect, ReadIOEffect].} =
if not fs.existsSync(cstring(dir)):
fs.mkdirSync(cstring(dir))
proc paramCount*: int {.tags: [ReadIOEffect].} =
process.argv.len - 2
proc paramStr*(i: int): TaintedString {.tags: [ReadIOEffect].} =
$process.argv[i + 1]
iterator walkDir*(path: string, relative: bool = false): tuple[kind: PathComponent, path: string] {.tags: [ReadDirEffect].} =
let filenames = fs.readdirSync(cstring(path)).mapIt($it)
for filename in filenames:
let path = if relative: filename else: path & filename
# TODO kind relative
yield (kind: pcFile, path: path)
proc `/`*(left: string, right: string): string =
$(path.join(cstring(left), cstring(right)))
template `$`*(o: JsObject): cstring = cast[cstring](o.toString())