os-user-dirs 2.5.0 → 2.7.0

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/README.md CHANGED
@@ -99,6 +99,27 @@ dirs.runtime //=> '/run/user/1000/my-app' (or null)
99
99
  // With suffix option
100
100
  const dirs2 = projectDirs("my-app", { suffix: "-nodejs" });
101
101
  dirs2.config //=> '/home/user/.config/my-app-nodejs'
102
+
103
+ // With vendor option
104
+ const dirs3 = projectDirs("my-app", { vendor: "My Org" });
105
+ dirs3.config //=> '/home/user/.config/my-org/my-app' (Linux)
106
+ dirs3.config //=> '~/Library/Application Support/My Org/my-app' (macOS)
107
+ ```
108
+
109
+ #### Project user directories
110
+
111
+ ```javascript
112
+ import { projectUserDirs } from "os-user-dirs";
113
+
114
+ const dirs = projectUserDirs("my-app");
115
+ dirs.desktop //=> '/home/user/Desktop/my-app'
116
+ dirs.downloads //=> '/home/user/Downloads/my-app'
117
+ dirs.documents //=> '/home/user/Documents/my-app'
118
+ dirs.music //=> '/home/user/Music/my-app'
119
+ dirs.pictures //=> '/home/user/Pictures/my-app'
120
+ dirs.videos //=> '/home/user/Videos/my-app'
121
+ dirs.templates //=> '/home/user/Templates/my-app'
122
+ dirs.publicshare //=> '/home/user/Public/my-app'
102
123
  ```
103
124
 
104
125
  ### CommonJS
@@ -165,6 +186,15 @@ Returns the path to the Public Share directory.
165
186
  ### `getPath(name)`
166
187
  Returns the path to the specified user directory. Valid names: `desktop`, `downloads`, `documents`, `music`, `pictures`, `videos`, `templates`, `publicshare`.
167
188
 
189
+ ### `binDir()`
190
+ Returns the path to the user local bin directory (`~/.local/bin` on Linux/macOS), or `null` on Windows.
191
+
192
+ ### `applicationsDir()`
193
+ Returns the path to the user applications directory.
194
+ - Linux: `$XDG_DATA_HOME/applications` (default `~/.local/share/applications`)
195
+ - macOS: `~/Applications`
196
+ - Windows: `%APPDATA%\Microsoft\Windows\Start Menu\Programs`
197
+
168
198
  ### Base Directories
169
199
 
170
200
  #### `configDir()`
@@ -185,6 +215,9 @@ Returns the path to the log directory (`~/.local/state` on Linux, `~/Library/Log
185
215
  #### `runtimeDir()`
186
216
  Returns the path to the runtime directory (`$XDG_RUNTIME_DIR` on Linux), or `null` if unavailable.
187
217
 
218
+ #### `fontsDir()`
219
+ Returns the path to the user fonts directory (`~/.local/share/fonts` on Linux, `~/Library/Fonts` on macOS, `%LOCALAPPDATA%/Microsoft/Windows/Fonts` on Windows). On Linux, respects `$XDG_DATA_HOME`.
220
+
188
221
  #### `getBasePath(name)`
189
222
  Returns the path to the specified base directory. Valid names: `config`, `data`, `cache`, `state`, `log`, `runtime`.
190
223
 
@@ -204,11 +237,20 @@ Returns an object with app-scoped directories for the given application name. Th
204
237
  **Parameters:**
205
238
  - `name` (string) — Application name
206
239
  - `options.suffix` (string, optional) — Suffix appended to the app name (e.g. `"-nodejs"`)
240
+ - `options.vendor` (string, optional) — Vendor/organization name used as a parent directory. On Linux, the vendor name is normalized to lowercase with spaces replaced by hyphens (e.g. `"My Org"` → `"my-org"`). On macOS and Windows, it is used as-is.
207
241
 
208
242
  **Returns:** `{ config, data, cache, state, log, temp, runtime }`
209
243
 
210
244
  On Windows, each directory uses a subdirectory structure (e.g. `%LOCALAPPDATA%/my-app/Config`, `%LOCALAPPDATA%/my-app/Data`).
211
245
 
246
+ #### `projectUserDirs(name)`
247
+ Returns an object with project-scoped user directories. Each value is the corresponding user directory with the app name appended as a subdirectory.
248
+
249
+ **Parameters:**
250
+ - `name` (string) — Application name
251
+
252
+ **Returns:** `{ desktop, downloads, documents, music, pictures, videos, templates, publicshare }`
253
+
212
254
  ## License
