@@ -5,11 +5,13 @@ import type * as childProcess from 'node:child_process';
55import { beforeEach , describe , expect , it , vi } from 'vitest' ;
66import {
77 startersData ,
8+ createStarterCDNUrl ,
89 createGitInitProcess ,
910 createStarterPaths ,
1011 execPackageManager ,
1112 getDependencyInstallFailureMessage ,
1213 getRequiredNPMClient ,
14+ stampStarterCDNVersions ,
1315 removeWireitScripts ,
1416 startStarter
1517} from './starters.js' ;
@@ -48,6 +50,7 @@ describe('startersData', () => {
4850 expect ( startersData . nextjs . cli ) . toBe ( true ) ;
4951 expect ( startersData . solidjs . cli ) . toBe ( true ) ;
5052 expect ( startersData . go . cli ) . toBe ( true ) ;
53+ expect ( startersData [ 'go-htmx' ] . cli ) . toBe ( true ) ;
5154 expect ( startersData . hugo . cli ) . toBe ( true ) ;
5255 expect ( startersData . eleventy . cli ) . toBe ( true ) ;
5356 expect ( startersData . bundles . cli ) . toBe ( true ) ;
@@ -66,6 +69,7 @@ describe('startersData', () => {
6669 expect ( startersData . nextjs . zip ) . toContain ( 'nextjs.zip' ) ;
6770 expect ( startersData . solidjs . zip ) . toContain ( 'solidjs.zip' ) ;
6871 expect ( startersData . go . zip ) . toContain ( 'go.zip' ) ;
72+ expect ( startersData [ 'go-htmx' ] . zip ) . toContain ( 'go-htmx.zip' ) ;
6973 expect ( startersData . eleventy . zip ) . toContain ( 'eleventy.zip' ) ;
7074 expect ( startersData . importmaps . zip ) . toContain ( 'importmaps.zip' ) ;
7175 expect ( startersData . bundles . zip ) . toContain ( 'bundles.zip' ) ;
@@ -198,6 +202,96 @@ describe('getDependencyInstallFailureMessage', () => {
198202 } ) ;
199203} ) ;
200204
205+ describe ( 'starter CDN URLs' , ( ) => {
206+ type StarterCDNPackageName = Parameters < typeof createStarterCDNUrl > [ 0 ] ;
207+ type StarterCDNAsset = { packageName : StarterCDNPackageName ; filePath : string } ;
208+
209+ const versions : Record < StarterCDNPackageName , string > = {
210+ '@nvidia-elements/core' : '1.2.3' ,
211+ '@nvidia-elements/styles' : '4.5.6' ,
212+ '@nvidia-elements/themes' : '7.8.9'
213+ } ;
214+
215+ const coreAsset : StarterCDNAsset = { packageName : '@nvidia-elements/core' , filePath : 'dist/bundles/index.min.js' } ;
216+ const stylesAsset : StarterCDNAsset = { packageName : '@nvidia-elements/styles' , filePath : 'dist/bundles/index.css' } ;
217+ const themesAsset : StarterCDNAsset = { packageName : '@nvidia-elements/themes' , filePath : 'dist/bundles/index.css' } ;
218+ const themeFontsAsset : StarterCDNAsset = { packageName : '@nvidia-elements/themes' , filePath : 'dist/fonts/inter.css' } ;
219+ const starterCDNAssets = [ stylesAsset , themesAsset , themeFontsAsset , coreAsset ] ;
220+
221+ function createVersionedStarterCDNUrl ( asset : StarterCDNAsset , version = versions [ asset . packageName ] ) {
222+ return createStarterCDNUrl ( asset . packageName , version , asset . filePath ) ;
223+ }
224+
225+ function createUnversionedStarterCDNUrl ( asset : StarterCDNAsset ) {
226+ return createVersionedStarterCDNUrl ( asset ) . replace (
227+ `${ asset . packageName } @${ versions [ asset . packageName ] } ` ,
228+ asset . packageName
229+ ) ;
230+ }
231+
232+ it ( 'should create versioned CDN URLs' , ( ) => {
233+ const url = createVersionedStarterCDNUrl ( coreAsset ) ;
234+
235+ expect ( new URL ( url ) . protocol ) . toBe ( 'https:' ) ;
236+ expect ( url ) . toContain ( `${ coreAsset . packageName } @${ versions [ coreAsset . packageName ] } /${ coreAsset . filePath } ` ) ;
237+ } ) ;
238+
239+ it ( 'should stamp unversioned Elements CDN URLs with package versions' , ( ) => {
240+ const content = `
241+ <link rel="stylesheet" href="${ createUnversionedStarterCDNUrl ( stylesAsset ) } " />
242+ <link rel="stylesheet" href="${ createUnversionedStarterCDNUrl ( themesAsset ) } " />
243+ <link rel="stylesheet" href="${ createUnversionedStarterCDNUrl ( themeFontsAsset ) } " />
244+ <script type="module">
245+ import '${ createUnversionedStarterCDNUrl ( coreAsset ) } ';
246+ </script>
247+ ` ;
248+
249+ const result = stampStarterCDNVersions ( content , versions ) ;
250+
251+ for ( const asset of starterCDNAssets ) {
252+ expect ( result ) . toContain ( createVersionedStarterCDNUrl ( asset ) ) ;
253+ }
254+ } ) ;
255+
256+ it ( 'should replace existing Elements CDN versions' , ( ) => {
257+ const content = `
258+ <link rel="stylesheet" href="${ createVersionedStarterCDNUrl ( stylesAsset , '0.0.1' ) } " />
259+ <link rel="stylesheet" href="${ createVersionedStarterCDNUrl ( themesAsset , '0.0.1' ) } " />
260+ <link rel="stylesheet" href="${ createVersionedStarterCDNUrl ( themeFontsAsset , '0.0.1' ) } " />
261+ <script type="module">
262+ import '${ createVersionedStarterCDNUrl ( coreAsset , '0.0.1' ) } ';
263+ </script>
264+ ` ;
265+
266+ const result = stampStarterCDNVersions ( content , versions ) ;
267+
268+ for ( const asset of starterCDNAssets ) {
269+ expect ( result ) . toContain ( createVersionedStarterCDNUrl ( asset ) ) ;
270+ }
271+ expect ( result ) . not . toContain ( '@0.0.1/' ) ;
272+ } ) ;
273+
274+ it ( 'should leave unrelated CDN URLs unchanged' , ( ) => {
275+ const unrelatedElementsPackageUrl = createVersionedStarterCDNUrl ( coreAsset ) . replace (
276+ `${ coreAsset . packageName } @${ versions [ coreAsset . packageName ] } /${ coreAsset . filePath } ` ,
277+ '@nvidia-elements/monaco/dist/bundles/index.css'
278+ ) ;
279+ const htmxUrl = createVersionedStarterCDNUrl ( coreAsset ) . replace (
280+ `${ coreAsset . packageName } @${ versions [ coreAsset . packageName ] } /${ coreAsset . filePath } ` ,
281+ 'htmx.org@2.0.10/dist/htmx.min.js'
282+ ) ;
283+ const content = `
284+ <link rel="stylesheet" href="${ unrelatedElementsPackageUrl } " />
285+ <script src="${ htmxUrl } "></script>
286+ ` ;
287+
288+ const result = stampStarterCDNVersions ( content , versions ) ;
289+
290+ expect ( result ) . toContain ( unrelatedElementsPackageUrl ) ;
291+ expect ( result ) . toContain ( htmxUrl ) ;
292+ } ) ;
293+ } ) ;
294+
201295describe ( 'getNPMClient' , ( ) => {
202296 it ( 'should return the npm client' , async ( ) => {
203297 expect ( await getNPMClient ( ) ) . toBe ( 'pnpm' ) ;
0 commit comments