os-user-dirs 2.0.0 → 2.1.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
@@ -18,8 +18,10 @@ $ npm install os-user-dirs
18
18
 
19
19
  ## Usage
20
20
 
21
+ ### ESM (recommended)
22
+
21
23
  ```javascript
22
- const { downloads, desktop, documents, music, pictures, videos, getPath } = require("os-user-dirs");
24
+ import { downloads, desktop, documents, music, pictures, videos, getPath } from "os-user-dirs";
23
25
 
24
26
  downloads();
25
27
  //=> '/home/user/Downloads'
@@ -34,15 +36,40 @@ getPath("music");
34
36
  //=> '/home/user/Music'
35
37
  ```
36
38
 
39
+ ### CommonJS
40
+
41
+ ```javascript
42
+ const { downloads, desktop, documents, music, pictures, videos, getPath } = require("os-user-dirs");
43
+
44
+ downloads();
45
+ //=> '/home/user/Downloads'
46
+ ```
47
+
37
48
  ### Default export (backward compatibility)
38
49
 
39
50
  ```javascript
51
+ // ESM
52
+ import downloads from "os-user-dirs";
53
+
54
+ // CommonJS
40
55
  const downloads = require("os-user-dirs");
41
56
 
42
57
  downloads();
43
58
  //=> '/home/user/Downloads'
44
59
  ```
45
60
 
61
+ ### TypeScript
62
+
63
+ Full type definitions are included. `getPath()` accepts a union type for auto-completion:
64
+
65
+ ```typescript
66
+ import { getPath } from "os-user-dirs";
67
+
68
+ getPath("downloads"); // OK
69
+ getPath("desktop"); // OK
70
+ getPath("unknown"); // Type error
71
+ ```
72
+
46
73
  ## API
47
74
 
48
75
  ### `downloads()`
package/index.d.ts ADDED
@@ -0,0 +1,49 @@
1
+ type DirName = "desktop" | "downloads" | "documents" | "music" | "pictures" | "videos";
2
+
3
+ /** Returns the path to the Desktop directory. */
4
+ export function desktop(): string;
5
+
6
+ /** Returns the path to the Downloads directory. */
7
+ export function downloads(): string;
8
+
9
+ /** Returns the path to the Documents directory. */
10
+ export function documents(): string;
11
+
12
+ /** Returns the path to the Music directory. */
13
+ export function music(): string;
14
+
15
+ /** Returns the path to the Pictures directory. */
16
+ export function pictures(): string;
17
+
18
+ /** Returns the path to the Videos directory (Movies on macOS). */
19
+ export function videos(): string;
20
+
21
+ /** Returns the path to the specified user directory. */
22
+ export function getPath(name: DirName): string;
23
+
24
+ /**
25
+ * Reads an XDG user-dirs.dirs config and returns the directory for the given key.
26
+ * @param key - XDG key (e.g. "XDG_DOWNLOAD_DIR")
27
+ * @param configPath - Optional path to user-dirs.dirs config file
28
+ * @returns The resolved directory path, or null if not found
29
+ */
30
+ export function getXDGUserDir(key: string, configPath?: string): string | null;
31
+
32
+ /**
33
+ * @deprecated Use `getXDGUserDir("XDG_DOWNLOAD_DIR", configPath)` instead.
34
+ */
35
+ export function getXDGDownloadDir(configPath?: string): string | null;
36
+
37
+ declare const osUserDirs: typeof downloads & {
38
+ downloads: typeof downloads;
39
+ desktop: typeof desktop;
40
+ documents: typeof documents;
41
+ music: typeof music;
42
+ pictures: typeof pictures;
43
+ videos: typeof videos;
44
+ getPath: typeof getPath;
45
+ getXDGUserDir: typeof getXDGUserDir;
46
+ getXDGDownloadDir: typeof getXDGDownloadDir;
47
+ };
48
+
49
+ export default osUserDirs;
package/index.mjs ADDED
@@ -0,0 +1,12 @@
1
+ import osUserDirs from './index.js';
2
+
3
+ export default osUserDirs;
4
+ export const downloads = osUserDirs.downloads;
5
+ export const desktop = osUserDirs.desktop;
6
+ export const documents = osUserDirs.documents;
7
+ export const music = osUserDirs.music;
8
+ export const pictures = osUserDirs.pictures;
9
+ export const videos = osUserDirs.videos;
10
+ export const getPath = osUserDirs.getPath;
11
+ export const getXDGUserDir = osUserDirs.getXDGUserDir;
12
+ export const getXDGDownloadDir = osUserDirs.getXDGDownloadDir;
package/package.json CHANGED
@@ -1,8 +1,21 @@
1
1
  {
2
2
  "name": "os-user-dirs",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "Get OS-specific user directories (Downloads, Desktop, Documents, Music, Pictures, Videos) with zero dependencies.",
5
5
  "main": "index.js",
6
+ "types": "index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./index.d.ts",
10
+ "import": "./index.mjs",
11
+ "require": "./index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "index.js",
16
+ "index.mjs",
17
+ "index.d.ts"
18
+ ],
6
19
  "scripts": {
7
20
  "test": "mocha test.js"
8
21
  },
