-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathLocal.ts
More file actions
128 lines (108 loc) · 3.73 KB
/
Copy pathLocal.ts
File metadata and controls
128 lines (108 loc) · 3.73 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
import { homedir, platform } from 'node:os'
import { normalize, basename, dirname, join, isAbsolute } from 'node:path/posix'
import osPath from 'node:path'
import { readdirSync, statSync, lstatSync, readlinkSync, watch as fsWatch, WatchEventType } from 'node:fs';
import { mkdir, unlink, rename, cp, open, rm, readFile, writeFile, watch as asyncWatch } from 'node:fs/promises'
import { winToUnix, unixToWin } from './utils/os'
import { LocalFileItem, LocalFiles } from './FileSystem'
import { getDrives } from './win'
export function isWin() {
return platform() === 'win32'
}
export function osify(path: string): string {
return isWin() ? unixToWin(path) : path
}
export function unosify(path: string): string {
return isWin() ? winToUnix(path) : path
}
export function pwd(): string {
return unosify(homedir())
}
export function stat(path: string): LocalFileItem|null {
path = normalize(path)
const actualPath = osify(path)
try {
let stat = lstatSync(actualPath)
let target = ''
if (stat.isSymbolicLink()) {
target = readlinkSync(actualPath)
if (!isAbsolute(target)) {
target = osPath.normalize(osPath.join(osPath.dirname(actualPath), target))
}
stat = statSync(target)
}
return {
path,
name: basename(path),
dir: stat.isDirectory(),
size: stat.size, // in bytes
modified: stat.mtime,
inode: stat.ino,
...(target ? { target } : {})
}
} catch (e) {
return null
}
}
export function list(dir: string): LocalFiles {
let actialDir = osify(dir)
if (actialDir == '\\') {
return getDrives().map(path => stat(unosify(path))).filter(f => f != null)
}
return readdirSync(actialDir).map(name => stat(join(dir, name))).filter(f => f != null)
}
export async function mkDirRecursive(path: string) {
return mkdir(osify(path), { recursive: true })
}
export async function move(from: string, to: string, force = false): Promise<true|LocalFileItem> {
await mkDirRecursive(dirname(to))
const existing = stat(to)
if (existing) {
if (force) {
await unlink(osify(to))
} else {
return existing
}
}
await rename(osify(from), osify(to))
return true
}
export async function copy(from: string, to: string, force = false): Promise<true|LocalFileItem> {
await mkDirRecursive(dirname(to))
const existing = stat(to)
if (existing && !force) {
return existing
}
await cp(osify(from), osify(to), { recursive: true })
return true
}
export async function del(path: string): Promise<void> {
return rm(osify(path), { recursive: true, force: true })
}
export async function touch(path: string, data?: string): Promise<void> {
if (!stat(path)) {
await mkDirRecursive(dirname(path))
data !== undefined ? await writeFile(osify(path), data) : await (await open(osify(path), 'a')).close()
}
}
export async function read(path: string): Promise<string> {
return readFile(osify(path), { encoding: 'utf8' })
}
export async function readInBuffer(path: string): Promise<Buffer> {
return readFile(osify(path))
}
export async function write(path: string, data: string): Promise<void> {
return writeFile(osify(path), data)
}
export function watch(
path: string,
listener: (event: WatchEventType, file: string|null) => void,
onError: (e: Error) => void
): () => void {
const watcher = fsWatch(osify(path), null, listener)
watcher.on('error', onError)
return () => watcher.close()
}
export function watchChanges(path: string, ac: AbortController) {
return asyncWatch(osify(path), { signal: ac.signal })
}