-
-
Notifications
You must be signed in to change notification settings - Fork 197
/
Copy pathuser-settings-service.ts
107 lines (87 loc) · 3.27 KB
/
user-settings-service.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
import * as path from "path";
import { parseJson } from "../helpers";
export class UserSettingsServiceBase implements IUserSettingsService {
private userSettingsFilePath: string = null;
protected userSettingsData: any = null;
private get lockFilePath(): string {
return `user-settings.lock`;
}
constructor(userSettingsFilePath: string,
protected $fs: IFileSystem,
protected $lockService: ILockService,
private $logger: ILogger) {
this.userSettingsFilePath = userSettingsFilePath;
}
public async getSettingValue<T>(settingName: string): Promise<T> {
const action = async (): Promise<T> => {
await this.loadUserSettingsFile();
return this.userSettingsData ? this.userSettingsData[settingName] : null;
};
return this.$lockService.executeActionWithLock<T>(action, this.lockFilePath);
}
public async saveSetting<T>(key: string, value: T): Promise<void> {
const settingObject: any = {};
settingObject[key] = value;
return this.saveSettings(settingObject);
}
public async removeSetting(key: string): Promise<void> {
const action = async (): Promise<void> => {
await this.loadUserSettingsFile();
delete this.userSettingsData[key];
await this.saveSettings();
};
return this.$lockService.executeActionWithLock<void>(action, this.lockFilePath);
}
public saveSettings(data?: any): Promise<void> {
const action = async (): Promise<void> => {
await this.loadUserSettingsFile();
this.userSettingsData = this.userSettingsData || {};
_(data)
.keys()
.each(propertyName => {
this.userSettingsData[propertyName] = data[propertyName];
});
this.$fs.writeJson(this.userSettingsFilePath, this.userSettingsData);
};
return this.$lockService.executeActionWithLock<void>(action, this.lockFilePath);
}
// TODO: Remove Promise, reason: writeFile - blocked as other implementation of the interface has async operation.
public async loadUserSettingsFile(): Promise<void> {
if (!this.userSettingsData) {
await this.loadUserSettingsData();
}
}
protected async loadUserSettingsData(): Promise<void> {
if (!this.$fs.exists(this.userSettingsFilePath)) {
const unexistingDirs = this.getUnexistingDirectories(this.userSettingsFilePath);
this.$fs.writeFile(this.userSettingsFilePath, null);
// when running under 'sudo' we create the <path to home dir>/.local/share/.nativescript-cli dir with root as owner
// and other Applications cannot access this directory anymore. (bower/heroku/etc)
if (process.env.SUDO_USER) {
for (const dir of unexistingDirs) {
await this.$fs.setCurrentUserAsOwner(dir, process.env.SUDO_USER);
}
}
}
const data = this.$fs.readText(this.userSettingsFilePath);
try {
this.userSettingsData = parseJson(data);
} catch (err) {
this.$logger.trace(`Error while trying to parseJson ${data} data from ${this.userSettingsFilePath} file. Err is: ${err}`);
this.$fs.deleteFile(this.userSettingsFilePath);
}
}
private getUnexistingDirectories(filePath: string): Array<string> {
const unexistingDirs: Array<string> = [];
let currentDir = path.join(filePath, "..");
while (true) {
// this directory won't be created.
if (this.$fs.exists(currentDir)) {
break;
}
unexistingDirs.push(currentDir);
currentDir = path.join(currentDir, "..");
}
return unexistingDirs;
}
}