-
Notifications
You must be signed in to change notification settings - Fork 0
/
reader.ts
127 lines (107 loc) · 4.14 KB
/
reader.ts
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
import { Constants } from ".";
/***
* @module Reader
*/
export module Reader {
/***
* Documentation directory, getter
*
* @param directory {@type string}
* @constructor
* @private
*/
async function Documentation (directory: string) {
return (await import("path")).relative(process.cwd(), directory);
}
/***
* A transformer function that mutates {@link FS.readdirSync} iterables into a {@link Descriptor} array data-structure.
*
* @param location
* @param file
* @param destination
*
* @return {@type Array<Descriptor>}
*/
async function schema(location: string, file?: (import("fs").Stats | import("fs").Dirent) & { name?: string }, destination?: string): Promise<Reader.Descriptor> {
const Path = await import("path");
const canonical = (location || file) ? Path.resolve(location!, file!.name!) : Path.resolve(location!);
const parent = Path.dirname(canonical);
return {
name: Path.basename(canonical),
path: Path.relative(process.cwd(), canonical),
parent: Path.relative(process.cwd(), parent),
descriptor: await Documentation(canonical),
properties: {
file: file?.isFile() ?? false,
directory: file?.isDirectory() ?? false,
socket: file?.isSocket() ?? false,
symbolic: file?.isSymbolicLink() ?? false
}
} as Descriptor;
}
/***
* An internal function that calls itself recursively, passing in a stateful array of file-descriptors.
*
* @see {@link Reader} for the interface.
*
* @param source
* @param collection
* @param debug
*/
async function parse (source: string = Constants.Source, collection?: Descriptor[], debug?: boolean): Promise<Reader.Descriptors> {
const FS = await import("fs");
const Path = await import("path");
const reference = (collection) ? collection : [];
const descriptors = FS.readdirSync(source, {withFileTypes: true});
for (const descriptor of descriptors) {
const Directory = descriptor?.isDirectory() || false;
const Link = descriptor?.isSymbolicLink() || false;
const Socket = descriptor?.isSocket() || false;
const File = descriptor?.isFile() || false;
(Directory) && (debug) && console.log("[Debug] [Read] Directory", descriptor.name);
(Directory) && reference.push(await schema(source, descriptor));
(Directory) && await parse(Path.join(source, descriptor.name), reference);
(Socket) && (debug) && console.log("[Debug] [Read] Socket", descriptor.name);
(Socket) && reference.push(await schema(source, descriptor));
(Link) && (debug) && console.log("[Debug] [Read] Symbolic Link", descriptor.name);
(Link) && reference.push(await schema(source, descriptor));
(File) && (debug) && console.log("[Debug] [Read] File", descriptor.name);
(File) && reference.push(await schema(source, descriptor));
}
return reference;
}
/***
* File Reader Function
*
* @param path
*/
export async function read (path: string): Promise<string> {
const FS = await import("fs/promises");
return FS.readFile(path, {encoding: "utf-8"});
}
/***
* A recursive system directory reader function that will iterate over file-descriptors and return a {@link Descriptor}
* array data-structure.
*
* @param directory
*
* @constructor
*/
export async function scan(directory: string): Promise<Reader.Descriptors> {
return parse(directory);
}
export type Property = {
readonly file: boolean,
readonly directory: boolean,
readonly socket: boolean,
readonly symbolic: boolean
};
export type Descriptor = {
readonly name: string,
readonly path: string,
readonly parent: string,
readonly descriptor: string,
readonly properties: Property
};
export type Descriptors = Reader.Descriptor[];
}