-
Notifications
You must be signed in to change notification settings - Fork 30
/
glob-source.js
67 lines (55 loc) · 1.6 KB
/
glob-source.js
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
'use strict'
const fsp = require('fs').promises
const fs = require('fs')
const glob = require('it-glob')
const Path = require('path')
const errCode = require('err-code')
/**
* Create an async iterator that yields paths that match requested glob pattern
*
* @param {string} cwd - The directory to start matching the pattern in
* @param {string} pattern - Glob pattern to match
* @param {import('../types').GlobSourceOptions} [options] - Optional options
* @returns {AsyncGenerator<import('../types').GlobSourceResult, void, unknown>} File objects that match glob
*/
module.exports = async function * globSource (cwd, pattern, options) {
options = options || {}
if (typeof pattern !== 'string') {
throw errCode(
new Error('Pattern must be a string'),
'ERR_INVALID_PATH',
{ pattern }
)
}
if (!Path.isAbsolute(cwd)) {
cwd = Path.resolve(process.cwd(), cwd)
}
const globOptions = Object.assign({}, {
nodir: false,
realpath: false,
absolute: true,
dot: Boolean(options.hidden),
follow: options.followSymlinks != null ? options.followSymlinks : true
})
for await (const p of glob(cwd, pattern, globOptions)) {
const stat = await fsp.stat(p)
let mode = options.mode
if (options.preserveMode) {
mode = stat.mode
}
let mtime = options.mtime
if (options.preserveMtime) {
mtime = stat.mtime
}
yield {
path: toPosix(p.replace(cwd, '')),
content: stat.isFile() ? fs.createReadStream(p) : undefined,
mode,
mtime
}
}
}
/**
* @param {string} path
*/
const toPosix = path => path.replace(/\\/g, '/')