-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathsettings-store.ts
More file actions
102 lines (94 loc) · 2.87 KB
/
settings-store.ts
File metadata and controls
102 lines (94 loc) · 2.87 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
// @ts-nocheck
import fs from "node:fs";
import path from "node:path";
const SETTINGS_FILE_NAME = "settings.json";
const SETTINGS_VERSION = 1;
function normalizeValues(input) {
if (!input || typeof input !== "object" || Array.isArray(input)) return {};
const values = {};
for (const [key, value] of Object.entries(input)) {
if (typeof key !== "string") continue;
if (typeof value === "string") {
values[key] = value;
}
}
return values;
}
function readSettingsFile(filePath) {
try {
const raw = fs.readFileSync(filePath, "utf8");
const parsed = JSON.parse(raw);
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
if (parsed.values && typeof parsed.values === "object") {
return {
version: typeof parsed.version === "number" ? parsed.version : SETTINGS_VERSION,
values: normalizeValues(parsed.values),
};
}
// Backward-compatible fallback if file ever contained flat object.
return {
version: SETTINGS_VERSION,
values: normalizeValues(parsed),
};
}
} catch {
// Ignore missing or malformed file; start fresh.
}
return { version: SETTINGS_VERSION, values: {} };
}
function writeSettingsFile(filePath, payload) {
const dir = path.dirname(filePath);
fs.mkdirSync(dir, { recursive: true });
const tempPath = `${filePath}.tmp-${process.pid}-${Date.now()}`;
fs.writeFileSync(tempPath, `${JSON.stringify(payload, null, 2)}\n`, "utf8");
fs.renameSync(tempPath, filePath);
}
function createSettingsStore(baseDir) {
const filePath = path.join(baseDir, SETTINGS_FILE_NAME);
let state = readSettingsFile(filePath);
function flush() {
state = {
version: SETTINGS_VERSION,
values: normalizeValues(state.values),
};
writeSettingsFile(filePath, state);
}
return {
filePath,
getAll() {
return { ...state.values };
},
get(key) {
if (typeof key !== "string") return null;
return state.values[key] ?? null;
},
set(key, value) {
if (typeof key !== "string" || typeof value !== "string") return false;
state.values[key] = value;
flush();
return true;
},
remove(key) {
if (typeof key !== "string") return false;
if (!(key in state.values)) return true;
delete state.values[key];
flush();
return true;
},
merge(entries) {
if (!entries || typeof entries !== "object" || Array.isArray(entries)) {
return false;
}
let changed = false;
for (const [key, value] of Object.entries(entries)) {
if (typeof key !== "string" || typeof value !== "string") continue;
if (state.values[key] === value) continue;
state.values[key] = value;
changed = true;
}
if (changed) flush();
return true;
},
};
}
export { SETTINGS_FILE_NAME, SETTINGS_VERSION, createSettingsStore };