1 | <img style="float: right; width: 48px;" src="icon.png"></img>
|
2 |
|
3 | # Closest File Data [![Build Status](https://travis-ci.org/huafu/closest-file-data.svg?branch=master)](https://travis-ci.org/huafu/closest-file-data) [![Beerpay](https://beerpay.io/huafu/closest-file-data/badge.svg?style=beer-square)](https://beerpay.io/huafu/closest-file-data) [![Beerpay](https://beerpay.io/huafu/closest-file-data/make-wish.svg?style=flat-square)](https://beerpay.io/huafu/closest-file-data?focus=wish)
|
4 |
|
5 | A NodeJS module to find and retrieve data (such as config) related to a given path. No dependencies. Implements caching.
|
6 |
|
7 | ## What is this?
|
8 |
|
9 | ### TL;DR:
|
10 |
|
11 | ```js
|
12 | // some/project/path
|
13 | // ├── package.json
|
14 | // └── src
|
15 | // ├── index.js
|
16 | // └── utils
|
17 | // └── dummy.js
|
18 | const pkg = closestFileData(
|
19 | '/some/project/path/src/utils/dummy.js',
|
20 | {basename: 'package.json', read: require}
|
21 | );
|
22 | console.log(pkg.version);
|
23 | ```
|
24 |
|
25 | ---
|
26 |
|
27 | ### A more complex example
|
28 |
|
29 | Let's say you want to find some config data related to a given file. We'll take BabelJS for example. Their config can be
|
30 | a `JSON` file in `.babelrc`, or a `JS` file in `.babelrc.js`, or even in the `babel` key of `package.json`.
|
31 | Now you are given the path of a file and you want to get the Babel config closest to that file... what a mess!
|
32 |
|
33 | Well, with this module now you can safely do:
|
34 |
|
35 | ```js
|
36 | import closestFileData from 'closest-file-data';
|
37 |
|
38 | const babelReaders = [
|
39 | // each line represents what is called a reader (see below):
|
40 | { basename: '.babelrc', read: f => JSON.parse(readFileSync(f, 'utf-8')) },
|
41 | { basename: '.babelrc.js', read: f => require(f) },
|
42 | { basename: 'package.json', read: f => require(f).babel },
|
43 | ];
|
44 |
|
45 | const config = closestFileData('/path/to/some/deep/file.js', babelReaders);
|
46 | // `config` will be either the object representing the first config data found,
|
47 | // or `undefined` if no configuration found.
|
48 | ```
|
49 |
|
50 | ## What is a `reader`?
|
51 |
|
52 | A reader is an object with 2 properties:
|
53 |
|
54 | - **`basename`**: the basename of the file for which the `read` will be called with.
|
55 | - **`read`**: a method that should return either the data read for given file, or `undefined` if the `read` should
|
56 | be considered without result (useful in the Babel case for example when there is no `babel` key in the `package.json`).
|
57 |
|
58 | The second parameter to `closestFileData()` can be a single reader or an array of readers.
|
59 | It will try a find a file with name `basename` in the given `path` (first argument of `closestFileData`) for each
|
60 | given reader, until one returns something else then `undefined`. If none, it'll go up one directory and start again,
|
61 | until it reaches the root of the filesystem.
|
62 |
|
63 | ## Is it cached?
|
64 |
|
65 | Yup, the cache is different per list of base names files in the set of readers given to `closestFileData()`.
|
66 | You can also clear the cache if needed for testing purpose:
|
67 |
|
68 | ```js
|
69 | import closestFileData from 'closest-file-data';
|
70 |
|
71 | // ...
|
72 |
|
73 | closestFileData.cache.clear();
|
74 | ```
|
75 |
|
76 | ### Installing
|
77 |
|
78 | Add to your project with `npm`:
|
79 |
|
80 | ```bash
|
81 | npm install --save closest-file-data
|
82 | ```
|
83 |
|
84 | or with `yarn`:
|
85 |
|
86 | ```bash
|
87 | yarn add closest-file-data
|
88 | ```
|
89 |
|
90 | End with an example of getting some data out of the system or using it for a little demo
|
91 |
|
92 | ## Running the tests
|
93 |
|
94 | You need to get a copy of the repository to run unit and integration tests:
|
95 |
|
96 | ```bash
|
97 | git clone https://github.com/huafu/closest-file-data.git
|
98 | cd closest-file-data
|
99 | npm run test
|
100 | ```
|
101 |
|
102 | ### There is 3 test scripts:
|
103 |
|
104 | - `test:unit`: run tests using the typescript source in `src`, useful while developing.
|
105 | - `test:dist`: run tests using the built js version in `dist`, needs to have ran `build` before.
|
106 | - `test:e2e`: run real World tests without mocking the file-system, using the built js version in `dist`. Needs to have ran `build` before.
|
107 |
|
108 | The `test` script run them all and takes care of building the sources before.
|
109 |
|
110 | ## Built With
|
111 |
|
112 | * [TypeScript](https://www.typescriptlang.org/)
|
113 |
|
114 | ## Contributing
|
115 |
|
116 | Pull requests welcome!
|
117 |
|
118 | ## Versioning
|
119 |
|
120 | We use [SemVer](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/huafu/closest-file-data/tags).
|
121 |
|
122 | ## Authors
|
123 |
|
124 | * **Huafu Gandon** - *Initial work* - [huafu](https://github.com/huafu)
|
125 |
|
126 | See also the list of [contributors](https://github.com/huafu/closest-file-data/contributors) who participated in this project.
|
127 |
|
128 | ## License
|
129 |
|
130 | This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details
|
131 |
|
132 | ## Support on Beerpay
|
133 | Hey dude! Help me out for a couple of :beers:!
|
134 |
|
135 | [![Beerpay](https://beerpay.io/huafu/closest-file-data/badge.svg?style=beer-square)](https://beerpay.io/huafu/closest-file-data) [![Beerpay](https://beerpay.io/huafu/closest-file-data/make-wish.svg?style=flat-square)](https://beerpay.io/huafu/closest-file-data?focus=wish) |
\ | No newline at end of file |