os-user-dirs 2.6.0 → 3.0.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
@@ -4,6 +4,10 @@ Get OS-specific user directories (Downloads, Desktop, Documents, etc.) and XDG b
4
4
 
5
5
  > **Note:** This package was previously published as [`os-downloads`](https://www.npmjs.com/package/os-downloads). The old package is deprecated — please use `os-user-dirs` instead.
6
6
 
7
+ ## Requirements
8
+
9
+ - Node.js 18 or later
10
+
7
11
  ## Supported platforms
8
12
 
9
13
  - Windows
@@ -21,7 +25,10 @@ $ npm install os-user-dirs
21
25
  ### ESM (recommended)
22
26
 
23
27
  ```javascript
24
- import { downloads, desktop, documents, music, pictures, videos, templates, publicshare, getPath } from "os-user-dirs";
28
+ import { downloads, desktop, documents, music, pictures, videos, templates, publicshare, getPath, homeDir } from "os-user-dirs";
29
+
30
+ homeDir();
31
+ //=> '/home/user'
25
32
 
26
33
  downloads();
27
34
  //=> '/home/user/Downloads'
@@ -99,6 +106,27 @@ dirs.runtime //=> '/run/user/1000/my-app' (or null)
99
106
  // With suffix option
100
107
  const dirs2 = projectDirs("my-app", { suffix: "-nodejs" });
101
108
  dirs2.config //=> '/home/user/.config/my-app-nodejs'
109
+
110
+ // With vendor option
111
+ const dirs3 = projectDirs("my-app", { vendor: "My Org" });
112
+ dirs3.config //=> '/home/user/.config/my-org/my-app' (Linux)
113
+ dirs3.config //=> '~/Library/Application Support/My Org/my-app' (macOS)
114
+ ```
115
+
116
+ #### Project user directories
117
+
118
+ ```javascript
119
+ import { projectUserDirs } from "os-user-dirs";
120
+
121
+ const dirs = projectUserDirs("my-app");
122
+ dirs.desktop //=> '/home/user/Desktop/my-app'
123
+ dirs.downloads //=> '/home/user/Downloads/my-app'
124
+ dirs.documents //=> '/home/user/Documents/my-app'
125
+ dirs.music //=> '/home/user/Music/my-app'
126
+ dirs.pictures //=> '/home/user/Pictures/my-app'
127
+ dirs.videos //=> '/home/user/Videos/my-app'
128
+ dirs.templates //=> '/home/user/Templates/my-app'
129
+ dirs.publicshare //=> '/home/user/Public/my-app'
102
130
  ```
103
131
 
104
132
  ### CommonJS
@@ -165,9 +193,18 @@ Returns the path to the Public Share directory.
165
193
  ### `getPath(name)`
166
194
  Returns the path to the specified user directory. Valid names: `desktop`, `downloads`, `documents`, `music`, `pictures`, `videos`, `templates`, `publicshare`.
167
195
 
196
+ ### `homeDir()`
197
+ Returns the path to the user's home directory. Uses `os.homedir()` internally.
198
+
168
199
  ### `binDir()`
169
200
  Returns the path to the user local bin directory (`~/.local/bin` on Linux/macOS), or `null` on Windows.
170
201
 
202
+ ### `trashDir()`
203
+ Returns the path to the user trash directory, or `null` on Windows.
204
+ - Linux: `$XDG_DATA_HOME/Trash` (default `~/.local/share/Trash`) — FreeDesktop Trash spec
205
+ - macOS: `~/.Trash`
206
+ - Windows: `null` (Recycle Bin requires Shell API)
207
+
171
208
  ### `applicationsDir()`
172
209
  Returns the path to the user applications directory.
173
210
  - Linux: `$XDG_DATA_HOME/applications` (default `~/.local/share/applications`)
@@ -216,11 +253,63 @@ Returns an object with app-scoped directories for the given application name. Th
216
253
  **Parameters:**
217
254
  - `name` (string) — Application name
218
255
  - `options.suffix` (string, optional) — Suffix appended to the app name (e.g. `"-nodejs"`)
256
+ - `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.
219
257
 
220
258
  **Returns:** `{ config, data, cache, state, log, temp, runtime }`
221
259
 
222
260
  On Windows, each directory uses a subdirectory structure (e.g. `%LOCALAPPDATA%/my-app/Config`, `%LOCALAPPDATA%/my-app/Data`).
223
261
 
262
+ #### `projectUserDirs(name)`
263
+ Returns an object with project-scoped user directories. Each value is the corresponding user directory with the app name appended as a subdirectory.
264
+
265
+ **Parameters:**
266
+ - `name` (string) — Application name
267
+
268
+ **Returns:** `{ desktop, downloads, documents, music, pictures, videos, templates, publicshare }`
269
+
270
+ ### Utilities
271
+
272
+ #### `ensureDirSync(dirPath)`
273
+ Ensures the specified directory exists, creating it recursively if necessary. Returns the directory path.
274
+
275
+ #### `ensureDir(dirPath)`
276
+ Async version of `ensureDirSync`. Returns a promise that resolves with the directory path.
277
+
278
+ ```javascript
279
+ import { projectDirs, ensureDirSync, ensureDir } from "os-user-dirs";
280
+
281
+ const dirs = projectDirs("my-app");
282
+
283
+ // Sync
284
+ ensureDirSync(dirs.config);
285
+
286
+ // Async
287
+ await ensureDir(dirs.data);
288
+ ```
289
+
290
+ ## Migration from env-paths
291
+
292
+ Switching from [env-paths](https://github.com/sindresorhus/env-paths)? See the **[Migration Guide](docs/migration-from-env-paths.md)** for API mapping, code examples, and a summary of additional features.
293
+
294
+ ## Migration from v2.x
295
+
296
+ ### `getXDGDownloadDir()` removed
297
+
298
+ `getXDGDownloadDir()` was deprecated in v2.3.0 and has been removed in v3.0.0.
299
+
300
+ **Before (v2.x):**
301
+ ```javascript
302
+ const { getXDGDownloadDir } = require("os-user-dirs");
303
+ getXDGDownloadDir(); // reads XDG user-dirs.dirs for download path
304
+ ```
305
+
306
+ **After (v3.x):**
307
+ ```javascript
308
+ const { downloads, getXDGUserDir } = require("os-user-dirs");
309
+ downloads(); // recommended: cross-platform Downloads path
310
+ getXDGUserDir("XDG_DOWNLOAD_DIR"); // direct replacement if you need XDG config parsing
311
+ ```
312
+
224
313
  ## License
225
314
 
226
315
  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's home directory. */
31
+ export function homeDir(): string;
32
+
30
33
  /** Returns the path to the user local bin directory (~/.local/bin), or null on Windows. */
31
34
  export function binDir(): string | null;
32
35
 
@@ -81,6 +84,8 @@ export function getBasePath(name: BaseDirName): string | null;
81
84
  interface ProjectDirsOptions {
82
85
  /** Suffix appended to the app name (default: ""). */
83
86
  suffix?: string;
87
+ /** Vendor/organization name used as a parent directory (e.g. "My Org"). On Linux, normalized to lowercase with hyphens. */
88
+ vendor?: string;
84
89
  }
85
90
 
86
91
  interface ProjectDirsResult {
@@ -100,6 +105,32 @@ interface ProjectDirsResult {
100
105
  */
101
106
  export function projectDirs(name: string, options?: ProjectDirsOptions): ProjectDirsResult;
102
107
 
108
+ interface ProjectUserDirsResult {
109
+ desktop: string;
110
+ downloads: string;
111
+ documents: string;
112
+ music: string;
113
+ pictures: string;
114
+ videos: string;
115
+ templates: string;
116
+ publicshare: string;
117
+ }
118
+
119
+ /**
120
+ * Returns project-scoped user directories for the given app name.
121
+ * Each value is the user directory path with the app name appended as a subdirectory.
122
+ * @param name - Application name used to derive directory paths
123
+ */
124
+ export function projectUserDirs(name: string): ProjectUserDirsResult;
125
+
126
+ /**
127
+ * Returns the path to the user trash directory, or null on Windows.
128
+ * Linux: `$XDG_DATA_HOME/Trash` (default `~/.local/share/Trash`)
129
+ * macOS: `~/.Trash`
130
+ * Windows: `null` (Recycle Bin requires Shell API)
131
+ */
132
+ export function trashDir(): string | null;
133
+
103
134
  /**
104
135
  * Returns the path to the user applications directory.
105
136
  * Linux: `$XDG_DATA_HOME/applications` (default `~/.local/share/applications`)
@@ -117,9 +148,18 @@ export function applicationsDir(): string;
117
148
  export function getXDGUserDir(key: string, configPath?: string): string | null;
118
149
 
119
150
  /**
120
- * @deprecated Use `getXDGUserDir("XDG_DOWNLOAD_DIR", configPath)` instead.
151
+ * Ensures the specified directory exists, creating it recursively if necessary.
152
+ * @param dirPath - The directory path to ensure exists
153
+ * @returns The directory path
154
+ */
155
+ export function ensureDirSync(dirPath: string): string;
156
+
157
+ /**
158
+ * Ensures the specified directory exists, creating it recursively if necessary (async version).
159
+ * @param dirPath - The directory path to ensure exists
160
+ * @returns A promise that resolves with the directory path
121
161
  */
122
- export function getXDGDownloadDir(configPath?: string): string | null;
162
+ export function ensureDir(dirPath: string): Promise<string>;
123
163
 
124
164
  declare const osUserDirs: typeof downloads & {
125
165
  downloads: typeof downloads;
@@ -143,9 +183,13 @@ declare const osUserDirs: typeof downloads & {
143
183
  configDirs: typeof configDirs;
144
184
  dataDirs: typeof dataDirs;
145
185
  projectDirs: typeof projectDirs;
186
+ trashDir: typeof trashDir;
146
187
  applicationsDir: typeof applicationsDir;
188
+ projectUserDirs: typeof projectUserDirs;
189
+ homeDir: typeof homeDir;
147
190
  getXDGUserDir: typeof getXDGUserDir;
148
- getXDGDownloadDir: typeof getXDGDownloadDir;
191
+ ensureDirSync: typeof ensureDirSync;
192
+ ensureDir: typeof ensureDir;
149
193
  };
150
194
 
151
195
  export default osUserDirs;
package/index.js CHANGED
@@ -1,6 +1,6 @@
1
- const path = require("path");
2
- const os = require("os");
3
- const fs = require("fs");
1
+ const path = require("node:path");
2
+ const os = require("node:os");
3
+ const fs = require("node:fs");
4
4
 
5
5
  const XDG_KEYS = {
6
6
  desktop: "XDG_DESKTOP_DIR",
@@ -241,31 +241,48 @@ const PROJECT_DIR_WIN32_SUB = {
241
241
  log: "Log",
242
242
  };
243
243
 
244
+ function normalizeVendor(vendor, platform) {
245
+ if (platform === "linux") {
246
+ return vendor.toLowerCase().replace(/\s+/g, "-");
247
+ }
248
+ return vendor;
249
+ }
250
+
244
251
  function projectDirs(name, options) {
245
252
  if (!name || typeof name !== "string") {
246
253
  throw new Error("projectDirs requires a non-empty string name");
247
254
  }
248
255
 
249
256
  const suffix = (options && options.suffix != null) ? options.suffix : "";
257
+ const vendor = (options && options.vendor) ? options.vendor : "";
250
258
  const appName = name + suffix;
251
259
 
252
260
  const homedir = os.homedir();
253
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
+ }
254
271
 
255
272
  function resolveProject(kind) {
256
273
  if (kind === "temp") {
257
274
  if (platform === "win32") {
258
275
  const localAppData = process.env.LOCALAPPDATA || path.join(homedir, "AppData", "Local");
259
- return path.join(localAppData, "Temp", appName);
276
+ return joinWithVendor(localAppData, "Temp", appName);
260
277
  }
261
- return path.join(os.tmpdir(), appName);
278
+ return joinWithVendor(os.tmpdir(), appName);
262
279
  }
263
280
 
264
281
  if (kind === "runtime") {
265
282
  if (platform === "linux") {
266
283
  const envVal = process.env.XDG_RUNTIME_DIR;
267
284
  if (envVal) {
268
- return path.join(path.resolve(envVal), appName);
285
+ return joinWithVendor(path.resolve(envVal), appName);
269
286
  }
270
287
  }
271
288
  return null;
@@ -276,10 +293,10 @@ function projectDirs(name, options) {
276
293
 
277
294
  const sub = PROJECT_DIR_WIN32_SUB[kind];
278
295
  if (platform === "win32" && sub) {
279
- return path.join(base, appName, sub);
296
+ return joinWithVendor(base, appName, sub);
280
297
  }
281
298
 
282
- return path.join(base, appName);
299
+ return joinWithVendor(base, appName);
283
300
  }
284
301
 
285
302
  return {
@@ -293,6 +310,43 @@ function projectDirs(name, options) {
293
310
  };
294
311
  }
295
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 trashDir() {
327
+ var platform = process.platform;
328
+ var homedir = os.homedir();
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, "Trash");
334
+ }
335
+
336
+ if (platform === "darwin") {
337
+ return path.join(homedir, ".Trash");
338
+ }
339
+
340
+ if (platform === "win32") {
341
+ return null;
342
+ }
343
+
344
+ // Unknown platform: use XDG-style default
345
+ var envVal = process.env.XDG_DATA_HOME;
346
+ var base = envVal ? path.resolve(envVal) : path.join(homedir, ".local", "share");
347
+ return path.join(base, "Trash");
348
+ }
349
+
296
350
  function applicationsDir() {
297
351
  var homedir = os.homedir();
298
352
  var platform = process.platform;
@@ -316,6 +370,27 @@ function applicationsDir() {
316
370
  return path.join(homedir, ".local", "share", "applications");
317
371
  }
318
372
 
373
+ function homeDir() {
374
+ return os.homedir();
375
+ }
376
+
377
+ function ensureDirSync(dirPath) {
378
+ if (!dirPath || typeof dirPath !== "string") {
379
+ throw new Error("ensureDirSync requires a non-empty string path");
380
+ }
381
+ fs.mkdirSync(dirPath, { recursive: true });
382
+ return dirPath;
383
+ }
384
+
385
+ function ensureDir(dirPath) {
386
+ if (!dirPath || typeof dirPath !== "string") {
387
+ return Promise.reject(new Error("ensureDir requires a non-empty string path"));
388
+ }
389
+ return fs.promises.mkdir(dirPath, { recursive: true }).then(function () {
390
+ return dirPath;
391
+ });
392
+ }
393
+
319
394
  // Backward compatibility: require("os-user-dirs")() returns Downloads path
320
395
  module.exports = downloads;
321
396
  module.exports.getPath = getPath;
@@ -340,9 +415,9 @@ module.exports.configDirs = configDirs;
340
415
  module.exports.dataDirs = dataDirs;
341
416
  module.exports.projectDirs = projectDirs;
342
417
  module.exports.applicationsDir = applicationsDir;
418
+ module.exports.projectUserDirs = projectUserDirs;
419
+ module.exports.homeDir = homeDir;
343
420
  module.exports.getXDGUserDir = getXDGUserDir;
344
-
345
- // Deprecated: kept for backward compatibility
346
- module.exports.getXDGDownloadDir = function (configPath) {
347
- return getXDGUserDir("XDG_DOWNLOAD_DIR", configPath);
348
- };
421
+ module.exports.ensureDirSync = ensureDirSync;
422
+ module.exports.trashDir = trashDir;
423
+ module.exports.ensureDir = ensureDir;
package/index.mjs CHANGED
@@ -23,5 +23,9 @@ export const configDirs = osUserDirs.configDirs;
23
23
  export const dataDirs = osUserDirs.dataDirs;
24
24
  export const projectDirs = osUserDirs.projectDirs;
25
25
  export const applicationsDir = osUserDirs.applicationsDir;
26
+ export const projectUserDirs = osUserDirs.projectUserDirs;
27
+ export const homeDir = osUserDirs.homeDir;
26
28
  export const getXDGUserDir = osUserDirs.getXDGUserDir;
27
- export const getXDGDownloadDir = osUserDirs.getXDGDownloadDir;
29
+ export const trashDir = osUserDirs.trashDir;
30
+ export const ensureDirSync = osUserDirs.ensureDirSync;
31
+ export const ensureDir = osUserDirs.ensureDir;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "os-user-dirs",
3
- "version": "2.6.0",
3
+ "version": "3.0.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",
@@ -46,6 +46,9 @@
46
46
  "bugs": {
47
47
  "url": "https://github.com/velocitylabo/os-user-dirs/issues"
48
48
  },
49
+ "engines": {
50
+ "node": ">=18"
51
+ },
49
52
  "homepage": "https://github.com/velocitylabo/os-user-dirs#readme",
50
53
  "devDependencies": {
51
54
  "mocha": "^11.7.5"