@@ -2,9 +2,11 @@ import fs from 'node:fs'
22import path from 'node:path'
33import crypto from 'node:crypto'
44import { describe , expect , test } from 'vitest'
5+ import { fileURLToPath } from 'mlly'
56import {
67 asyncFlatten ,
78 bareImportRE ,
9+ combineSourcemaps ,
810 extractHostnamesFromSubjectAltName ,
911 flattenId ,
1012 generateCodeFrame ,
@@ -13,6 +15,7 @@ import {
1315 injectQuery ,
1416 isFileReadable ,
1517 mergeWithDefaults ,
18+ normalizePath ,
1619 posToNumber ,
1720 processSrcSetSync ,
1821 resolveHostname ,
@@ -555,3 +558,150 @@ describe('mergeWithDefaults', () => {
555558 expect ( actual2 . array ) . not . toBe ( defaults . array )
556559 } )
557560} )
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