@@ -12,6 +12,13 @@ import pico from 'picomatch';
12
12
* @param {string } modulePath file path prefixed with the module name, not CWD
13
13
*/
14
14
export function importMetaGlob ( glob , options , modulePath ) {
15
+ let ARITY_3 = arguments . length === 3 ;
16
+
17
+ if ( typeof options === 'string' ) {
18
+ modulePath = options ;
19
+ options = null ;
20
+ }
21
+
15
22
assert (
16
23
`The first argument to import.meta.glob must be a string` ,
17
24
typeof glob === 'string' ,
@@ -20,14 +27,18 @@ export function importMetaGlob(glob, options, modulePath) {
20
27
`The glob pattern must be a relative path starting with either ./ or ../. Received: ${ glob } ` ,
21
28
glob . startsWith ( './' ) || glob . startsWith ( '../' ) ,
22
29
) ;
23
- assert (
24
- `the second argument to import.meta.glob must be an object` ,
25
- typeof options === 'object' ,
26
- ) ;
27
- assert (
28
- `the only supported option is 'eager'. Received: ${ Object . keys ( options ) } ` ,
29
- Object . keys ( options ) . length === 1 && 'eager' in options ,
30
- ) ;
30
+
31
+ if ( ARITY_3 ) {
32
+ assert (
33
+ `the second argument to import.meta.glob must be an object. Received: ${ typeof options } ` ,
34
+ typeof options === 'object' ,
35
+ ) ;
36
+ assert (
37
+ `the only supported option is 'eager'. Received: ${ Object . keys ( options ) } ` ,
38
+ Object . keys ( options ) . length === 1 && 'eager' in options ,
39
+ ) ;
40
+ }
41
+
31
42
assert (
32
43
`the third argument to import.meta.glob must be passed and be the module path. This is filled in automatically via the babel plugin. If you're seeing this something has gone wrong with installing the babel plugin` ,
33
44
modulePath ,
@@ -48,6 +59,12 @@ export function importMetaGlob(glob, options, modulePath) {
48
59
let [ , ...reversedParts ] = modulePath . split ( '/' ) . reverse ( ) ;
49
60
let currentDir = reversedParts . reverse ( ) . join ( '/' ) ;
50
61
62
+ console . log ( { glob, currentDir, modulePath } ) ;
63
+ assert (
64
+ `not a valid path. Received: '${ currentDir } ' from '${ modulePath } '` ,
65
+ currentDir . length > 0 ,
66
+ ) ;
67
+
51
68
// TODO: drop the extensions, since at runtime, we don't have them.
52
69
let globsArray = Array . isArray ( glob ) ? glob : [ glob ] ;
53
70
let fullGlobs = globsArray . map ( ( g ) => {
@@ -56,18 +73,50 @@ export function importMetaGlob(glob, options, modulePath) {
56
73
let isMatch = pico ( fullGlobs ) ;
57
74
let matches = allModules . filter ( isMatch ) ;
58
75
59
- console . log ( { fullGlobs , matches , currentDir } ) ;
76
+ let hasInvalid = fullGlobs . some ( isEscapingApp ) ;
60
77
61
- // TODO: assert: cannot escape the app.
62
- // (too many ../../../../)
78
+ assert (
79
+ `Cannot have a path that escapes the app. Received: ${ glob } ` ,
80
+ ! hasInvalid ,
81
+ ) ;
63
82
64
83
let result = { } ;
65
84
66
85
for ( let match of matches ) {
67
86
let key = match . replace ( `${ currentDir } /` , './' ) ;
68
87
69
- result [ key ] = requirejs ( match ) ;
88
+ if ( options ?. eager ) {
89
+ result [ key ] = requirejs ( match ) ;
90
+ } else {
91
+ // TODO: can we usue a real import if we use app-imports
92
+ // from ember-auto-import?
93
+ result [ key ] = ( ) => Promise . resolve ( requirejs ( match ) ) ;
94
+ }
70
95
}
71
96
72
97
return result ;
73
98
}
99
+
100
+ function isEscapingApp ( path ) {
101
+ let parts = path . split ( '/' ) ;
102
+
103
+ let preUpCount = 0 ;
104
+ let upCount = 0 ;
105
+
106
+ for ( let part of parts ) {
107
+ if ( part === '..' ) {
108
+ upCount ++ ;
109
+ continue ;
110
+ }
111
+
112
+ if ( upCount > 0 ) {
113
+ break ;
114
+ }
115
+
116
+ if ( part !== '..' ) {
117
+ preUpCount ++ ;
118
+ }
119
+ }
120
+
121
+ return upCount >= preUpCount ;
122
+ }
0 commit comments