-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathio_deno.mjs
More file actions
188 lines (153 loc) · 5.27 KB
/
Copy pathio_deno.mjs
File metadata and controls
188 lines (153 loc) · 5.27 KB
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
/*
Compare `./io_bun.mjs`. The two modules should have the same interface.
For consumer code, the pseudo-module `./io` should automatically resolve
to the engine-specific implementation via `package.json`.`exports`.
*/
/* global Deno */
import * as l from './lang.mjs'
import * as pt from './path.mjs'
export const ENV = globalThis.process.env
export function cwd() {return Deno.cwd()}
export function exit(...src) {return Deno.exit(...src)}
export function isErrNotFound(val) {return l.isInst(val, Deno.errors.NotFound)}
export function skipErrNotFound(val) {return l.errSkip(val, isErrNotFound)}
export function validPath(val) {
if (l.isKey(val)) return val
if (l.isInst(val, URL)) return val
return l.reqScalar(val).toString()
}
export function validPathOpt(val) {return l.opt(val, validPath)}
export function readFileText(path) {return Deno.readTextFile(validPath(path))}
export function readFileTextSync(path) {return Deno.readTextFileSync(validPath(path))}
export function readFileBytes(path) {return Deno.readFile(path)}
export function readFileBytesSync(path) {return Deno.readFileSync(path)}
export function readFileTextOpt(path) {
if (l.isNil(path)) return undefined
return readFileText(path).catch(skipErrNotFound)
}
export function readFileTextOptSync(path) {
if (l.isNil(path)) return undefined
try {return readFileTextSync(path)}
catch (err) {
if (isErrNotFound(err)) return undefined
throw err
}
}
export function writeFile(path, body, opt) {
path = validPath(path)
l.optRec(opt)
if (l.isNil(body)) return Deno.create(path)
if (l.isStr(body)) return Deno.writeTextFile(path, body, opt)
if (l.isInst(body, Uint8Array)) return Deno.writeFile(path, body, opt)
if (l.isInst(body, ReadableStream)) return Deno.writeFile(path, body, opt)
throw TypeError(`unable to write ${l.show(path)}: file body must be [string | Uint8Array | ReadableStream], got ${l.show(body)}`)
}
export function writeFileSync(path, body, opt) {
validPath(path)
l.optRec(opt)
if (l.isNil(body)) return Deno.createSync(path)
if (l.isStr(body)) return Deno.writeTextFileSync(path, body, opt)
if (l.isInst(body, Uint8Array)) return Deno.writeFileSync(path, body, opt)
throw TypeError(`unable to write ${l.show(path)}: file body must be [string | Uint8Array], got ${l.show(body)}`)
}
export function remove(path, opt) {return Deno.remove(path, opt)}
export function removeSync(path, opt) {return Deno.removeSync(path, opt)}
export async function exists(path) {return !!await statOpt(path)}
export function existsSync(path) {return !!statOptSync(path)}
export async function stat(path) {
return statNorm(await Deno.stat(validPath(path)))
}
export function statSync(path) {
return statNorm(Deno.statSync(validPath(path)))
}
export function statOpt(path) {
if (l.isNil(path) || path === ``) return undefined
return stat(path).catch(skipErrNotFound)
}
export function statOptSync(path) {
if (l.isNil(path) || path === ``) return undefined
try {return statSync(path)}
catch (err) {
if (isErrNotFound(err)) return undefined
throw err
}
}
export function statNorm(src) {
if (!l.optRec(src)) return undefined
return {
__proto__: null,
isDir: src.isDirectory,
isFile: src.isFile,
isSymlink: src.isSymlink,
isBlockDevice: src.isBlockDevice,
isCharDevice: src.isCharDevice,
isSocket: src.isSocket,
isFifo: src.isFifo,
size: src.size,
mtime: src.mtime?.valueOf(),
atime: src.atime?.valueOf(),
birthtime: src.birthtime?.valueOf(),
ctime: src.ctime?.valueOf(),
uid: src.uid,
gid: src.gid,
dev: src.dev,
ino: src.ino,
rdev: src.rdev,
mode: src.mode,
nlink: src.nlink,
blksize: src.blksize,
blocks: src.blocks,
}
}
// Caller must eventually call `.cancel` on the stream.
export async function fileReadStream(path) {
return (await Deno.open(path)).readable
}
// Caller must eventually call `.close` on the stream.
export async function fileWriteStream(path) {
return (await Deno.open(path)).writable
}
export function mkdir(path, opt) {
return Deno.mkdir(validPath(path), l.optRec(opt))
}
export function mkdirSync(path, opt) {
return Deno.mkdirSync(validPath(path), l.optRec(opt))
}
export function mkdirTemp(opt) {return Deno.makeTempDir(l.optRec(opt))}
export function mkdirTempSync(opt) {return Deno.makeTempDirSync(l.optRec(opt))}
export async function readDir(path) {
const out = []
for await (const val of Deno.readDir(validPath(path))) {
out.push(normInfo(val))
}
return out
}
export function readDirSync(path) {
const out = []
for (const val of Deno.readDirSync(validPath(path))) {
out.push(normInfo(val))
}
return out
}
export function rename(prev, next) {
return Deno.rename(validPath(prev), validPath(next))
}
export function renameSync(prev, next) {
return Deno.renameSync(validPath(prev), validPath(next))
}
export function watchCwd() {return watchRel(Deno.cwd())}
export async function* watchRel(base) {
l.req(base, pt.isAbs)
const iter = Deno.watchFs(base, {recursive: true})
for await (const {kind: type, paths} of iter) {
for (const path of paths) yield {type, path: pt.strictRelTo(path, base)}
}
}
/* Internal */
function normInfo(val) {
val.toString = getName
val.valueOf = getName
val.toJSON = getName
return val
}
function getName() {return this.name}