@@ -4,45 +4,65 @@ import path from 'path'
4
4
import walk from 'walk-sync'
5
5
import yaml from 'js-yaml'
6
6
import { isRegExp , setWith } from 'lodash-es'
7
- import filenameToKey from './filename-to-key.js '
7
+ import filenameToKey from './filename-to-key'
8
8
import matter from 'gray-matter'
9
9
10
- export default function dataDirectory ( dir , opts = { } ) {
11
- const defaultOpts = {
12
- preprocess : ( content ) => {
10
+ interface DataDirectoryOptions {
11
+ preprocess ?: ( content : string ) => string
12
+ ignorePatterns ?: RegExp [ ]
13
+ extensions ?: string [ ]
14
+ }
15
+
16
+ interface DataDirectoryResult {
17
+ [ key : string ] : any
18
+ }
19
+
20
+ export default function dataDirectory (
21
+ dir : string ,
22
+ opts : DataDirectoryOptions = { } ,
23
+ ) : DataDirectoryResult {
24
+ const defaultOpts : Required < DataDirectoryOptions > = {
25
+ preprocess : ( content : string ) => {
13
26
return content
14
27
} ,
15
28
ignorePatterns : [ / R E A D M E \. m d $ / i] ,
16
29
extensions : [ '.json' , '.md' , '.markdown' , '.yml' ] ,
17
30
}
18
31
19
- opts = Object . assign ( { } , defaultOpts , opts )
32
+ const mergedOpts = Object . assign ( { } , defaultOpts , opts )
20
33
21
34
// validate input
22
- assert ( Array . isArray ( opts . ignorePatterns ) )
23
- assert ( opts . ignorePatterns . every ( isRegExp ) )
24
- assert ( Array . isArray ( opts . extensions ) )
25
- assert ( opts . extensions . length )
35
+ assert ( Array . isArray ( mergedOpts . ignorePatterns ) )
36
+ assert ( mergedOpts . ignorePatterns . every ( isRegExp ) )
37
+ assert ( Array . isArray ( mergedOpts . extensions ) )
38
+ assert ( mergedOpts . extensions . length )
26
39
27
40
// start with an empty data object
28
- const data = { }
41
+ const data : DataDirectoryResult = { }
29
42
30
43
// find YAML and Markdown files in the given directory, recursively
31
- const filenames = walk ( dir , { includeBasePath : true } ) . filter ( ( filename ) => {
44
+ const filenames = walk ( dir , { includeBasePath : true } ) . filter ( ( filename : string ) => {
32
45
// ignore files that match any of ignorePatterns regexes
33
- if ( opts . ignorePatterns . some ( ( pattern ) => pattern . test ( filename ) ) ) return false
46
+ if ( mergedOpts . ignorePatterns . some ( ( pattern ) => pattern . test ( filename ) ) ) return false
34
47
35
48
// ignore files that don't have a whitelisted file extension
36
- return opts . extensions . includes ( path . extname ( filename ) . toLowerCase ( ) )
49
+ return mergedOpts . extensions . includes ( path . extname ( filename ) . toLowerCase ( ) )
37
50
} )
38
51
39
- const files = filenames . map ( ( filename ) => [ filename , fs . readFileSync ( filename , 'utf8' ) ] )
52
+ const files : [ string , string ] [ ] = filenames . map ( ( filename : string ) => [
53
+ filename ,
54
+ fs . readFileSync ( filename , 'utf8' ) ,
55
+ ] )
56
+
40
57
files . forEach ( ( [ filename , fileContent ] ) => {
41
58
// derive `foo.bar.baz` object key from `foo/bar/baz.yml` filename
42
59
const key = filenameToKey ( path . relative ( dir , filename ) )
43
60
const extension = path . extname ( filename ) . toLowerCase ( )
44
61
45
- if ( opts . preprocess ) fileContent = opts . preprocess ( fileContent )
62
+ let processedContent = fileContent
63
+ if ( mergedOpts . preprocess ) {
64
+ processedContent = mergedOpts . preprocess ( fileContent )
65
+ }
46
66
47
67
// Add this file's data to the global data object.
48
68
// Note we want to use `setWith` instead of `set` so we can customize the type during path creation.
@@ -51,17 +71,17 @@ export default function dataDirectory(dir, opts = {}) {
51
71
// See https://lodash.com/docs#set for an explanation.
52
72
switch ( extension ) {
53
73
case '.json' :
54
- setWith ( data , key , JSON . parse ( fileContent ) , Object )
74
+ setWith ( data , key , JSON . parse ( processedContent ) , Object )
55
75
break
56
76
case '.yml' :
57
- setWith ( data , key , yaml . load ( fileContent , { filename } ) , Object )
77
+ setWith ( data , key , yaml . load ( processedContent , { filename } ) , Object )
58
78
break
59
79
case '.md' :
60
80
case '.markdown' :
61
81
// Use `matter` to drop frontmatter, since localized reusable Markdown files
62
82
// can potentially have frontmatter, but we want to prevent the frontmatter
63
83
// from being rendered.
64
- setWith ( data , key , matter ( fileContent ) . content , Object )
84
+ setWith ( data , key , matter ( processedContent ) . content , Object )
65
85
break
66
86
}
67
87
} )
0 commit comments