Skip to content

Commit 9400369

Browse files
committed
Fix types
BREAKING CHANGE: Property set up types and publishing lifecycle
1 parent edaaed0 commit 9400369

File tree

7 files changed

+152
-194
lines changed

7 files changed

+152
-194
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
11
node_modules
22
sandbox.js
33
.nyc_output
4+
.tap
5+
6+
# Generated types
7+
*.d.ts
8+
*.d.ts.map

declaration.tsconfig.json

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
{
2-
"extends": "./tsconfig",
3-
"exclude": [
4-
"test.js"
5-
],
2+
"extends": "./tsconfig.json",
63
"compilerOptions": {
74
"declaration": true,
5+
"declarationMap": true,
86
"noEmit": false,
97
"emitDeclarationOnly": true
108
}

index.d.ts

Lines changed: 0 additions & 106 deletions
This file was deleted.

index.js

Lines changed: 85 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
// @ts-check
22

3+
/**
4+
* @typedef {import('fs').Stats} Stats
5+
*/
6+
37
'use strict'
48

59
const fs = require('fs')
@@ -9,93 +13,108 @@ const ignore = require('ignore')
913
const { readdir, lstat } = fs.promises
1014

1115
/**
12-
* pathFilter lets you filter files based on a resolved `filepath`.
13-
* @callback pathFilter
14-
* @param {String} filepath - The resolved `filepath` of the file to test for filtering.
16+
* PathFilter lets you filter files based on a resolved `filepath`.
17+
* @callback PathFilter
18+
* @param {string} filepath - The resolved `filepath` of the file to test for filtering.
1519
*
16-
* @return {Boolean} Return false to filter the given `filepath` and true to include it.
20+
* @return {boolean} Return false to filter the given `filepath` and true to include it.
21+
*/
22+
23+
/**
24+
* @type PathFilter
1725
*/
18-
const pathFilter = filepath => true
26+
const pathFilter = (/* filepath */) => true
1927

2028
/**
2129
* statFilter lets you filter files based on a lstat object.
22-
* @callback statFilter
23-
* @param {Object} st - A fs.Stats instance.
30+
* @callback StatFilter
31+
* @param {Stats} st - A fs.Stats instance.
2432
*
25-
* @return {Boolean} Return false to filter the given `filepath` and true to include it.
33+
* @return {boolean} Return false to filter the given `filepath` and true to include it.
2634
*/
27-
const statFilter = st => true
35+
36+
/**
37+
* @type StatFilter
38+
*/
39+
const statFilter = (/* st */) => true
2840

2941
/**
3042
* FWStats is the object that the okdistribute/folder-walker module returns by default.
3143
*
3244
* @typedef FWStats
33-
* @property {String} root - The filepath of the directory where the walk started.
34-
* @property {String} filepath - The resolved filepath.
35-
* @property {Object} stat - A fs.Stats instance.
36-
* @property {String} relname - The relative path to `root`.
37-
* @property {String} basename - The resolved filepath of the files containing directory.
45+
* @property {string} root - The filepath of the directory where the walk started.
46+
* @property {string} filepath - The resolved assolute path.
47+
* @property {Stats} stat - A fs.Stats instance.
48+
* @property {string} relname - The relative path to `root`.
49+
* @property {string} basename - The resolved filepath of the files containing directory.
3850
*/
3951

4052
/**
41-
* shaper lets you change the shape of the returned file data from walk-time stats.
42-
* @callback shaper
53+
* Shaper lets you change the shape of the returned file data from walk-time stats.
54+
* @template T
55+
* @callback Shaper
4356
* @param {FWStats} fwStats - The same status object returned from folder-walker.
4457
*
45-
* @return {*} - Whatever you want returned from the directory walk.
58+
* @return {T} - Whatever you want returned from the directory walk.
59+
*/
60+
61+
/**
62+
* @type {Shaper<string>}
4663
*/
47-
const shaper = ({ root, filepath, stat, relname, basename }) => filepath
64+
const shaper = ({ filepath/*, root, stat, relname, basename */ }) => filepath
4865

4966
/**
50-
* Options object
67+
* Options object.
5168
*
52-
* @typedef Opts
53-
* @property {pathFilter} [pathFilter] - A pathFilter cb.
54-
* @property {statFilter} [statFilter] - A statFilter cb.
55-
* @property {String[]} [ignore] - An array of .gitignore style strings of files to ignore.
56-
* @property {Number} [maxDepth=Infinity] - The maximum number of folders to walk down into.
57-
* @property {shaper} [shaper] - A shaper cb.
69+
* @template T
70+
* @typedef {object} AFWOpts
71+
* @property {PathFilter} pathFilter=pathFilter - A pathFilter callback.
72+
* @property {StatFilter} statFilter=statFilter - A statFilter callback.
73+
* @property {string[]} ignore=[] - An array of .gitignore style strings of files to ignore.
74+
* @property {number} maxDepth=Infinity - The maximum number of folders to walk down into.
75+
* @property {Shaper<T>} shaper=shaper - A shaper callback.
5876
*/
5977

6078
/**
6179
* Create an async generator that iterates over all folders and directories inside of `dirs`.
6280
*
63-
* @async
64-
* @generator
65-
* @function
81+
* @template T
6682
* @public
67-
* @param {String|String[]} dirs - The path of the directory to walk, or an array of directory paths.
68-
* @param {?(Opts)} opts - Options used for the directory walk.
69-
*
70-
* @yields {Promise<String|any>} - An async iterator that returns anything.
83+
* @param {string|string[]} dirs - The path or paths of the directory to walk.
84+
* @param {?Partial<AFWOpts<T>>} [opts] - Options used for the directory walk.
85+
* @yields {T} - An iterator that returns a value of type T.
7186
*/
7287
async function * asyncFolderWalker (dirs, opts) {
73-
opts = Object.assign({
88+
/** @type {AFWOpts<T>} */
89+
const resolvedOpts = Object.assign({
7490
fs,
7591
pathFilter,
7692
statFilter,
77-
ignore,
93+
ignore: [],
7894
maxDepth: Infinity,
7995
shaper
8096
}, opts)
8197

8298
// @ts-ignore
83-
const ig = ignore().add(opts.ignore)
99+
const ig = ignore().add(resolvedOpts.ignore)
84100

85-
const roots = [dirs].flat().filter(opts.pathFilter)
101+
const roots = [dirs].flat().filter(resolvedOpts.pathFilter)
86102
const pending = []
87103

88104
while (roots.length) {
89105
const root = roots.shift()
106+
if (!root) continue // Handle potential undefined value
90107
pending.push(root)
108+
91109
while (pending.length) {
92110
const current = pending.shift()
93-
if (typeof current === 'undefined') continue
111+
if (!current) continue // Handle potential undefined value
112+
94113
const st = await lstat(current)
95114
const rel = relname(root, current)
96115
if (ig.ignores(st.isDirectory() ? rel + '/' : rel)) continue
97-
if ((!st.isDirectory() || depthLimiter(current, root, opts.maxDepth)) && opts.statFilter(st)) {
98-
yield opts.shaper(fwShape(root, current, st))
116+
if ((!st.isDirectory() || depthLimiter(current, root, resolvedOpts.maxDepth)) && resolvedOpts.statFilter(st)) {
117+
yield resolvedOpts.shaper(fwShape(root, current, st))
99118
continue
100119
}
101120

@@ -104,32 +123,34 @@ async function * asyncFolderWalker (dirs, opts) {
104123

105124
for (const file of files) {
106125
const next = path.join(current, file)
107-
if (opts.pathFilter(next)) pending.unshift(next)
126+
if (resolvedOpts.pathFilter(next)) pending.unshift(next)
108127
}
109-
if (current === root || !opts.statFilter(st)) continue
110-
else yield opts.shaper(fwShape(root, current, st))
128+
if (current === root || !resolvedOpts.statFilter(st)) continue
129+
else yield resolvedOpts.shaper(fwShape(root, current, st))
111130
}
112131
}
113132
}
114133

134+
/**
135+
* @param {string} root
136+
* @param {string} name
137+
* @return {string} The basename or relative name if root === name
138+
*/
115139
function relname (root, name) {
116140
return root === name ? path.basename(name) : path.relative(root, name)
117141
}
118142

119143
/**
120144
* Generates the same shape as the folder-walker module.
121145
*
122-
* @function
123-
* @private
124-
* @param {String} root - Root filepath.
125-
* @param {String} name - Target filepath.
126-
* @param {Object} st - fs.Stat object.
127-
*
128-
* @return {FWStats} - Folder walker object.
146+
* @param {string} root - Root filepath.
147+
* @param {string} name - Target filepath.
148+
* @param {Stats} st - fs.Stat object.
149+
* @returns {FWStats} Folder walker object.
129150
*/
130151
function fwShape (root, name, st) {
131152
return {
132-
root: root,
153+
root,
133154
filepath: name,
134155
stat: st,
135156
relname: relname(root, name),
@@ -140,13 +161,10 @@ function fwShape (root, name, st) {
140161
/**
141162
* Test if we are at maximum directory depth.
142163
*
143-
* @private
144-
* @function
145-
* @param {String} filePath - The resolved path of the target fille.
146-
* @param {String} relativeTo - The root directory of the current walk.
147-
* @param {Number} maxDepth - The maximum number of folders to descend into.
148-
*
149-
* @returns {Boolean} - Return true to signal stop descending.
164+
* @param {string} filePath - The resolved path of the target file.
165+
* @param {string} relativeTo - The root directory of the current walk.
166+
* @param {number} maxDepth - The maximum number of folders to descend into.
167+
* @returns {boolean} Return true to signal stop descending.
150168
*/
151169
function depthLimiter (filePath, relativeTo, maxDepth) {
152170
if (maxDepth === Infinity) return false
@@ -156,17 +174,16 @@ function depthLimiter (filePath, relativeTo, maxDepth) {
156174
}
157175

158176
/**
159-
* Async iterable collector
177+
* Async iterable collector.
160178
*
161-
* @async
162-
* @function
163-
* @private
164-
* @param {AsyncIterator} iterator - The iterator to collect into an array
179+
* @template T
180+
* @public
181+
* @param {AsyncIterableIterator<T>} iterator - The iterator to collect into an array.
182+
* @returns {Promise<T[]>} Array of items collected from the iterator.
165183
*/
166184
async function all (iterator) {
167185
const collect = []
168186

169-
// @ts-ignore
170187
for await (const result of iterator) {
171188
collect.push(result)
172189
}
@@ -175,15 +192,13 @@ async function all (iterator) {
175192
}
176193

177194
/**
178-
* allFiles gives you all files from the directory walk as an array.
195+
* Gives you all files from the directory walk as an array.
179196
*
180-
* @async
181-
* @function
197+
* @template T
182198
* @public
183-
* @param {String|String[]} dirs - The path of the directory to walk, or an array of directory paths.
184-
* @param {?(Opts)} opts - Options used for the directory walk.
185-
*
186-
* @returns {Promise<String[]|any>} - An async iterator that returns anything.
199+
* @param {string|string[]} dirs - The path of the directory to walk, or an array of directory paths.
200+
* @param {Partial<AFWOpts<T>>} [opts] - Options used for the directory walk.
201+
* @returns {Promise<T[]>} Array of files or any other result from the directory walk.
187202
*/
188203
async function allFiles (dirs, opts) {
189204
return all(asyncFolderWalker(dirs, opts))

0 commit comments

Comments
 (0)