Skip to content

Commit bb885ee

Browse files
committed
Merge branch '4.0.0'
2 parents 3de2767 + f1feb83 commit bb885ee

File tree

5 files changed

+143
-60
lines changed

5 files changed

+143
-60
lines changed

README.md

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
# @folder/xdg [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=W8YFZ425KND68) [![NPM version](https://img.shields.io/npm/v/@folder/xdg.svg?style=flat)](https://www.npmjs.com/package/@folder/xdg) [![NPM monthly downloads](https://img.shields.io/npm/dm/@folder/xdg.svg?style=flat)](https://npmjs.org/package/@folder/xdg) [![NPM total downloads](https://img.shields.io/npm/dt/@folder/xdg.svg?style=flat)](https://npmjs.org/package/@folder/xdg)
1+
# @folder/xdg [![NPM version](https://img.shields.io/npm/v/@folder/xdg.svg?style=flat)](https://www.npmjs.com/package/@folder/xdg) [![NPM monthly downloads](https://img.shields.io/npm/dm/@folder/xdg.svg?style=flat)](https://npmjs.org/package/@folder/xdg) [![NPM total downloads](https://img.shields.io/npm/dt/@folder/xdg.svg?style=flat)](https://npmjs.org/package/@folder/xdg)
22

3-
> Get cross-platform XDG Base Directories or their equivalents. Works with Linux, Windows, or MacOS. No dependencies.
3+
> Get cross-platform XDG Base Directories or their equivalents. Works with Linux, Windows, or MacOS.
44
55
Please consider following this project's author, [Jon Schlinkert](https://github.com/jonschlinkert), and consider starring the project to show your :heart: and support.
66

77
## Install
88

