16
16
* @callback FieldProcessor
17
17
* @param {string } request request
18
18
* @param {Set<string> } conditionNames condition names
19
- * @returns {string[] } resolved paths
19
+ * @returns {[ string[], string | null] } resolved paths with used field
20
20
*/
21
21
22
22
/*
@@ -72,6 +72,7 @@ Conditional mapping nested in another conditional mapping is called nested mappi
72
72
73
73
*/
74
74
75
+ const { parseIdentifier } = require ( "./identifier" ) ;
75
76
const slashCode = "/" . charCodeAt ( 0 ) ;
76
77
const dotCode = "." . charCodeAt ( 0 ) ;
77
78
const hashCode = "#" . charCodeAt ( 0 ) ;
@@ -100,7 +101,7 @@ module.exports.processImportsField = function processImportsField(
100
101
importsField
101
102
) {
102
103
return createFieldProcessor (
103
- buildImportsField ( importsField ) ,
104
+ importsField ,
104
105
request => "#" + request ,
105
106
assertImportsFieldRequest ,
106
107
assertImportTarget
@@ -125,9 +126,10 @@ function createFieldProcessor(
125
126
126
127
const match = findMatch ( normalizeRequest ( request ) , field ) ;
127
128
128
- if ( match === null ) return [ ] ;
129
+ if ( match === null ) return [ [ ] , null ] ;
129
130
130
- const [ mapping , remainingRequest , isSubpathMapping , isPattern ] = match ;
131
+ const [ mapping , remainingRequest , isSubpathMapping , isPattern , usedField ] =
132
+ match ;
131
133
132
134
/** @type {DirectMapping|null } */
133
135
let direct = null ;
@@ -139,19 +141,22 @@ function createFieldProcessor(
139
141
) ;
140
142
141
143
// matching not found
142
- if ( direct === null ) return [ ] ;
144
+ if ( direct === null ) return [ [ ] , null ] ;
143
145
} else {
144
146
direct = /** @type {DirectMapping } */ ( mapping ) ;
145
147
}
146
148
147
- return directMapping (
148
- remainingRequest ,
149
- isPattern ,
150
- isSubpathMapping ,
151
- direct ,
152
- conditionNames ,
153
- assertTarget
154
- ) ;
149
+ return [
150
+ directMapping (
151
+ remainingRequest ,
152
+ isPattern ,
153
+ isSubpathMapping ,
154
+ direct ,
155
+ conditionNames ,
156
+ assertTarget
157
+ ) ,
158
+ usedField
159
+ ] ;
155
160
} ;
156
161
}
157
162
@@ -200,18 +205,15 @@ function assertImportsFieldRequest(request) {
200
205
* @param {boolean } expectFolder is folder expected
201
206
*/
202
207
function assertExportTarget ( exp , expectFolder ) {
203
- if (
204
- exp . charCodeAt ( 0 ) === slashCode ||
205
- ( exp . charCodeAt ( 0 ) === dotCode && exp . charCodeAt ( 1 ) !== slashCode )
206
- ) {
207
- throw new Error (
208
- `Export should be relative path and start with "./", got ${ JSON . stringify (
209
- exp
210
- ) } .`
211
- ) ;
208
+ const parsedIdentifier = parseIdentifier ( exp ) ;
209
+
210
+ if ( ! parsedIdentifier ) {
211
+ return ;
212
212
}
213
213
214
- const isFolder = exp . charCodeAt ( exp . length - 1 ) === slashCode ;
214
+ const [ relativePath ] = parsedIdentifier ;
215
+ const isFolder =
216
+ relativePath . charCodeAt ( relativePath . length - 1 ) === slashCode ;
215
217
216
218
if ( isFolder !== expectFolder ) {
217
219
throw new Error (
@@ -231,7 +233,15 @@ function assertExportTarget(exp, expectFolder) {
231
233
* @param {boolean } expectFolder is folder expected
232
234
*/
233
235
function assertImportTarget ( imp , expectFolder ) {
234
- const isFolder = imp . charCodeAt ( imp . length - 1 ) === slashCode ;
236
+ const parsedIdentifier = parseIdentifier ( imp ) ;
237
+
238
+ if ( ! parsedIdentifier ) {
239
+ return ;
240
+ }
241
+
242
+ const [ relativePath ] = parsedIdentifier ;
243
+ const isFolder =
244
+ relativePath . charCodeAt ( relativePath . length - 1 ) === slashCode ;
235
245
236
246
if ( isFolder !== expectFolder ) {
237
247
throw new Error (
@@ -271,7 +281,7 @@ function patternKeyCompare(a, b) {
271
281
* Trying to match request to field
272
282
* @param {string } request request
273
283
* @param {ExportsField | ImportsField } field exports or import field
274
- * @returns {[MappingValue, string, boolean, boolean]|null } match or null, number is negative and one less when it's a folder mapping, number is request.length + 1 for direct mappings
284
+ * @returns {[MappingValue, string, boolean, boolean, string ]|null } match or null, number is negative and one less when it's a folder mapping, number is request.length + 1 for direct mappings
275
285
*/
276
286
function findMatch ( request , field ) {
277
287
if (
@@ -281,7 +291,7 @@ function findMatch(request, field) {
281
291
) {
282
292
const target = /** @type {{[k: string]: MappingValue} } */ ( field ) [ request ] ;
283
293
284
- return [ target , "" , false , false ] ;
294
+ return [ target , "" , false , false , request ] ;
285
295
}
286
296
287
297
/** @type {string } */
@@ -332,7 +342,8 @@ function findMatch(request, field) {
332
342
target ,
333
343
/** @type {string } */ ( bestMatchSubpath ) ,
334
344
isSubpathMapping ,
335
- isPattern
345
+ isPattern ,
346
+ bestMatch
336
347
] ;
337
348
}
338
349
@@ -560,39 +571,3 @@ function buildExportsField(field) {
560
571
561
572
return field ;
562
573
}
563
-
564
- /**
565
- * @param {ImportsField } field imports field
566
- * @returns {ImportsField } normalized imports field
567
- */
568
- function buildImportsField ( field ) {
569
- const keys = Object . keys ( field ) ;
570
-
571
- for ( let i = 0 ; i < keys . length ; i ++ ) {
572
- const key = keys [ i ] ;
573
-
574
- if ( key . charCodeAt ( 0 ) !== hashCode ) {
575
- throw new Error (
576
- `Imports field key should start with "#" (key: ${ JSON . stringify ( key ) } )`
577
- ) ;
578
- }
579
-
580
- if ( key . length === 1 ) {
581
- throw new Error (
582
- `Imports field key should have at least 2 characters (key: ${ JSON . stringify (
583
- key
584
- ) } )`
585
- ) ;
586
- }
587
-
588
- if ( key . charCodeAt ( 1 ) === slashCode ) {
589
- throw new Error (
590
- `Imports field key should not start with "#/" (key: ${ JSON . stringify (
591
- key
592
- ) } )`
593
- ) ;
594
- }
595
- }
596
-
597
- return field ;
598
- }
0 commit comments