213
255
 
214
256
  MIT
package/index.d.ts CHANGED
@@ -27,6 +27,9 @@ export function publicshare(): string;
27
27
  /** Returns the path to the specified user directory. */
28
28
  export function getPath(name: DirName): string;
29
29
 
30
+ /** Returns the path to the user local bin directory (~/.local/bin), or null on Windows. */
31
+ export function binDir(): string | null;
32
+
30
33
  type BaseDirName = "config" | "data" | "cache" | "state" | "log" | "runtime";
31
34
 
32
35
  /** Returns the path to the XDG config directory. */
@@ -47,6 +50,9 @@ export function logDir(): string;
47
50
  /** Returns the path to the XDG runtime directory, or null if unavailable. */
48
51
  export function runtimeDir(): string | null;
49
52
 
53
+ /** Returns the path to the user fonts directory. */
54
+ export function fontsDir(): string;
55
+
50
56
  /**
51
57
  * Returns the system config directory search path list.
52
58
  * On Linux, reads `$XDG_CONFIG_DIRS` (default: `["/etc/xdg"]`).
@@ -75,6 +81,8 @@ export function getBasePath(name: BaseDirName): string | null;
75
81
  interface ProjectDirsOptions {
76
82
  /** Suffix appended to the app name (default: ""). */
77
83
  suffix?: string;
84
+ /** Vendor/organization name used as a parent directory (e.g. "My Org"). On Linux, normalized to lowercase with hyphens. */
85
+ vendor?: string;
78
86
  }
79
87
 
