platformdirs 4.3.6 → 4.3.8-rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/windows.js ADDED
@@ -0,0 +1,279 @@
1
+ /**
2
+ * @module
3
+ * Windows.
4
+ */
5
+
6
+ import * as path from "node:path";
7
+ import process from "node:process";
8
+ import { PlatformDirsABC } from "./api.js";
9
+
10
+ /**
11
+ * [MSDN on where to store app data
12
+ * files](https://learn.microsoft.com/en-us/windows/win32/shell/knownfolderid)
13
+ *
14
+ * Makes use of the {@link PlatformDirsABC.appname},
15
+ * {@link PlatformDirsABC.appauthor}, {@link PlatformDirsABC.version},
16
+ * {@link PlatformDirsABC.roaming}, {@link PlatformDirsABC.opinion},
17
+ * {@link PlatformDirsABC.ensureExists}.
18
+ */
19
+ export class Windows extends PlatformDirsABC {
20
+ /**
21
+ * @return {string} data directory tied to the user, e.g. `%USERPROFILE%\AppData\Local\$appauthor\$appname` (not roaming) or `%USERPROFILE%\AppData\Roaming\$appauthor\$appname` (roaming)
22
+ * @override
23
+ */
24
+ get userDataDir() {
25
+ const const2 = this.roaming ? "CSIDL_APPDATA" : "CSIDL_LOCAL_APPDATA";
26
+ const path2 = path.normalize(getWinFolder(const2));
27
+ return this._appendParts(path2);
28
+ }
29
+
30
+ /**
31
+ * @protected
32
+ * @param {string} path2
33
+ * @param {{ opinionValue?: string | undefined }} [param1]
34
+ * @return {string}
35
+ */
36
+ _appendParts(path2, { opinionValue } = {}) {
37
+ const params = [];
38
+ if (this.appname) {
39
+ if (this.appauthor !== false) {
40
+ const author = this.appauthor || this.appname;
41
+ params.push(author);
42
+ }
43
+ params.push(this.appname);
44
+ if (opinionValue !== undefined && this.opinion) {
45
+ params.push(opinionValue);
46
+ }
47
+ if (this.version) {
48
+ params.push(this.version);
49
+ }
50
+ }
51
+ const path3 = path.join(path2, ...params);
52
+ this._optionallyCreateDirectory(path3);
53
+ return path3;
54
+ }
55
+
56
+ /**
57
+ * @return {string} data directory shared by users, e.g. `C:\ProgramData\$appauthor\$appname`
58
+ * @override
59
+ */
60
+ get siteDataDir() {
61
+ const path2 = path.normalize(getWinFolder("CSIDL_COMMON_APPDATA"));
62
+ return this._appendParts(path2);
63
+ }
64
+
65
+ /**
66
+ * @override
67
+ * @return {string} config directory tied to the user, same as `userDataDir`
68
+ */
69
+ get userConfigDir() {
70
+ return this.userDataDir;
71
+ }
72
+
73
+ /**
74
+ * @return {string} config directory shared by users, same as `siteDataDir`
75
+ * @override
76
+ */
77
+ get siteConfigDir() {
78
+ return this.siteDataDir;
79
+ }
80
+
81
+ /**
82
+ * @override
83
+ * @return {string} cache directory tied to the user (if opinionated with `Cache` folder within `$appname`) e.g. `%USERPROFILE%\AppData\Local\$appauthor\$appname\Cache\$version`
84
+ */
85
+ get userCacheDir() {
86
+ const path2 = path.normalize(getWinFolder("CSIDL_LOCAL_APPDATA"));
87
+ return this._appendParts(path2, { opinionValue: "Cache" });
88
+ }
89
+
90
+ /**
91
+ * @override
92
+ * @return {string} cache directory shared by users, e.g. `C:\ProgramData\$appauthor\$appname\Cache\$version`
93
+ */
94
+ get siteCacheDir() {
95
+ const path2 = path.normalize(getWinFolder("CSIDL_COMMON_APPDATA"));
96
+ return this._appendParts(path2, { opinionValue: "Cache" });
97
+ }
98
+
99
+ /**
100
+ * @override
101
+ * @return {string} state directory tied to the user, same as `userDataDir`
102
+ */
103
+ get userStateDir() {
104
+ return this.userDataDir;
105
+ }
106
+
107
+ /**
108
+ * @override
109
+ * @return {string} log directory tied to the user, same as `userCacheDir` if not opinionated else `log` in it
110
+ */
111
+ get userLogDir() {
112
+ let path2 = this.userDataDir;
113
+ if (this.opinion) {
114
+ path2 = path.join(path2, "Logs");
115
+ this._optionallyCreateDirectory(path2);
116
+ }
117
+ return path2;
118
+ }
119
+
120
+ /**
121
+ * @return {string} documents directory tied to the user, e.g. `%USERPROFILE%\Documents`
122
+ * @override
123
+ */
124
+ get userDocumentsDir() {
125
+ return path.normalize(getWinFolder("CSIDL_PERSONAL"));
126
+ }
127
+
128
+ /**
129
+ * @override
130
+ * @return {string} downloads directory tied to the user, e.g. `%USERPROFILE%\Downloads`
131
+ */
132
+ get userDownloadsDir() {
133
+ return path.normalize(getWinFolder("CSIDL_DOWNLOADS"));
134
+ }
135
+
136
+ /**
137
+ * @override
138
+ * @return {string} pictures directory tied to the user, e.g. `%USERPROFILE%\Pictures`
139
+ */
140
+ get userPicturesDir() {
141
+ return path.normalize(getWinFolder("CSIDL_MYPICTURES"));
142
+ }
143
+
144
+ /**
145
+ * @override
146
+ * @return {string} videos directory tied to the user, e.g. `%USERPROFILE%\Videos`
147
+ */
148
+ get userVideosDir() {
149
+ return path.normalize(getWinFolder("CSIDL_MYVIDEO"));
150
+ }
151
+
152
+ /**
153
+ * @override
154
+ * @return {string} music directory tied to the user, e.g. `%USERPROFILE%\Music`
155
+ */
156
+ get userMusicDir() {
157
+ return path.normalize(getWinFolder("CSIDL_MYMUSIC"));
158
+ }
159
+
160
+ /**
161
+ * @override
162
+ * @return {string} desktop directory tied to the user, e.g. `%USERPROFILE%\Desktop`
163
+ */
164
+ get userDesktopDir() {
165
+ return path.normalize(getWinFolder("CSIDL_DESKTOPDIRECTORY"));
166
+ }
167
+
168
+ /**
169
+ * @override
170
+ * @return {string} runtime directory tied to the user, e.g. `%USERPROFILE%\AppData\Local\Temp\$appauthor\$appname`
171
+ */
172
+ get userRuntimeDir() {
173
+ const path2 = path.normalize(
174
+ path.join(getWinFolder("CSIDL_LOCAL_APPDATA"), "Temp"),
175
+ );
176
+ return this._appendParts(path2);
177
+ }
178
+
179
+ /**
180
+ * @override
181
+ * @return {string} runtime directory shared by users, same as `userRuntimeDir`
182
+ */
183
+ get siteRuntimeDir() {
184
+ return this.userRuntimeDir;
185
+ }
186
+ }
187
+
188
+ /**
189
+ * Get folder from environment variable
190
+ * @param {string} csidlName
191
+ * @return {string}
192
+ */
193
+ function getWinFolderFromEnvVars(csidlName) {
194
+ let result = getWinFolderIfCSIDLNameNotEnvVar(csidlName);
195
+ if (result !== undefined) {
196
+ return result;
197
+ }
198
+
199
+ if (csidlName === "CSIDL_APPDATA") {
200
+ result = process.env.APPDATA;
201
+ if (result === undefined) {
202
+ throw new Error("Unset environment variable: APPDATA");
203
+ }
204
+ } else if (csidlName === "CSIDL_COMMON_APPDATA") {
205
+ result = process.env.ALLUSERSPROFILE;
206
+ if (result === undefined) {
207
+ throw new Error("Unset environment variable: ALLUSERSPROFILE");
208
+ }
209
+ } else if (csidlName === "CSIDL_LOCAL_APPDATA") {
210
+ result = process.env.LOCALAPPDATA;
211
+ if (result === undefined) {
212
+ throw new Error("Unset environment variable: LOCALAPPDATA");
213
+ }
214
+ } else {
215
+ throw new Error(`Unknown CSIDL name: ${csidlName}`);
216
+ }
217
+ return result;
218
+ }
219
+
220
+ /**
221
+ * Get a folder for a CSIDL name that does not exist as an environment variable.
222
+ * @param {string} csidlName
223
+ * @return {string | undefined}
224
+ */
225
+ function getWinFolderIfCSIDLNameNotEnvVar(csidlName) {
226
+ if (csidlName === "CSIDL_PERSONAL") {
227
+ const p = process.env.USERPROFILE;
228
+ if (p === undefined) {
229
+ throw new Error("Unset environment variable: USERPROFILE");
230
+ }
231
+ return path.join(path.normalize(p), "Documents");
232
+ }
233
+ if (csidlName === "CSIDL_DOWNLOADS") {
234
+ const p = process.env.USERPROFILE;
235
+ if (p === undefined) {
236
+ throw new Error("Unset environment variable: USERPROFILE");
237
+ }
238
+ return path.join(path.normalize(p), "Downloads");
239
+ }
240
+ if (csidlName === "CSIDL_MYPICTURES") {
241
+ const p = process.env.USERPROFILE;
242
+ if (p === undefined) {
243
+ throw new Error("Unset environment variable: USERPROFILE");
244
+ }
245
+ return path.join(path.normalize(p), "Pictures");
246
+ }
247
+ if (csidlName === "CSIDL_MYVIDEO") {
248
+ const p = process.env.USERPROFILE;
249
+ if (p === undefined) {
250
+ throw new Error("Unset environment variable: USERPROFILE");
251
+ }
252
+ return path.join(path.normalize(p), "Videos");
253
+ }
254
+ if (csidlName === "CSIDL_MYMUSIC") {
255
+ const p = process.env.USERPROFILE;
256
+ if (p === undefined) {
257
+ throw new Error("Unset environment variable: USERPROFILE");
258
+ }
259
+ return path.join(path.normalize(p), "Music");
260
+ }
261
+ return undefined;
262
+ }
263
+
264
+ // function getWinFolderFromRegistry(csidlName: string): string {
265
+ // throw new Error("Not implemented");
266
+ // }
267
+
268
+ // function getWinFolderViaCTypes(csidlName: string): string {
269
+ // throw new Error("Not implemented");
270
+ // }
271
+
272
+ /**
273
+ * @returns {(csidlName: string) => string}
274
+ */
275
+ function pickGetWinFolder() {
276
+ return getWinFolderFromEnvVars;
277
+ }
278
+
279
+ const getWinFolder = pickGetWinFolder();