@@ -62,9 +62,14 @@ function normalizeLiteralPayload(value: string): string {
6262}
6363
6464function wrapWithQuote ( q : string , s : string ) : string {
65- // Escape occurrences of the outer quote inside the string
66- const escaped = q === "'" ? s . replace ( / ' / g, "\\'" ) : s . replace ( / " / g, '\\"' )
67- return `${ q } ${ escaped } ${ q } `
65+ // Produce a JS string literal safely using JSON.stringify, preserving the requested quote.
66+ const json = JSON . stringify ( String ( s ) )
67+ const wantsSingle = q === "'"
68+
69+ if ( ! wantsSingle ) return json
70+
71+ const inner = json . slice ( 1 , - 1 ) . replace ( / ' / g, "\\'" )
72+ return `'${ inner } '`
6873}
6974
7075function isLikelyApiContextAt (
@@ -811,11 +816,14 @@ export default async function resolvePathsLoader(this: any, source: string) {
811816 const q = ( isQuote ( before ) ? before : after ) as "'" | '"'
812817 const start = isQuote ( before ) ? span . start - 1 : span . start
813818 const end = isQuote ( after ) ? span . end + 1 : span . end
814- const escaped =
815- q === "'"
816- ? String ( computed ) . replace ( / ' / g, "\\'" )
817- : String ( computed ) . replace ( / " / g, '\\"' )
818- ms . overwrite ( start , end , `${ q } ${ escaped } ${ q } ` )
819+ // Use JSON-based quoting to ensure correct escaping of control chars and slashes
820+ const json = JSON . stringify ( String ( computed ) )
821+ if ( q === '"' ) {
822+ ms . overwrite ( start , end , json )
823+ } else {
824+ const inner = json . slice ( 1 , - 1 ) . replace ( / ' / g, "\\'" )
825+ ms . overwrite ( start , end , `'${ inner } '` )
826+ }
819827 } else {
820828 // Fallback to JSON string if we cannot safely detect surrounding quotes
821829 ms . overwrite ( span . start , span . end , JSON . stringify ( computed ) )
0 commit comments