@@ -11,7 +11,7 @@ import {
1111} from "../src/internal" ;
1212// Use TS source import path (extensionless)
1313// @ts -ignore - resolved by TS during tests
14- export { } ;
14+ export { } ;
1515
1616type BundleEntry = { code ?: any ; source ?: any } ;
1717type Bundle = Record < string , BundleEntry > ;
@@ -64,7 +64,9 @@ describe("helpers", () => {
6464
6565 describe ( "getUrlAttrName" , ( ) => {
6666 it ( "returns src for script and href otherwise" , ( ) => {
67- const $s = cheerioLoad ( '<script src="/a.js"></script>' ) ( "script" ) . get ( 0 ) ;
67+ const $s = cheerioLoad ( '<script src="/a.js"></script>' ) (
68+ "script"
69+ ) . get ( 0 ) ;
6870 const $l = cheerioLoad ( '<link rel="stylesheet" href="/a.css">' ) (
6971 "link"
7072 ) . get ( 0 ) ;
@@ -95,12 +97,10 @@ describe("helpers", () => {
9597
9698 it ( "fetches remote when http and returns bytes" , async ( ) => {
9799 const bytes = new Uint8Array ( [ 1 , 2 , 3 ] ) ;
98- globalThis . fetch = vi
99- . fn ( )
100- . mockResolvedValue ( {
101- ok : true ,
102- arrayBuffer : ( ) => Promise . resolve ( bytes . buffer ) ,
103- } ) as any ;
100+ globalThis . fetch = vi . fn ( ) . mockResolvedValue ( {
101+ ok : true ,
102+ arrayBuffer : ( ) => Promise . resolve ( bytes . buffer ) ,
103+ } ) as any ;
104104 const res = await loadResource (
105105 "https://example.com/x.js" ,
106106 { } ,
@@ -112,44 +112,40 @@ describe("helpers", () => {
112112 } ) ;
113113
114114 it ( "throws on failed fetch" , async ( ) => {
115- globalThis . fetch = vi
116- . fn ( )
117- . mockResolvedValue ( {
118- ok : false ,
119- status : 404 ,
120- statusText : "Not Found" ,
121- } ) as any ;
115+ globalThis . fetch = vi . fn ( ) . mockResolvedValue ( {
116+ ok : false ,
117+ status : 404 ,
118+ statusText : "Not Found" ,
119+ } ) as any ;
122120 await expect (
123121 loadResource ( "https://example.com/404.js" , { } )
124122 ) . rejects . toThrow ( "Failed to fetch" ) ;
125123 } ) ;
126124
127125 it ( "supports protocol-relative URLs via https" , async ( ) => {
128126 const bytes = new Uint8Array ( [ 9 , 8 , 7 ] ) ;
129- const fetchSpy = vi
130- . fn ( )
131- . mockResolvedValue ( {
132- ok : true ,
133- arrayBuffer : ( ) => Promise . resolve ( bytes . buffer ) ,
134- } ) ;
127+ const fetchSpy = vi . fn ( ) . mockResolvedValue ( {
128+ ok : true ,
129+ arrayBuffer : ( ) => Promise . resolve ( bytes . buffer ) ,
130+ } ) ;
135131 globalThis . fetch = fetchSpy as any ;
136132 const res = await loadResource (
137133 "//cdn.example.com/lib.js" ,
138134 { } ,
139135 { enableCache : false }
140136 ) ;
141137 expect ( res ) . toBeInstanceOf ( Uint8Array ) ;
142- expect ( fetchSpy . mock . calls [ 0 ] [ 0 ] ) . toBe ( "https://cdn.example.com/lib.js" ) ;
138+ expect ( fetchSpy . mock . calls [ 0 ] [ 0 ] ) . toBe (
139+ "https://cdn.example.com/lib.js"
140+ ) ;
143141 } ) ;
144142
145143 it ( "caches remote fetches when enabled" , async ( ) => {
146144 const bytes = new Uint8Array ( [ 5 , 4 , 3 ] ) ;
147- const fetchSpy = vi
148- . fn ( )
149- . mockResolvedValue ( {
150- ok : true ,
151- arrayBuffer : ( ) => Promise . resolve ( bytes . buffer ) ,
152- } ) ;
145+ const fetchSpy = vi . fn ( ) . mockResolvedValue ( {
146+ ok : true ,
147+ arrayBuffer : ( ) => Promise . resolve ( bytes . buffer ) ,
148+ } ) ;
153149 globalThis . fetch = fetchSpy as any ;
154150 const cache = new Map < string , Uint8Array > ( ) ;
155151 const url = "https://example.com/once.js" ;
@@ -197,7 +193,9 @@ describe("helpers", () => {
197193 } ) ;
198194
199195 it ( "prefers source over code when code is missing" , async ( ) => {
200- const bundle = mockBundle ( { "a.js" : { source : "console.log(42)" } } ) ;
196+ const bundle = mockBundle ( {
197+ "a.js" : { source : "console.log(42)" } ,
198+ } ) ;
201199 const res = await loadResource ( "/a.js" , bundle ) ;
202200 expect ( res ) . toBe ( "console.log(42)" ) ;
203201 } ) ;
@@ -226,7 +224,11 @@ describe("helpers", () => {
226224 it ( "skips when already has integrity" , async ( ) => {
227225 const $script = $ ( "script" ) ;
228226 $script . attr ( "integrity" , "sha256-abc" ) ;
229- await processElement ( $script , mockBundle ( { "a.js" : "x" } ) , "sha256" ) ;
227+ await processElement (
228+ $script ,
229+ mockBundle ( { "a.js" : "x" } ) ,
230+ "sha256"
231+ ) ;
230232 expect ( $script . attr ( "integrity" ) ) . toBe ( "sha256-abc" ) ;
231233 } ) ;
232234
@@ -238,12 +240,22 @@ describe("helpers", () => {
238240
239241 it ( "skips when element wrapper is invalid" , async ( ) => {
240242 const fakeWrapper : any = { get : ( ) => undefined , attr : ( ) => { } } ;
241- await processElement ( fakeWrapper , mockBundle ( { "a.js" : "x" } ) , "sha256" ) ;
243+ await processElement (
244+ fakeWrapper ,
245+ mockBundle ( { "a.js" : "x" } ) ,
246+ "sha256"
247+ ) ;
242248 } ) ;
243249
244250 it ( "skips when URL attribute missing" , async ( ) => {
245- const $noHref = cheerioLoad ( '<link rel="stylesheet"></link>' ) ( "link" ) ;
246- await processElement ( $noHref , mockBundle ( { "a.css" : "x" } ) , "sha256" ) ;
251+ const $noHref = cheerioLoad ( '<link rel="stylesheet"></link>' ) (
252+ "link"
253+ ) ;
254+ await processElement (
255+ $noHref ,
256+ mockBundle ( { "a.css" : "x" } ) ,
257+ "sha256"
258+ ) ;
247259 expect ( $noHref . attr ( "integrity" ) ) . toBeUndefined ( ) ;
248260 } ) ;
249261 } ) ;
@@ -290,38 +302,65 @@ describe("helpers", () => {
290302 const bundle = mockBundle ( {
291303 "dist/assets/nested/path/app.js" : "console.log(1)" ,
292304 } ) ;
293- const out = await addSriToHtml ( html , bundle , { algorithm : "sha256" } ) ;
305+ const out = await addSriToHtml ( html , bundle , {
306+ algorithm : "sha256" ,
307+ } ) ;
294308 expect ( out ) . toContain ( 'integrity="sha256-' ) ;
295309 } ) ;
296310
297311 it ( "resolves bundle items via basename fallback" , async ( ) => {
298312 const html = `<html><head><script src="/assets/app.js"></script></head></html>` ;
299313 const bundle = mockBundle ( { "dist/app.js" : "console.log(2)" } ) ;
300- const out = await addSriToHtml ( html , bundle , { algorithm : "sha256" } ) ;
314+ const out = await addSriToHtml ( html , bundle , {
315+ algorithm : "sha256" ,
316+ } ) ;
301317 expect ( out ) . toContain ( 'integrity="sha256-' ) ;
302318 } ) ;
303319
304320 it ( "warns per element when processing fails" , async ( ) => {
305321 const realFetch = globalThis . fetch ;
306- const warnLocal = vi . spyOn ( console , "warn" ) . mockImplementation ( ( ) => { } ) ;
322+ const warnLocal = vi
323+ . spyOn ( console , "warn" )
324+ . mockImplementation ( ( ) => { } ) ;
307325 try {
308- globalThis . fetch = vi
309- . fn ( )
310- . mockResolvedValue ( {
311- ok : false ,
312- status : 500 ,
313- statusText : "ERR" ,
314- } ) as any ;
326+ globalThis . fetch = vi . fn ( ) . mockResolvedValue ( {
327+ ok : false ,
328+ status : 500 ,
329+ statusText : "ERR" ,
330+ } ) as any ;
315331 const html = `<html><head><script src=\"//cdn.example.com/a.js\"></script></head></html>` ;
316332 const out = await addSriToHtml ( html , mockBundle ( { } ) , {
317333 algorithm : "sha256" ,
318334 } ) ;
319- expect ( out ) . toContain ( '<script src="//cdn.example.com/a.js"></script>' ) ;
335+ expect ( out ) . toContain (
336+ '<script src="//cdn.example.com/a.js"></script>'
337+ ) ;
320338 expect ( warnLocal ) . toHaveBeenCalled ( ) ;
321339 } finally {
322340 globalThis . fetch = realFetch as any ;
323341 warnLocal . mockRestore ( ) ;
324342 }
325343 } ) ;
344+
345+ it ( "adds integrity to preload links for scripts and styles" , async ( ) => {
346+ const html = `<!doctype html><html><head>
347+ <link rel="preload" as="script" href="/entry.js">
348+ <link rel="preload" as="style" href="/style.css">
349+ </head></html>` ;
350+ const out = await addSriToHtml (
351+ html ,
352+ mockBundle ( {
353+ "entry.js" : "console.log(0)" ,
354+ "style.css" : "body{}" ,
355+ } ) ,
356+ { algorithm : "sha256" }
357+ ) ;
358+ expect ( out ) . toContain (
359+ '<link rel="preload" as="script" href="/entry.js" integrity="sha256-'
360+ ) ;
361+ expect ( out ) . toContain (
362+ '<link rel="preload" as="style" href="/style.css" integrity="sha256-'
363+ ) ;
364+ } ) ;
326365 } ) ;
327366} ) ;
0 commit comments