4
4
*/
5
5
import fs from 'fs' ;
6
6
import path from 'path' ;
7
- import urlUtils from 'url' ;
7
+
8
+ import { promisify } from 'util' ;
8
9
9
10
import validateOptions from 'schema-utils' ;
10
11
import parseDataURL from 'data-urls' ;
11
12
12
13
import { SourceMapConsumer } from 'source-map' ;
14
+
13
15
import { labelToName , decode } from 'whatwg-encoding' ;
14
16
import { getOptions , urlToRequest } from 'loader-utils' ;
15
17
@@ -18,11 +20,11 @@ import {
18
20
flattenSourceMap ,
19
21
readFile ,
20
22
getContentFromSourcesContent ,
21
- isUrlRequest ,
22
23
getSourceMappingUrl ,
24
+ getRequestedUrl ,
23
25
} from './utils' ;
24
26
25
- export default function loader ( input , inputMap ) {
27
+ export default async function loader ( input , inputMap ) {
26
28
const options = getOptions ( this ) ;
27
29
28
30
validateOptions ( schema , options , {
@@ -40,99 +42,83 @@ export default function loader(input, inputMap) {
40
42
return ;
41
43
}
42
44
43
- const dataURL = parseDataURL ( url ) ;
44
-
45
45
const { context, resolve, addDependency, emitWarning } = this ;
46
+ const resolver = promisify ( resolve ) ;
46
47
47
- if ( dataURL ) {
48
- let map ;
48
+ if ( url . toLowerCase ( ) . startsWith ( 'data:' ) ) {
49
+ const dataURL = parseDataURL ( url ) ;
49
50
50
- try {
51
- dataURL . encodingName =
52
- labelToName ( dataURL . mimeType . parameters . get ( 'charset' ) ) || 'UTF-8' ;
51
+ if ( dataURL ) {
52
+ let map ;
53
53
54
- map = decode ( dataURL . body , dataURL . encodingName ) ;
55
- map = JSON . parse ( map . replace ( / ^ \) \] \} ' / , '' ) ) ;
56
- } catch ( error ) {
57
- emitWarning (
58
- `Cannot parse inline SourceMap with Charset ${ dataURL . encodingName } : ${ error } `
59
- ) ;
54
+ try {
55
+ dataURL . encodingName =
56
+ labelToName ( dataURL . mimeType . parameters . get ( 'charset' ) ) || 'UTF-8' ;
60
57
61
- callback ( null , input , inputMap ) ;
58
+ map = decode ( dataURL . body , dataURL . encodingName ) ;
59
+ map = JSON . parse ( map . replace ( / ^ \) \] \} ' / , '' ) ) ;
60
+ } catch ( error ) {
61
+ emitWarning (
62
+ `Cannot parse inline SourceMap with Charset ${ dataURL . encodingName } : ${ error } `
63
+ ) ;
62
64
63
- return ;
64
- }
65
+ callback ( null , input , inputMap ) ;
65
66
66
- processMap ( map , context , callback ) ;
67
+ return ;
68
+ }
67
69
68
- return ;
69
- }
70
+ processMap ( map , context , callback ) ;
71
+
72
+ return ;
73
+ }
70
74
71
- if ( url . toLowerCase ( ) . indexOf ( 'data:' ) === 0 ) {
72
75
emitWarning ( `Cannot parse inline SourceMap: ${ url } ` ) ;
73
76
74
77
callback ( null , input , inputMap ) ;
75
78
76
79
return ;
77
80
}
78
81
79
- if ( ! isUrlRequest ( url ) ) {
80
- const { protocol } = urlUtils . parse ( url ) ;
81
-
82
- if ( protocol !== 'file:' ) {
83
- emitWarning ( `URL scheme not supported: ${ protocol } ` ) ;
82
+ try {
83
+ url = getRequestedUrl ( url ) ;
84
+ } catch ( error ) {
85
+ emitWarning ( error . message ) ;
84
86
85
- callback ( null , input , inputMap ) ;
86
-
87
- return ;
88
- }
89
-
90
- try {
91
- url = urlUtils . fileURLToPath ( url ) ;
92
- } catch ( error ) {
93
- emitWarning ( error ) ;
94
-
95
- callback ( null , input , inputMap ) ;
87
+ callback ( null , input , inputMap ) ;
96
88
97
- return ;
98
- }
89
+ return ;
99
90
}
100
91
101
- resolve ( context , urlToRequest ( url , true ) , ( resolveError , result ) => {
102
- if ( resolveError ) {
103
- emitWarning ( `Cannot find SourceMap '${ url } ': ${ resolveError } ` ) ;
104
-
105
- callback ( null , input , inputMap ) ;
106
-
107
- return ;
108
- }
92
+ let urlResolved ;
109
93
110
- addDependency ( result ) ;
94
+ try {
95
+ urlResolved = await resolver ( context , urlToRequest ( url , true ) ) ;
96
+ } catch ( resolveError ) {
97
+ emitWarning ( `Cannot find SourceMap '${ url } ': ${ resolveError } ` ) ;
111
98
112
- fs . readFile ( result , 'utf-8' , ( readFileError , content ) => {
113
- if ( readFileError ) {
114
- emitWarning ( `Cannot open SourceMap '${ result } ': ${ readFileError } ` ) ;
99
+ callback ( null , input , inputMap ) ;
115
100
116
- callback ( null , input , inputMap ) ;
101
+ return ;
102
+ }
117
103
118
- return ;
119
- }
104
+ urlResolved = urlResolved . toString ( ) ;
105
+ addDependency ( urlResolved ) ;
120
106
121
- let map ;
107
+ const reader = promisify ( fs . readFile ) ;
108
+ const content = await reader ( urlResolved ) ;
109
+ let map ;
122
110
123
- try {
124
- map = JSON . parse ( content ) ;
125
- } catch ( e ) {
126
- emitWarning ( `Cannot parse SourceMap '${ url } ': ${ e } ` ) ;
111
+ try {
112
+ map = JSON . parse ( content . toString ( ) ) ;
113
+ } catch ( parseError ) {
114
+ emitWarning ( `Cannot parse SourceMap '${ url } ': ${ parseError } ` ) ;
127
115
128
- callback ( null , input , inputMap ) ;
116
+ callback ( null , input , inputMap ) ;
129
117
130
- return ;
131
- }
118
+ return ;
119
+ }
132
120
133
- processMap ( map , path . dirname ( result ) , callback ) ;
134
- } ) ;
135
- } ) ;
121
+ processMap ( map , path . dirname ( urlResolved ) , callback ) ;
136
122
137
123
// eslint-disable-next-line no-shadow
138
124
async function processMap ( map , context , callback ) {
@@ -163,30 +149,30 @@ export default function loader(input, inputMap) {
163
149
: readFile ( fullPath , 'utf-8' , emitWarning ) ;
164
150
}
165
151
166
- return new Promise ( ( promiseResolve ) => {
167
- resolve (
152
+ let fullPathResolved ;
153
+
154
+ try {
155
+ fullPathResolved = await resolver (
168
156
context ,
169
- urlToRequest ( fullPath , true ) ,
170
- ( resolveError , result ) => {
171
- if ( resolveError ) {
172
- emitWarning (
173
- `Cannot find source file '${ source } ': ${ resolveError } `
174
- ) ;
175
-
176
- return originalData
177
- ? promiseResolve ( {
178
- source : fullPath ,
179
- content : originalData ,
180
- } )
181
- : promiseResolve ( { source : fullPath , content : null } ) ;
157
+ urlToRequest ( fullPath , true )
158
+ ) ;
159
+ } catch ( resolveError ) {
160
+ emitWarning ( `Cannot find source file '${ source } ': ${ resolveError } ` ) ;
161
+
162
+ return originalData
163
+ ? {
164
+ source : fullPath ,
165
+ content : originalData ,
182
166
}
167
+ : { source : fullPath , content : null } ;
168
+ }
183
169
184
- return originalData
185
- ? promiseResolve ( { source : result , content : originalData } )
186
- : promiseResolve ( readFile ( result , 'utf-8' , emitWarning ) ) ;
170
+ return originalData
171
+ ? {
172
+ source : fullPathResolved ,
173
+ content : originalData ,
187
174
}
188
- ) ;
189
- } ) ;
175
+ : readFile ( fullPathResolved , 'utf-8' , emitWarning ) ;
190
176
} )
191
177
) ;
192
178
} catch ( error ) {
0 commit comments