@@ -87,9 +87,23 @@ class Main {
87
87
} else {
88
88
this . #_config. addExtensions = false ;
89
89
}
90
+
91
+ if ( 'aliases' in this . #_configFile) {
92
+ const aliases = this . #_configFile. aliases ;
93
+ if ( ! utils . is . realObject ( aliases ) ) { throw new Error ( `The "aliases" option is expecting a real object, isntead got ${ typeof aliases } ` ) }
94
+
95
+ this . #_config. aliases = { }
96
+ for ( const prop in aliases ) {
97
+ if ( typeof aliases [ prop ] === 'string' ) {
98
+ this . #_config. aliases [ prop ] = aliases [ prop ] ;
99
+ } else {
100
+ throw new TypeError ( `One of the defined aliases (${ aliases [ prop ] } ) is not a string` )
101
+ }
102
+ }
103
+ }
90
104
} catch ( error ) {
91
105
if ( error instanceof Error ) {
92
- error . message = `Unable to read postbuild.this.#_configFile.json : ${ error . message } ` ;
106
+ error . message = `Unable to read postbuild configFile : ${ error . message } ` ;
93
107
}
94
108
95
109
throw error ;
@@ -263,6 +277,98 @@ class Main {
263
277
fs . writeFileSync ( fullPath , content , 'utf8' ) ;
264
278
}
265
279
} ) ;
280
+ } ,
281
+ aliases : {
282
+ regex : {
283
+ /**
284
+ * Create a regular expression for catching imports
285
+ * @param {string } pattern
286
+ * @returns {RegExp }
287
+ */
288
+ createCatch : ( pattern ) => {
289
+ const escapedPattern = pattern . replace ( / [ - \/ \\ ^ $ + ? . ( ) | [ \] { } ] / g, '\\$&' ) . replace ( / \* / g, '.*' ) ;
290
+ return new RegExp ( `^${ escapedPattern } $` )
291
+ } ,
292
+ /**
293
+ * Create a regular expression for catching imports
294
+ * @param {string } pattern
295
+ * @returns {RegExp }
296
+ */
297
+ createExact : ( pattern ) => {
298
+ const escapedPattern = pattern . replace ( / [ - \/ \\ ^ $ + ? . ( ) | [ \] { } ] / g, '\\$&' ) ;
299
+ return new RegExp ( `^${ escapedPattern } ` )
300
+ }
301
+ } ,
302
+ getPatterns : ( ) => {
303
+ const aliases = this . #_config. aliases ;
304
+ return Object . keys ( aliases ) . map ( alias => {
305
+ const catchPattern = this . #_helpers. aliases . regex . createCatch ( alias ) ;
306
+ const exactPattern = this . #_helpers. aliases . regex . createExact ( alias ) ;
307
+
308
+ return {
309
+ alias,
310
+ catchPattern,
311
+ exactPattern,
312
+ resolvedPath : aliases [ alias ]
313
+ } ;
314
+ } ) ;
315
+ } ,
316
+ matchImportPath : ( importPath , aliasPatterns ) => {
317
+ for ( const { catchPattern, exactPattern, resolvedPath } of aliasPatterns ) {
318
+ // Check if the import path starts with the alias pattern
319
+ const match = importPath . match ( catchPattern ) ;
320
+ if ( match ) {
321
+ const newMatch = match [ 0 ] . replace ( exactPattern , resolvedPath )
322
+ const newImportPath = importPath . replace ( match [ 0 ] , newMatch ) ;
323
+
324
+ // Construct the new path by combining the resolved path with the remaining path
325
+ return importPath . replace ( match , newImportPath )
326
+ }
327
+ }
328
+
329
+ return importPath ; // No match found
330
+ } ,
331
+ replaceImports : ( filePath , aliasPatterns ) => {
332
+ let fileContent = fs . readFileSync ( filePath , 'utf8' ) ;
333
+
334
+ // Replace import paths based on alias patterns
335
+ fileContent = fileContent . replace ( / f r o m [ ' " ] ( [ ^ ' " ] + ) [ ' " ] / g, ( match , importPath ) => {
336
+ // Match the import path against alias patterns
337
+ const resolvedPath = this . #_helpers. aliases . matchImportPath ( importPath , aliasPatterns ) ;
338
+
339
+ // Only replace if the alias was matched, else return the original import path
340
+ if ( resolvedPath !== importPath ) {
341
+ // Preserve the specific path segments after the alias
342
+ const remainingPath = importPath . replace ( / ^ .* \/ [ ^ \/ ] + / , '' ) ; // Strip alias part
343
+ return `from '${ resolvedPath } ${ remainingPath } ${ remainingPath . endsWith ( '.js' ) ? '' : '.js' } '` ;
344
+ }
345
+
346
+ return match ; // No change if alias was not matched
347
+ } ) ;
348
+
349
+ fs . writeFileSync ( filePath , fileContent , 'utf8' ) ;
350
+ } ,
351
+ processFiles : ( directory , aliasPatterns ) => {
352
+ fs . readdirSync ( directory ) . forEach ( file => {
353
+ const fullPath = path . join ( directory , file ) ;
354
+
355
+ if ( fs . lstatSync ( fullPath ) . isDirectory ( ) ) {
356
+ this . #_helpers. aliases . processFiles ( fullPath , aliasPatterns ) ;
357
+ } else if ( file . endsWith ( '.js' ) ) {
358
+ this . #_helpers. aliases . replaceImports ( fullPath , aliasPatterns ) ;
359
+ }
360
+ } ) ;
361
+ } ,
362
+ check : ( ) => {
363
+ const aliasPatterns = this . #_helpers. aliases . getPatterns ( ) ;
364
+ if ( this . #_config. esmDir ) {
365
+ this . #_helpers. aliases . processFiles ( this . #_config. esmDir , aliasPatterns ) ;
366
+ }
367
+
368
+ if ( this . #_config. cjsDir ) {
369
+ this . #_helpers. aliases . processFiles ( this . #_config. cjsDir , aliasPatterns ) ;
370
+ }
371
+ }
266
372
}
267
373
}
268
374
@@ -274,10 +380,11 @@ class Main {
274
380
this . #_helpers. create . packages ( ) ;
275
381
this . #_helpers. copy . run ( ) ;
276
382
this . #_helpers. extensions . run ( ) ;
383
+ this . #_helpers. aliases . check ( ) ;
277
384
278
385
const et = Date . now ( ) ;
279
386
const duration = et - st ;
280
- this . #_helpers. print ( `PostBuild finishes in ${ duration } milliseconds` ) ;
387
+ this . #_helpers. print ( `PostBuild finished in ${ duration } milliseconds` ) ;
281
388
}
282
389
}
283
390
0 commit comments