@@ -2,9 +2,11 @@ import fs from 'node:fs'
2
2
import path from 'node:path'
3
3
import crypto from 'node:crypto'
4
4
import { describe , expect , test } from 'vitest'
5
+ import { fileURLToPath } from 'mlly'
5
6
import {
6
7
asyncFlatten ,
7
8
bareImportRE ,
9
+ combineSourcemaps ,
8
10
extractHostnamesFromSubjectAltName ,
9
11
flattenId ,
10
12
generateCodeFrame ,
@@ -13,6 +15,7 @@ import {
13
15
injectQuery ,
14
16
isFileReadable ,
15
17
mergeWithDefaults ,
18
+ normalizePath ,
16
19
posToNumber ,
17
20
processSrcSetSync ,
18
21
resolveHostname ,
@@ -555,3 +558,150 @@ describe('mergeWithDefaults', () => {
555
558
expect ( actual2 . array ) . not . toBe ( defaults . array )
556
559
} )
557
560
} )
561
+
562
+ describe ( 'combineSourcemaps' , ( ) => {
563
+ const _dirname = path . dirname ( fileURLToPath ( import . meta. url ) )
564
+ const resolveFile = ( file : string ) => {
565
+ return normalizePath ( path . resolve ( _dirname , file ) )
566
+ }
567
+
568
+ test ( 'should combine sourcemaps with single sources' , ( ) => {
569
+ const sourcemaps = [
570
+ // processed with magic-string
571
+ // https://evanw.github.io/source-map-visualization/#MzQALyogY29tbWVudCAqLwpjb25zb2xlLmxvZygiZm9vIik7CjE1NgB7InZlcnNpb24iOjMsInNvdXJjZXMiOlsiL3NyYy9mb28uanMiXSwic291cmNlc0NvbnRlbnQiOlsiY29uc29sZS5sb2coXCJmb29cIik7XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQzsifQo=
572
+ {
573
+ version : 3 as const ,
574
+ mappings : ';AAAA,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;' ,
575
+ names : [ ] ,
576
+ sources : [ resolveFile ( './src/foo.js' ) ] ,
577
+ } ,
578
+ // processed with esbuild
579
+ // https://evanw.github.io/source-map-visualization/#MjAAY29uc29sZS5sb2coImZvbyIpOwoxNDgAewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiL3NyYy9mb28uanMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnNvbGUubG9nKFwiZm9vXCIpIl0sCiAgIm1hcHBpbmdzIjogIkFBQUEsUUFBUSxJQUFJLEtBQUs7IiwKICAibmFtZXMiOiBbXQp9Cg==
580
+ {
581
+ version : 3 as const ,
582
+ mappings : 'AAAA,QAAQ,IAAI,KAAK;' ,
583
+ names : [ ] ,
584
+ sources : [ resolveFile ( './src/foo.js' ) ] ,
585
+ } ,
586
+ ]
587
+ const combined = combineSourcemaps ( resolveFile ( './src/foo.js' ) , sourcemaps )
588
+ expect ( combined ) . toStrictEqual (
589
+ expect . objectContaining ( {
590
+ version : 3 ,
591
+ file : resolveFile ( './src/foo.js' ) ,
592
+ mappings : ';AAAA,QAAQ,IAAI,KAAK' ,
593
+ sources : [ resolveFile ( './src/foo.js' ) ] ,
594
+ } ) ,
595
+ )
596
+ } )
597
+
598
+ test ( 'should combine sourcemaps with multiple sources' , ( ) => {
599
+ const sourcemaps = [
600
+ // processed with magic-string
601
+ // https://evanw.github.io/source-map-visualization/#NzcALyogY29tbWVudCAqLwovLyBiLmpzCmNvbnNvbGUubG9nKCIuL2IuanMiKTsKCi8vIGEuanMKY29uc29sZS5sb2coIi4vYS5qcyIpOwozMzkAeyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9hLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIGIuanNcbmNvbnNvbGUubG9nKFwiLi9iLmpzXCIpO1xuXG4vLyBhLmpzXG5jb25zb2xlLmxvZyhcIi4vYS5qc1wiKTtcblxuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7T0FDRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7O0FBRXJCLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztPQUNFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQzs7In0K
602
+ {
603
+ version : 3 as const ,
604
+ mappings :
605
+ ';AAAA,CAAC,CAAC,CAAC,CAAC,CAAC;OACE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;;AAErB,CAAC,CAAC,CAAC,CAAC,CAAC;OACE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;;' ,
606
+ names : [ ] ,
607
+ sources : [ resolveFile ( './src/a.js' ) ] ,
608
+ } ,
609
+ // processed with esbuild
610
+ // https://evanw.github.io/source-map-visualization/#NjMALy8gYi5qcwpjb25zb2xlLmxvZygiLi9iLmpzIik7CgovLyBhLmpzCmNvbnNvbGUubG9nKCIuL2EuanMiKTsKMjIwAHsKICAidmVyc2lvbiI6IDMsCiAgInNvdXJjZXMiOiBbImIuanMiLCAiYS5qcyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiY29uc29sZS5sb2coJy4vYi5qcycpXG4iLCAiaW1wb3J0ICcuL2IuanMnXG5jb25zb2xlLmxvZygnLi9hLmpzJylcbiJdLAogICJtYXBwaW5ncyI6ICI7QUFBQSxRQUFRLElBQUksUUFBUTs7O0FDQ3BCLFFBQVEsSUFBSSxRQUFROyIsCiAgIm5hbWVzIjogW10KfQo=
611
+ {
612
+ version : 3 as const ,
613
+ mappings : ';AAAA,QAAQ,IAAI,QAAQ;;;ACCpB,QAAQ,IAAI,QAAQ;' ,
614
+ names : [ ] ,
615
+ sources : [ resolveFile ( './src/b.js' ) , resolveFile ( './src/a.js' ) ] ,
616
+ } ,
617
+ ]
618
+ const combined = combineSourcemaps ( resolveFile ( './src/a.js' ) , sourcemaps )
619
+ expect ( combined ) . toStrictEqual (
620
+ expect . objectContaining ( {
621
+ version : 3 ,
622
+ file : resolveFile ( './src/a.js' ) ,
623
+ mappings : ';;OAAA,CAAQ,IAAI,QAAQ;;;OCCpB,CAAQ,IAAI,QAAQ' ,
624
+ sources : [ resolveFile ( './src/b.js' ) , resolveFile ( './src/a.js' ) ] ,
625
+ } ) ,
626
+ )
627
+ } )
628
+
629
+ test ( 'should combine sourcemaps with multiple sources 2' , ( ) => {
630
+ const sourcemaps = [
631
+ // processed with sass
632
+ // https://evanw.github.io/source-map-visualization/#NTYALmltcG9ydGVkMiB7CiAgY29sb3I6IHJlZAp9CgouaW1wb3J0ZWQgewogIGNvbG9yOiByZWQKfQoyNzAAewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsKICAgICIvaW1wb3J0ZWQyLnNhc3MiLAogICAgIi9Gb28udnVlIgogIF0sCiAgIm5hbWVzIjogW10sCiAgIm1hcHBpbmdzIjogIkFBQUE7RUFDRTs7O0FDRUY7RUFDRSIsCiAgImZpbGUiOiAiL0Zvby52dWUiLAogICJzb3VyY2VzQ29udGVudCI6IFsKICAgICIuaW1wb3J0ZWQyXG4gIGNvbG9yOiByZWRcbiIsCiAgICAiXG5AdXNlICcuL2ltcG9ydGVkMidcblxuLmltcG9ydGVkXG4gIGNvbG9yOiByZWRcbiIKICBdCn0K
633
+ {
634
+ version : 3 as const ,
635
+ file : resolveFile ( './src/Foo.vue' ) ,
636
+ mappings : 'AAAA;EACE;;;ACEF;EACE' ,
637
+ names : [ ] ,
638
+ sources : [
639
+ resolveFile ( './src/imported2.sass' ) ,
640
+ resolveFile ( './src/Foo.vue' ) ,
641
+ ] ,
642
+ } ,
643
+ // processed with vue
644
+ // https://evanw.github.io/source-map-visualization/#NDQACkB1c2UgJy4vaW1wb3J0ZWQyJwoKLmltcG9ydGVkCiAgY29sb3I6IHJlZAo0OTQAewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsKICAgICIvRm9vLnZ1ZSIKICBdLAogICJuYW1lcyI6IFtdLAogICJtYXBwaW5ncyI6ICI7QUFNQSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDOztBQUVqQixDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7RUFDTixDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMiLAogICJmaWxlIjogIi9Gb28udnVlIiwKICAic291cmNlc0NvbnRlbnQiOiBbCiAgICAiPHRlbXBsYXRlPlxuICA8cCBjbGFzcz1cImltcG9ydGVkXCI+Zm9vPC9wPlxuICA8cCBjbGFzcz1cImltcG9ydGVkMlwiPmJhcjwvcD5cbjwvdGVtcGxhdGU+XG5cbjxzdHlsZSBsYW5nPVwic2Fzc1wiPlxuQHVzZSAnLi9pbXBvcnRlZDInXG5cbi5pbXBvcnRlZFxuICBjb2xvcjogcmVkXG48L3N0eWxlPlxuIgogIF0KfQo=
645
+ {
646
+ version : 3 as const ,
647
+ file : resolveFile ( './src/Foo.vue' ) ,
648
+ sources : [ resolveFile ( './src/Foo.vue' ) ] ,
649
+ names : [ ] ,
650
+ mappings :
651
+ ';AAMA,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;;AAEjB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACN,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC' ,
652
+ } ,
653
+ ]
654
+ const combined = combineSourcemaps ( resolveFile ( './src/Foo.vue' ) , sourcemaps )
655
+ expect ( combined ) . toStrictEqual (
656
+ expect . objectContaining ( {
657
+ version : 3 ,
658
+ file : resolveFile ( './src/Foo.vue' ) ,
659
+ mappings : 'AAAA;EACE;;;ACOF;EACE' ,
660
+ sources : [
661
+ resolveFile ( './src/imported2.sass' ) ,
662
+ resolveFile ( './src/Foo.vue' ) ,
663
+ ] ,
664
+ } ) ,
665
+ )
666
+ } )
667
+
668
+ test ( 'should combine sourcemaps with multiple sources without matched source' , ( ) => {
669
+ const sourcemaps = [
670
+ // processed with postcss
671
+ // https://evanw.github.io/source-map-visualization/#NjYALmZvbyB7CiAgb3ZlcmZsb3c6IHNjcm9sbDsKICAtd2Via2l0LW92ZXJmbG93LXNjcm9sbGluZzogdG91Y2g7Cn0KMjU1AHsKICAiZmlsZSI6ICIvc3JjL3Nhc3Mvc3R5bGUuc2FzcyIsCiAgIm1hcHBpbmdzIjogIkFBQUE7RUFDRSxnQkFBZ0I7RUNEbEIsa0NBQUE7QURFQSIsCiAgIm5hbWVzIjogW10sCiAgInNvdXJjZXMiOiBbCiAgICAiL3NyYy9zYXNzL3N0eWxlLnNhc3MiLAogICAgIlx1MDAwMDxubyBzb3VyY2U+IgogIF0sCiAgInNvdXJjZXNDb250ZW50IjogWyAiLmZvbyB7XG4gIG92ZXJmbG93OiBzY3JvbGw7XG59IiwgbnVsbCBdLAogICJ2ZXJzaW9uIjogMwp9Cg==
672
+ {
673
+ version : 3 as const ,
674
+ file : resolveFile ( './src/sass/style.sass' ) ,
675
+ mappings : 'AAAA;EACE,gBAAgB;ECDlB,kCAAA;ADEA' ,
676
+ names : [ ] ,
677
+ sources : [
678
+ resolveFile ( './src/sass/style.sass' ) ,
679
+ '\x00<no source>' , // postcss virtual file
680
+ ] ,
681
+ } ,
682
+ // processed with sass
683
+ // https://evanw.github.io/source-map-visualization/#MjkALmZvbyB7CiAgb3ZlcmZsb3c6IHNjcm9sbDsKfQoyMDcAewogICJmaWxlIjogIi9zcmMvc2Fzcy9zdHlsZS5zYXNzIiwKICAibWFwcGluZ3MiOiAiQUFBQTtFQUNFIiwKICAibmFtZXMiOiBbXSwKICAic291cmNlcyI6IFsKICAgICIvc3JjL3Nhc3MvdmVuZG9yL2luZGV4LnNjc3MiCiAgXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi5mb28ge1xuICBvdmVyZmxvdzogc2Nyb2xsO1xufVxuIl0sCiAgInZlcnNpb24iOiAzCn0K
684
+ {
685
+ version : 3 as const ,
686
+ sources : [ resolveFile ( './src/sass/vendor/index.scss' ) ] ,
687
+ names : [ ] ,
688
+ mappings : 'AAAA;EACE' ,
689
+ } ,
690
+ ]
691
+ const combined = combineSourcemaps (
692
+ resolveFile ( './src/sass/style.sass' ) ,
693
+ sourcemaps ,
694
+ )
695
+ expect ( combined ) . toStrictEqual (
696
+ expect . objectContaining ( {
697
+ version : 3 ,
698
+ file : resolveFile ( './src/sass/style.sass' ) ,
699
+ mappings : 'AAAA;EACE;ECDF' ,
700
+ sources : [
701
+ resolveFile ( './src/sass/vendor/index.scss' ) ,
702
+ '\x00<no source>' ,
703
+ ] ,
704
+ } ) ,
705
+ )
706
+ } )
707
+ } )
0 commit comments