@@ -1,23 +0,0 @@
1
- name: CI
2
-
3
- on:
4
- push:
5
- branches: [master]
6
- pull_request:
7
- branches: [master]
8
-
9
- jobs:
10
- test:
11
- runs-on: ${{ matrix.os }}
12
- strategy:
13
- matrix:
14
- os: [ubuntu-latest, macos-latest, windows-latest]
15
- node-version: [20, 22]
16
- steps:
17
- - uses: actions/checkout@v4
18
- - uses: actions/setup-node@v4
19
- with:
20
- node-version: ${{ matrix.node-version }}
21
- cache: npm
22
- - run: npm install
23
- - run: npm test
package/test.js DELETED
@@ -1,168 +0,0 @@
1
- const assert = require("assert");
2
- const path = require("path");
3
- const os = require("os");
4
- const fs = require("fs");
5
- const downloads = require("./");
6
- const {
7
- getXDGDownloadDir,
8
- getXDGUserDir,
9
- getPath,
10
- desktop,
11
- documents,
12
- music,
13
- pictures,
14
- videos,
15
- } = require("./");
16
-
17
- describe("os-user-dirs", () => {
18
- describe("downloads (default export / backward compatibility)", () => {
19
- it("returns a path ending with Downloads", () => {
20
- assert.ok(path.basename(downloads()).match(/downloads/i));
21
- });
22
-
23
- it("returns an absolute path", () => {
24
- assert.ok(path.isAbsolute(downloads()));
25
- });
26
-
27
- it("path starts with home directory", () => {
28
- assert.ok(downloads().startsWith(os.homedir()));
29
- });
30
- });
31
-
32
- describe("named directory functions", () => {
33
- const cases = [
34
- { fn: desktop, name: "desktop" },
35
- { fn: downloads, name: "downloads" },
36
- { fn: documents, name: "documents" },
37
- { fn: music, name: "music" },
38
- { fn: pictures, name: "pictures" },
39
- { fn: videos, name: "videos" },
40
- ];
41
-
42
- cases.forEach(({ fn, name }) => {
43
- it(`${name}() returns an absolute path`, () => {
44
- assert.ok(path.isAbsolute(fn()));
45
- });
46
-
47
- it(`${name}() starts with home directory`, () => {
48
- assert.ok(fn().startsWith(os.homedir()));
49
- });
50
- });
51
- });
52
-
53
- describe("getPath", () => {
54
- it("returns the same result as named functions", () => {
55
- assert.strictEqual(getPath("desktop"), desktop());
56
- assert.strictEqual(getPath("downloads"), downloads());
57
- assert.strictEqual(getPath("documents"), documents());
58
- assert.strictEqual(getPath("music"), music());
59
- assert.strictEqual(getPath("pictures"), pictures());
60
- assert.strictEqual(getPath("videos"), videos());
61
- });
62
-
63
- it("throws for unknown directory names", () => {
64
- assert.throws(() => getPath("unknown"), /Unknown directory/);
65
- });
66
- });
67
-
68
- describe("getXDGUserDir", () => {
69
- const tmpDir = path.join(os.tmpdir(), "os-user-dirs-test");
70
-
71
- beforeEach(() => {
72
- fs.mkdirSync(tmpDir, { recursive: true });
73
- });
74
-
75
- afterEach(() => {
76
- fs.rmSync(tmpDir, { recursive: true, force: true });
77
- });
78
-
79
- const xdgEntries = [
80
- { key: "XDG_DESKTOP_DIR", value: "Desktop" },
81
- { key: "XDG_DOWNLOAD_DIR", value: "Downloads" },
82
- { key: "XDG_DOCUMENTS_DIR", value: "Documents" },
83
- { key: "XDG_MUSIC_DIR", value: "Music" },
84
- { key: "XDG_PICTURES_DIR", value: "Pictures" },
85
- { key: "XDG_VIDEOS_DIR", value: "Videos" },
86
- ];
87
-
88
- xdgEntries.forEach(({ key, value }) => {
89
- it(`parses ${key} with $HOME`, () => {
90
- const configPath = path.join(tmpDir, "user-dirs.dirs");
91
- fs.writeFileSync(configPath, `${key}="$HOME/${value}"\n`);
92
- const result = getXDGUserDir(key, configPath);
93
- assert.strictEqual(result, path.join(os.homedir(), value));
94
- });
95
- });
96
-
97
- it("parses entry with absolute path", () => {
98
- const configPath = path.join(tmpDir, "user-dirs.dirs");
99
- fs.writeFileSync(configPath, 'XDG_DOWNLOAD_DIR="/custom/downloads"\n');
100
- const result = getXDGUserDir("XDG_DOWNLOAD_DIR", configPath);
101
- assert.strictEqual(result, path.normalize("/custom/downloads"));
102
- });
103
-
104
- it("parses correct entry among multiple entries", () => {
105
- const configPath = path.join(tmpDir, "user-dirs.dirs");
106
- const content = [
107
- 'XDG_DESKTOP_DIR="$HOME/Desktop"',
108
- 'XDG_DOWNLOAD_DIR="$HOME/MyDownloads"',
109
- 'XDG_DOCUMENTS_DIR="$HOME/Documents"',
110
- 'XDG_MUSIC_DIR="$HOME/Musik"',
111
- 'XDG_PICTURES_DIR="$HOME/Bilder"',
112
- 'XDG_VIDEOS_DIR="$HOME/Videos"',
113
- ].join("\n");
114
- fs.writeFileSync(configPath, content);
115
-
116
- assert.strictEqual(
117
- getXDGUserDir("XDG_DOWNLOAD_DIR", configPath),
118
- path.join(os.homedir(), "MyDownloads")
119
- );
120
- assert.strictEqual(
121
- getXDGUserDir("XDG_MUSIC_DIR", configPath),
122
- path.join(os.homedir(), "Musik")
123
- );
124
- assert.strictEqual(
125
- getXDGUserDir("XDG_PICTURES_DIR", configPath),
126
- path.join(os.homedir(), "Bilder")
127
- );
128
- });
129
-
130
- it("returns null when key is not present", () => {
131
- const configPath = path.join(tmpDir, "user-dirs.dirs");
132
- fs.writeFileSync(configPath, 'XDG_DESKTOP_DIR="$HOME/Desktop"\n');
133
- const result = getXDGUserDir("XDG_DOWNLOAD_DIR", configPath);
134
- assert.strictEqual(result, null);
135
- });
136
-
137
- it("returns null when config file does not exist", () => {
138
- const configPath = path.join(tmpDir, "nonexistent");
139
- const result = getXDGUserDir("XDG_DOWNLOAD_DIR", configPath);
140
- assert.strictEqual(result, null);
141
- });
142
- });
143
-
144
- describe("getXDGDownloadDir (backward compatibility)", () => {
145
- const tmpDir = path.join(os.tmpdir(), "os-user-dirs-test");
146
-
147
- beforeEach(() => {
148
- fs.mkdirSync(tmpDir, { recursive: true });
149
- });
150
-
151
- afterEach(() => {
152
- fs.rmSync(tmpDir, { recursive: true, force: true });
153
- });
154
-
155
- it("parses XDG_DOWNLOAD_DIR with $HOME", () => {
156
- const configPath = path.join(tmpDir, "user-dirs.dirs");
157
- fs.writeFileSync(configPath, 'XDG_DOWNLOAD_DIR="$HOME/Downloads"\n');
158
- const result = getXDGDownloadDir(configPath);
159
- assert.strictEqual(result, path.join(os.homedir(), "Downloads"));
160
- });
161
-
162
- it("returns null when config file does not exist", () => {
163
- const configPath = path.join(tmpDir, "nonexistent");
164
- const result = getXDGDownloadDir(configPath);
165
- assert.strictEqual(result, null);
166
- });
167
- });
168
- });