-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathread-dir.ts
More file actions
130 lines (123 loc) · 3.82 KB
/
read-dir.ts
File metadata and controls
130 lines (123 loc) · 3.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/**
* @fileoverview Async/sync directory listing — returns directory names
* only (filtering out files), with optional emptiness suppression and
* natural-order sorting. Glob-based ignore patterns are evaluated only
* when `includeEmpty: false` triggers a per-entry emptiness probe.
*/
import { getNodeFs } from '../node/fs'
import { getNodePath } from '../node/path'
import { naturalCompare } from '../sorts/natural'
import { isDirEmptySync } from './inspect'
import type { Dirent, ObjectEncodingOptions, PathLike } from 'node:fs'
import type { ReadDirOptions } from './types'
/**
* Process directory entries and filter for directories.
* Filters entries to include only directories, optionally excluding empty ones.
* Applies ignore patterns and natural sorting.
*
* @param dirents - Directory entries from readdir
* @param dirname - Parent directory path
* @param options - Filtering and sorting options
* @returns Array of directory names, optionally sorted
*/
/*@__NO_SIDE_EFFECTS__*/
export function innerReadDirNames(
dirents: Dirent[],
dirname: string | undefined,
options?: ReadDirOptions | undefined,
): string[] {
const {
ignore,
includeEmpty = true,
sort = true,
} = { __proto__: null, ...options } as ReadDirOptions
const path = getNodePath()
const names = dirents
.filter(
(d: Dirent) =>
d.isDirectory() &&
(includeEmpty ||
!isDirEmptySync(path.join(dirname || d.parentPath, d.name), {
ignore,
})),
)
.map((d: Dirent) => d.name)
return sort ? names.sort(naturalCompare) : names
}
/**
* Read directory names asynchronously with filtering and sorting.
* Returns only directory names (not files), with optional filtering for empty directories
* and glob-based ignore patterns. Results are naturally sorted by default.
*
* @param dirname - Directory path to read
* @param options - Options for filtering and sorting
* @returns Array of directory names, empty array on error
*
* @example
* ```ts
* // Get all subdirectories, sorted naturally
* const dirs = await readDirNames('./packages')
*
* // Get non-empty directories only
* const nonEmpty = await readDirNames('./cache', { includeEmpty: false })
*
* // Get directories without sorting
* const unsorted = await readDirNames('./src', { sort: false })
* ```
*/
/*@__NO_SIDE_EFFECTS__*/
export async function readDirNames(
dirname: PathLike,
options?: ReadDirOptions | undefined,
) {
const fs = getNodeFs()
try {
return innerReadDirNames(
await fs.promises.readdir(dirname, {
__proto__: null,
encoding: 'utf8',
withFileTypes: true,
} as ObjectEncodingOptions & { withFileTypes: true }),
String(dirname),
options,
)
} catch {}
return []
}
/**
* Read directory names synchronously with filtering and sorting.
* Returns only directory names (not files), with optional filtering for empty directories
* and glob-based ignore patterns. Results are naturally sorted by default.
*
* @param dirname - Directory path to read
* @param options - Options for filtering and sorting
* @returns Array of directory names, empty array on error
*
* @example
* ```ts
* // Get all subdirectories, sorted naturally
* const dirs = readDirNamesSync('./packages')
*
* // Get non-empty directories only, ignoring node_modules
* const nonEmpty = readDirNamesSync('./src', {
* includeEmpty: false,
* ignore: ['node_modules']
* })
* ```
*/
/*@__NO_SIDE_EFFECTS__*/
export function readDirNamesSync(dirname: PathLike, options?: ReadDirOptions) {
const fs = getNodeFs()
try {
return innerReadDirNames(
fs.readdirSync(dirname, {
__proto__: null,
encoding: 'utf8',
withFileTypes: true,
} as ObjectEncodingOptions & { withFileTypes: true }),
String(dirname),
options,
)
} catch {}
return []
}