9-
Install with [npm](https://www.npmjs.com/) (requires [Node.js](https://nodejs.org/en/) >=8):
9+
Install with [npm](https://www.npmjs.com/):
1010

1111
```sh
1212
$ npm install --save @folder/xdg
@@ -260,7 +260,7 @@ Get the XDG Base Directory paths for Linux, or equivalent paths for Windows or M
260260
* `options` **{Object}**
261261
* `returns` **{Object}**: Returns an object of paths for the current platform.
262262

263-
### [.darwin](index.js#L43)
263+
### [.darwin](index.js#L44)
264264

265265
Get XDG equivalent paths for MacOS. Used by the main export when `process.platform` is `darwin`. Aliased as `xdg.macos()`.
266266

@@ -277,7 +277,7 @@ const dirs = xdg.darwin();
277277
const dirs = xdg.macos();
278278
```
279279

280-
### [.linux](index.js#L83)
280+
### [.linux](index.js#L89)
281281

282282
Get XDG equivalent paths for Linux. Used by the main export when `process.platform` is `linux`.
283283

@@ -290,7 +290,7 @@ Get XDG equivalent paths for Linux. Used by the main export when `process.platfo
290290
const dirs = xdg.linux();
291291
```
292292

293-
### [.win32](index.js#L124)
293+
### [.win32](index.js#L136)
294294

295295
Get XDG equivalent paths for MacOS. Used by the main export when `process.platform` is `win32`. Aliased as `xdg.windows()`.
296296

@@ -327,7 +327,7 @@ load each file.
327327
* `paths` **{Object}**: Optionally pass the paths from the `userdirs()` function to avoid creating them again.
328328
* `returns` **{Object}**: Returns an object with a `paths` object, and `config`, `defaults`, `dirs`, and `create` functions for actually loading the user-dir files.
329329

330-
### [.userdirs.conf()](lib/userdirs.js#L77)
330+
### [.userdirs.conf()](lib/userdirs.js#L76)
331331

332332
Loads and parses the contents of `user-dirs.conf`, if one exists in user home.
333333

@@ -344,7 +344,7 @@ console.log(config);
344344
//=> { enabled: true, filename_encoding: 'UTF-8' }
345345
```
346346

347-
### [.userdirs.defaults()](lib/userdirs.js#L106)
347+
### [.userdirs.defaults()](lib/userdirs.js#L105)
348348

349349
Loads and parses the contents of `user-dirs.defaults`, if one exists in user home.
350350

@@ -372,7 +372,7 @@ const defaults = userdirs.defaults();
372372
console.log(defaults);
373373
```
374374

375-
### [.userdirs.dirs()](lib/userdirs.js#L133)
375+
### [.userdirs.dirs()](lib/userdirs.js#L132)
376376

377377
Loads and parses the contents of `user-dirs.dirs`, if one exists in user home.
378378

@@ -395,7 +395,7 @@ console.log(dirs);
395395
// }
396396
```
397397

398-
### [.userdirs.create()](lib/userdirs.js#L166)
398+
### [.userdirs.create()](lib/userdirs.js#L165)
399399

400400
Get the actual XDG User Directories to use for MacOS. Gets the `user-dirs.conf`, `user-dirs.defaults`, and the `user-dirs.dirs` files and, if not disabled in `user-dirs.conf`, merges the values in defaults and dirs to create the paths to use.
401401

@@ -422,7 +422,7 @@ console.log(dirs);
422422
// }
423423
```
424424

425-
### [.userdirs.darwin()](lib/userdirs.js#L182)
425+
### [.userdirs.darwin()](lib/userdirs.js#L181)
426426

427427
Get the XDG User Directories for MacOS. This method is used by the main function when `process.platform` is `darwin`. Exposed as a method so you can call it directly if necessary. Also aliased as `userdirs.macos()`.
428428

@@ -437,7 +437,7 @@ Get the XDG User Directories for MacOS. This method is used by the main function
437437
const { dirs, conf, defaults } = userdirs.darwin(); // or userdirs.macos();
438438
```
439439

440-
### [.userdirs.linux()](lib/userdirs.js#L210)
440+
### [.userdirs.linux()](lib/userdirs.js#L209)
441441

442442
Gets the XDG User Directories for Linux. Used by the main export when `process.platform` is `linux`.
443443

@@ -450,7 +450,7 @@ Gets the XDG User Directories for Linux. Used by the main export when `process.p
450450
const { dirs, conf, defaults } = userdirs.linux();
451451
```
452452

453-
### [.userdirs.win32()](lib/userdirs.js#L236)
453+
### [.userdirs.win32()](lib/userdirs.js#L235)
454454

455455
Gets the XDG User Directories for MacOS. Used by the `userdirs()` function when `process.platform` is `win32`. Also aliased as `userdirs.windows()`.
456456

@@ -558,9 +558,9 @@ You might also be interested in these projects:
558558

559559
### License
560560

561-
Copyright © 2020, [Jon Schlinkert](https://github.com/jonschlinkert).
561+
Copyright © 2023, [Jon Schlinkert](https://github.com/jonschlinkert).
562562
Released under the MIT License.
563563

564564
***
565565

566-
_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.8.0, on July 13, 2020._
566+
_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.8.0, on July 22, 2023._

index.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
const os = require('os');
44
const path = require('path');
55
const join = path.join;
6-
const expand = require('./lib/expand');
6+
const { create, expand, loadFile } = require('./lib/expand');
77
const { homedir, load, resolve, split } = require('./lib/utils');
88

99
/**
@@ -68,9 +68,13 @@ xdg.darwin = (options = {}) => {
6868
};
6969

7070
if (options.expanded === true) {
71-
return expand(dirs, options);
71+
const expanded = expand(dirs, options);
72+
expanded.create = create;
73+
expanded.load = (pathname, config, options) => loadFile(config)(pathname, options);
74+
return expanded;
7275
}
7376

77+
dirs.create = create;
7478
return dirs;
7579
};
7680

@@ -116,7 +120,9 @@ xdg.linux = (options = {}) => {
116120
};
117121

118122
if (options.expanded === true) {
119-
return expand(dirs, options);
123+
const expanded = expand(dirs, options);
124+
expanded.create = create;
125+
return expanded;
120126
}
121127

122128
return dirs;
@@ -173,7 +179,9 @@ xdg.win32 = (options = {}) => {
173179
};
174180

175181
if (options.expanded === true) {
176-
return expand(dirs, options);
182+
const expanded = expand(dirs, options);
183+
expanded.create = create;
184+
return expanded;
177185
}
178186

179187
return dirs;

lib/expand.js

Lines changed: 104 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* eslint-disable no-multi-assign */
12
'use strict';
23

34
const os = require('os');
@@ -9,7 +10,7 @@ const ini = require('ini');
910
const toml = require('toml');
1011
const yaml = require('yaml');
1112
const userdirs = require('./userdirs');
12-
const { dir, homedir, read, resolve } = require('./utils');
13+
const { dir, homedir, isObject, read, resolve } = require('./utils');
1314

1415
const readfile = config => (pathname, find = false) => {
1516
try {
@@ -23,35 +24,71 @@ const readfile = config => (pathname, find = false) => {
2324
}
2425
};
2526

26-
const loadFile = config => (pathname, find = true) => {
27+
const parseNpmrc = data => {
28+
const init = {};
29+
30+
for (const [key, value] of Object.entries(data)) {
31+
if (key.startsWith('init-')) {
32+
const segs = key.split('-');
33+
let k = segs[0];
34+
let o = init;
35+
36+
while (segs.length) {
37+
k = segs.shift();
38+
o = o[k] = segs.length ? o[k] || {} : value;
39+
}
40+
41+
delete data[key];
42+
}
43+
}
44+
45+
if (init?.init) {
46+
data.init ||= init?.init;
47+
}
48+
49+
return data;
50+
};
51+
52+
const loadFile = config => (pathname, { find = true, ext } = {}) => {
53+
const basename = path.basename(pathname);
2754
const contents = config.read(pathname, find !== false);
28-
const extname = pathname.startsWith('.env') ? '.env' : path.extname(pathname);
55+
const extname = ext || (basename.startsWith('.env') ? '.env' : path.extname(basename));
2956

3057
if (!contents) {
3158
return {};
3259
}
3360

34-
switch (extname) {
35-
case '.env':
36-
case '.ini':
37-
return ini.parse(contents);
38-
case '.json':
39-
return JSON.parse(contents);
40-
case '.toml':
41-
return toml.parse(contents);
42-
case '.yaml':
43-
case '.yml':
44-
return yaml.parse(contents);
45-
case '.js':
46-
return require(pathname);
47-
default: {
48-
return contents;
61+
const load = () => {
62+
switch (extname) {
63+
case '.env':
64+
case '.ini':
65+
return ini.parse(contents);
66+
case '.json':
67+
return JSON.parse(contents);
68+
case '.toml':
69+
return toml.parse(contents);
70+
case '.yaml':
71+
case '.yml':
72+
return yaml.parse(contents);
73+
case '.js':
74+
return require(pathname);
75+
default: {
76+
return contents;
77+
}
4978
}
79+
};
80+
81+
const data = load();
82+
83+
if (basename === '.npmrc') {
84+
return parseNpmrc(data);
5085
}
86+
87+
return data;
5188
};
5289

53-
const search = (dirs = []) => (pattern, folder) => {
54-
const isMatch = pico(pattern, { dot: true, basename: true });
90+
const search = (dirs = []) => (patterns, folder) => {
91+
const isMatch = pico(patterns, { dot: true });
5592
const matches = [];
5693

5794
for (const dir of dirs) {
@@ -60,8 +97,9 @@ const search = (dirs = []) => (pattern, folder) => {
6097

6198
for (const dirent of dirents) {
6299
dirent.path = path.resolve(dir, dirent.name);
100+
dirent.relative = path.relative(dir, dirent.path);
63101

64-
if (isMatch(dirent.path)) {
102+
if (isMatch(dirent.relative)) {
65103
matches.push(dirent);
66104
}
67105
}
@@ -74,26 +112,47 @@ const writefile = dir => (pathname, ...args) => {
74112
return write(path.resolve(dir, pathname), ...args);
75113
};
76114

77-
const find = dirs => (pathname, ...args) => {
78-
return dirs.map(dir => path.resolve(dir, pathname)).find(fp => fs.existsSync(fp));
115+
const find = config => pathname => {
116+
// const cwd = config.parent?.cwd;
117+
118+
for (const dir of config.dirs) {
119+
const filepath = path.resolve(dir, pathname);
120+
121+
// if (dir === cwd) {
122+
// console.log({ dir, pathname, filepath });
123+
// }
124+
125+
if (fs.existsSync(filepath)) {
126+
return filepath;
127+
}
128+
}
129+
return null;
79130
};
80131

81-
const decorateMethods = dirs => {
132+
const create = config => {
133+
if (Array.isArray(config.dirs)) {
134+
config.find = find(config);
135+
config.search = search(config);
136+
}
137+
138+
config.read = readfile(config);
139+
config.load = loadFile(config);
140+
config.parse = loadFile(config);
141+
config.write = writefile(config.home);
142+
return config;
143+
};
144+
145+
const createDirs = dirs => {
82146
for (const key of Object.keys(dirs)) {
83147
const config = dirs[key];
84148

85-
if (config && typeof config !== 'string') {
86-
if (Array.isArray(config.dirs)) {
87-
config.find = find(config.dirs);
88-
config.search = search(config.dirs);
89-
}
90-
91-
config.read = readfile(config);
92-
config.load = loadFile(config);
93-
config.parse = loadFile(config);
94-
config.write = writefile(config.home);
149+
if (isObject(config)) {
150+
Reflect.defineProperty(config, 'parent', { value: dirs, enumerable: false });
151+
create(config);
95152
}
96153
}
154+
155+
return dirs;
97156
};
98157

99158
// eslint-disable-next-line complexity
@@ -133,8 +192,17 @@ const expand = (paths, options = {}) => {
133192
}
134193
};
135194

136-
decorateMethods(dirs);
195+
createDirs(dirs);
137196
return dirs;
138197
};
139198

140-
module.exports = expand;
199+
module.exports = {
200+
expand,
201+
create,
202+
createDirs,
203+
readfile,
204+
loadFile,
205+
search,
206+
writefile,
207+
find
208+
};

lib/utils.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ const XDG_DIR_REGEX = /^(?:XDG_)?(.+)(?:_DIR)?$/i;
1111
const split = str => str ? str.split(path.delimiter) : [];
1212
const title = str => str ? str[0].toUpperCase() + str.slice(1) : '';
1313

14+
const isObject = v => v !== null && typeof v === 'object' && !Array.isArray(v);
15+
1416
const read = filepath => {
1517
if (filepath) {
1618
return fs.readFileSync(filepath, 'utf8').replace(BOM_REGEX, '');
@@ -162,5 +164,6 @@ module.exports = {
162164
title,
163165
unformatKey,
164166
parseIni,
165-
cast
167+
cast,
168+
isObject
166169
};

0 commit comments

Comments
 (0)