os-user-dirs 2.0.0 → 2.2.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 +28 -1
- package/index.d.ts +49 -0
- package/index.mjs +12 -0
- package/package.json +14 -1
- package/.github/workflows/ci.yml +0 -23
- package/test.js +0 -168
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
|
-
|
|
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.
|
|
3
|
+
"version": "2.2.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
|
},
|
package/.github/workflows/ci.yml
DELETED
|
@@ -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
|
-
});
|