-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconfig.ts
98 lines (87 loc) · 3.62 KB
/
config.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
import * as path from 'https://deno.land/[email protected]/path/mod.ts';
import { safeParse } from "./utils.ts";
const { configFilePath, appFolder } = (() => {
const dataFolder = Deno.env.get("HOME")?.concat("/.config") || path.normalize(Deno.env.get("LOCALAPPDATA")!);
const appFolder = path.join(dataFolder, "reddwp");
const configFilePath = path.join(appFolder, "config.json");
return { configFilePath, appFolder };
})();
type stringMapping = { [variable: string]: unknown };
export const fileExists = (path: string) => {
try {
Deno.statSync(path);
return true;
}
catch (e) {
if (e.name != "NotFound") throw e;
return false;
}
}
if (!fileExists(appFolder))
// Appdata folder generation
await Deno.mkdir(appFolder, { recursive: true });
const defaults: { [p: string]: unknown } = {
targetFolder: path.join(appFolder, "Downloads"),
sources: ["r/wallpapers"],
interval: 20,
filterNsfw: true,
maxFolderSize: 500,
minimumSize: 0.1,
};
if (!fileExists(path.join(appFolder, "config.json"))) {
// Write defaults as config.json
await Deno.writeFile(path.join(appFolder, "config.json"), new TextEncoder().encode(
// Convert object to pretty string
JSON.stringify(defaults, null, 2)
));
}
const configFileVars: stringMapping = await (async () => {
const configFilePath = path.join(appFolder, "config.json");
const configFileString = new TextDecoder().decode(await Deno.readFile(configFilePath));
return JSON.parse(configFileString);
})();
interface appConfig {
readonly configFilePath: string;
readonly appFolder: string;
targetFolder: string;
interval /* Hours */: number;
sources: string[];
filterNsfw?: true;
maxFolderSize? /* Megabytes */: number;
minimumSize? /* Megabytes */: number;
}
const optionals: { [p: string]: unknown } = { minimumSize: 0, maxFolderSize: 0, filterNsfw: true };
const config = new Proxy<appConfig>({ configFilePath, appFolder } as unknown as appConfig, {
// Either read from environment, or from config
get(target, variable: string) {
return Deno.env.get(variable) ?
safeParse(Deno.env.get(variable)!) || Deno.env.get(variable)
:
(target as any)[variable] || configFileVars[variable];
},
// Always write to config
set(_, variable: string, value: unknown) {
// readonlies
if (variable == "configFilePath" || variable == "appFolder") throw new TypeError(
`${variable} is read-only and can only be different based on environment variables.`);
// Write new config to file
// Indicate that a write to a nonexistent attribute failed
if (!Object.keys(defaults).includes(variable))
throw new RangeError(`Attribute ${variable} isn't valid for the config.`);
// Indicate that a write with the wrong type failed
// Allow undefined for optional configs
if (typeof value == "undefined" && !Object.keys(optionals).includes(variable)) {
throw new TypeError(`Attribute "${variable}" is required.`);
}
else if (typeof configFileVars[variable] != typeof value && typeof optionals[variable] != typeof value)
throw new TypeError(`Wrong type for attribute ${variable}. Please provide a value of type ${typeof configFileVars[variable]}.`);
// Write to the object
configFileVars[variable] = value;
// Write to the config JSON
Deno.writeFileSync(configFilePath, new TextEncoder().encode(
JSON.stringify({ ...configFileVars }, null, 2)
));
return true;
}
});
export default config;