80
88
  interface ProjectDirsResult {
@@ -94,6 +102,32 @@ interface ProjectDirsResult {
94
102
  */
95
103
  export function projectDirs(name: string, options?: ProjectDirsOptions): ProjectDirsResult;
96
104
 
105
+ interface ProjectUserDirsResult {
106
+ desktop: string;
107
+ downloads: string;
108
+ documents: string;
109
+ music: string;
110
+ pictures: string;
111
+ videos: string;
112
+ templates: string;
113
+ publicshare: string;
114
+ }
115
+
116
+ /**
117
+ * Returns project-scoped user directories for the given app name.
118
+ * Each value is the user directory path with the app name appended as a subdirectory.
119
+ * @param name - Application name used to derive directory paths
120
+ */
121
+ export function projectUserDirs(name: string): ProjectUserDirsResult;
122
+
123
+ /**
124
+ * Returns the path to the user applications directory.
125
+ * Linux: `$XDG_DATA_HOME/applications` (default `~/.local/share/applications`)
126
+ * macOS: `~/Applications`
127
+ * Windows: `%APPDATA%/Microsoft/Windows/Start Menu/Programs`
128
+ */
129
+ export function applicationsDir(): string;
130
+
97
131
  /**
98
132
  * Reads an XDG user-dirs.dirs config and returns the directory for the given key.
99
133
  * @param key - XDG key (e.g. "XDG_DOWNLOAD_DIR")
@@ -117,16 +151,20 @@ declare const osUserDirs: typeof downloads & {
117
151
  templates: typeof templates;
118
152
  publicshare: typeof publicshare;
119
153
  getPath: typeof getPath;
154
+ binDir: typeof binDir;
120
155
  configDir: typeof configDir;
121
156
  dataDir: typeof dataDir;
122
157
  cacheDir: typeof cacheDir;
123
158
  stateDir: typeof stateDir;
124
159
  logDir: typeof logDir;
125
160
  runtimeDir: typeof runtimeDir;
161
+ fontsDir: typeof fontsDir;
126
162
  getBasePath: typeof getBasePath;
127
163
  configDirs: typeof configDirs;
128
164
  dataDirs: typeof dataDirs;
129
165
  projectDirs: typeof projectDirs;
166
+ applicationsDir: typeof applicationsDir;
167
+ projectUserDirs: typeof projectUserDirs;
130
168
  getXDGUserDir: typeof getXDGUserDir;
131
169
  getXDGDownloadDir: typeof getXDGDownloadDir;
132
170
  };
package/index.js CHANGED
@@ -137,6 +137,13 @@ function resolveBase(name) {
137
137
  return cfg.linux ? path.join(homedir, cfg.linux) : null;
138
138
  }
139
139
 
140
+ function binDir() {
141
+ if (process.platform === "win32") {
142
+ return null;
143
+ }
144
+ return path.join(os.homedir(), ".local", "bin");
145
+ }
146
+
140
147
  function configDir() { return resolveBase("config"); }
141
148
  function dataDir() { return resolveBase("data"); }
142
149
  function cacheDir() { return resolveBase("cache"); }
@@ -144,6 +151,31 @@ function stateDir() { return resolveBase("state"); }
144
151
  function logDir() { return resolveBase("log"); }
145
152
  function runtimeDir() { return resolveBase("runtime"); }
146
153
 
154
+ function fontsDir() {
155
+ var platform = process.platform;
156
+ var homedir = os.homedir();
157
+
158
+ if (platform === "linux") {
159
+ var envVal = process.env.XDG_DATA_HOME;
160
+ if (envVal) {
161
+ return path.join(path.resolve(envVal), "fonts");
162
+ }
163
+ return path.join(homedir, ".local", "share", "fonts");
164
+ }
165
+
166
+ if (platform === "darwin") {
167
+ return path.join(homedir, "Library", "Fonts");
168
+ }
169
+
170
+ if (platform === "win32") {
171
+ var localAppData = process.env.LOCALAPPDATA || path.join(homedir, "AppData", "Local");
172
+ return path.join(localAppData, "Microsoft", "Windows", "Fonts");
173
+ }
174
+
175
+ // Unknown platform: use XDG-style default
176
+ return path.join(homedir, ".local", "share", "fonts");
177
+ }
178
+
147
179
  const SEARCH_DIRS_CONFIG = {
148
180
  config: {
149
181
  env: "XDG_CONFIG_DIRS",
@@ -209,31 +241,48 @@ const PROJECT_DIR_WIN32_SUB = {
209
241
  log: "Log",
210
242
  };
211
243
 
244
+ function normalizeVendor(vendor, platform) {
245
+ if (platform === "linux") {
246
+ return vendor.toLowerCase().replace(/\s+/g, "-");
247
+ }
248
+ return vendor;
249
+ }
250
+
212
251
  function projectDirs(name, options) {
213
252
  if (!name || typeof name !== "string") {
214
253
  throw new Error("projectDirs requires a non-empty string name");
215
254
  }
216
255
 
217
256
  const suffix = (options && options.suffix != null) ? options.suffix : "";
257
+ const vendor = (options && options.vendor) ? options.vendor : "";
218
258
  const appName = name + suffix;
219
259
 
220
260
  const homedir = os.homedir();
221
261
  const platform = process.platform;
262
+ const vendorDir = vendor ? normalizeVendor(vendor, platform) : "";
263
+
264
+ function joinWithVendor() {
265
+ var segments = Array.prototype.slice.call(arguments);
266
+ if (vendorDir) {
267
+ segments.splice(1, 0, vendorDir);
268
+ }
269
+ return path.join.apply(path, segments);
270
+ }
222
271
 
223
272
  function resolveProject(kind) {
224
273
  if (kind === "temp") {
225
274
  if (platform === "win32") {
226
275
  const localAppData = process.env.LOCALAPPDATA || path.join(homedir, "AppData", "Local");
227
- return path.join(localAppData, "Temp", appName);
276
+ return joinWithVendor(localAppData, "Temp", appName);
228
277
  }
229
- return path.join(os.tmpdir(), appName);
278
+ return joinWithVendor(os.tmpdir(), appName);
230
279
  }
231
280
 
232
281
  if (kind === "runtime") {
233
282
  if (platform === "linux") {
234
283
  const envVal = process.env.XDG_RUNTIME_DIR;
235
284
  if (envVal) {
236
- return path.join(path.resolve(envVal), appName);
285
+ return joinWithVendor(path.resolve(envVal), appName);
237
286
  }
238
287
  }
239
288
  return null;
@@ -244,10 +293,10 @@ function projectDirs(name, options) {
244
293
 
245
294
  const sub = PROJECT_DIR_WIN32_SUB[kind];
246
295
  if (platform === "win32" && sub) {
247
- return path.join(base, appName, sub);
296
+ return joinWithVendor(base, appName, sub);
248
297
  }
249
298
 
250
- return path.join(base, appName);
299
+ return joinWithVendor(base, appName);
251
300
  }
252
301
 
253
302
  return {
@@ -261,6 +310,42 @@ function projectDirs(name, options) {
261
310
  };
262
311
  }
263
312
 
313
+ function projectUserDirs(name) {
314
+ if (!name || typeof name !== "string") {
315
+ throw new Error("projectUserDirs requires a non-empty string name");
316
+ }
317
+
318
+ var result = {};
319
+ var keys = Object.keys(XDG_KEYS);
320
+ for (var i = 0; i < keys.length; i++) {
321
+ result[keys[i]] = path.join(resolve(keys[i]), name);
322
+ }
323
+ return result;
324
+ }
325
+
326
+ function applicationsDir() {
327
+ var homedir = os.homedir();
328
+ var platform = process.platform;
329
+
330
+ if (platform === "linux") {
331
+ var envVal = process.env.XDG_DATA_HOME;
332
+ var base = envVal ? path.resolve(envVal) : path.join(homedir, ".local", "share");
333
+ return path.join(base, "applications");
334
+ }
335
+
336
+ if (platform === "darwin") {
337
+ return path.join(homedir, "Applications");
338
+ }
339
+
340
+ if (platform === "win32") {
341
+ var appdata = process.env.APPDATA || path.join(homedir, "AppData", "Roaming");
342
+ return path.join(appdata, "Microsoft", "Windows", "Start Menu", "Programs");
343
+ }
344
+
345
+ // Unknown platform: use XDG-style default
346
+ return path.join(homedir, ".local", "share", "applications");
347
+ }
348
+
264
349
  // Backward compatibility: require("os-user-dirs")() returns Downloads path
265
350
  module.exports = downloads;
266
351
  module.exports.getPath = getPath;
@@ -272,16 +357,20 @@ module.exports.pictures = pictures;
272
357
  module.exports.videos = videos;
273
358
  module.exports.templates = templates;
274
359
  module.exports.publicshare = publicshare;
360
+ module.exports.binDir = binDir;
275
361
  module.exports.configDir = configDir;
276
362
  module.exports.dataDir = dataDir;
277
363
  module.exports.cacheDir = cacheDir;
278
364
  module.exports.stateDir = stateDir;
279
365
  module.exports.logDir = logDir;
280
366
  module.exports.runtimeDir = runtimeDir;
367
+ module.exports.fontsDir = fontsDir;
281
368
  module.exports.getBasePath = getBasePath;
282
369
  module.exports.configDirs = configDirs;
283
370
  module.exports.dataDirs = dataDirs;
284
371
  module.exports.projectDirs = projectDirs;
372
+ module.exports.applicationsDir = applicationsDir;
373
+ module.exports.projectUserDirs = projectUserDirs;
285
374
  module.exports.getXDGUserDir = getXDGUserDir;
286
375
 
287
376
  // Deprecated: kept for backward compatibility
package/index.mjs CHANGED
@@ -10,15 +10,19 @@ export const videos = osUserDirs.videos;
10
10
  export const templates = osUserDirs.templates;
11
11
  export const publicshare = osUserDirs.publicshare;
12
12
  export const getPath = osUserDirs.getPath;
13
+ export const binDir = osUserDirs.binDir;
13
14
  export const configDir = osUserDirs.configDir;
14
15
  export const dataDir = osUserDirs.dataDir;
15
16
  export const cacheDir = osUserDirs.cacheDir;
16
17
  export const stateDir = osUserDirs.stateDir;
17
18
  export const logDir = osUserDirs.logDir;
18
19
  export const runtimeDir = osUserDirs.runtimeDir;
20
+ export const fontsDir = osUserDirs.fontsDir;
19
21
  export const getBasePath = osUserDirs.getBasePath;
20
22
  export const configDirs = osUserDirs.configDirs;
21
23
  export const dataDirs = osUserDirs.dataDirs;
22
24
  export const projectDirs = osUserDirs.projectDirs;
25
+ export const applicationsDir = osUserDirs.applicationsDir;
26
+ export const projectUserDirs = osUserDirs.projectUserDirs;
23
27
  export const getXDGUserDir = osUserDirs.getXDGUserDir;
24
28
  export const getXDGDownloadDir = osUserDirs.getXDGDownloadDir;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "os-user-dirs",
3
- "version": "2.5.0",
3
+ "version": "2.7.0",
4
4
  "description": "Get OS-specific user directories and XDG base directories (config, data, cache, runtime) with zero dependencies.",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",