@@ -5,8 +5,8 @@ import { basename, dirname, join, parse, resolve } from 'node:path';
55import { execFile , execFileSync } from 'node:child_process' ;
66import { cwd } from 'node:process' ;
77
8- import { writeFile } from 'fs/promises' ;
9- import { existsSync , unlinkSync , writeFileSync , cpSync , createWriteStream , rmSync } from 'fs' ;
8+ import { readFile , writeFile } from 'fs/promises' ;
9+ import { existsSync , unlinkSync , writeFileSync , cpSync , createWriteStream , rmSync , readFileSync } from 'fs' ;
1010import { readWorkspaceManifest } from '@pnpm/workspace.read-manifest' ;
1111import { getCatalogsFromWorkspaceManifest } from '@pnpm/catalogs.config' ;
1212import { createExportableManifest } from '@pnpm/exportable-manifest' ;
@@ -18,12 +18,33 @@ import type { Report } from '../internal/types.js';
1818import { writeAllAgentConfigs } from './setup-agent.js' ;
1919
2020const ELEMENTS_PAGES_BASE_URL = 'https://nvidia.github.io/elements' ;
21+ const ELEMENTS_CDN_BASE_URL = 'https://esm.sh' ;
22+ const REPO_WORKSPACE_DIR = '../../' ;
23+
24+ type StarterCDNPackageName = '@nvidia-elements/core' | '@nvidia-elements/styles' | '@nvidia-elements/themes' ;
25+
26+ const starterCDNPackagePaths : Record < StarterCDNPackageName , string > = {
27+ '@nvidia-elements/core' : 'projects/core/package.json' ,
28+ '@nvidia-elements/styles' : 'projects/styles/package.json' ,
29+ '@nvidia-elements/themes' : 'projects/themes/package.json'
30+ } ;
31+
32+ const starterCDNAssets : { packageName : StarterCDNPackageName ; filePath : string } [ ] = [
33+ { packageName : '@nvidia-elements/core' , filePath : 'dist/bundles/index.js' } ,
34+ { packageName : '@nvidia-elements/styles' , filePath : 'dist/bundles/index.css' } ,
35+ { packageName : '@nvidia-elements/themes' , filePath : 'dist/bundles/index.css' } ,
36+ { packageName : '@nvidia-elements/themes' , filePath : 'dist/fonts/inter.css' }
37+ ] ;
38+
39+ const starterDirsWithStampedCDNVersions = new Set < string > ( [ 'go' , 'go-htmx' ] ) ;
2140
2241export type Starter =
2342 | 'angular'
2443 | 'bundles'
2544 | 'eleventy'
2645 | 'go'
46+ | 'go-htmx'
47+ | 'hugo'
2748 | 'importmaps'
2849 | 'lit-library'
2950 | 'lit'
@@ -54,7 +75,13 @@ export const startersData = {
5475 } ,
5576 go : {
5677 zip : `${ ELEMENTS_PAGES_BASE_URL } /starters/download/go.zip` ,
57- cli : true
78+ cli : true ,
79+ setupElementsDependencies : false
80+ } ,
81+ 'go-htmx' : {
82+ zip : `${ ELEMENTS_PAGES_BASE_URL } /starters/download/go-htmx.zip` ,
83+ cli : true ,
84+ setupElementsDependencies : false
5885 } ,
5986 hugo : {
6087 zip : `${ ELEMENTS_PAGES_BASE_URL } /starters/download/hugo.zip` ,
@@ -113,7 +140,8 @@ export const startersData = {
113140/* istanbul ignore next -- @preserve */
114141export async function archiveStarter ( projectDir : string , outDir : string ) {
115142 const dist = join ( outDir , projectDir ) ;
116- await copyProject ( projectDir ) ;
143+ await copyProject ( projectDir , dist ) ;
144+ await stampStarterCDNVersionFiles ( projectDir , dist ) ;
117145 writeAllAgentConfigs ( dist ) ;
118146 const packageJSON = await exportPackageFromWorkspace ( projectDir ) ;
119147 await writeFile ( join ( dist , 'package.json' ) , JSON . stringify ( packageJSON , undefined , 2 ) ) ;
@@ -135,17 +163,64 @@ async function zipProject(outDir: string) {
135163}
136164
137165/* istanbul ignore next -- @preserve */
138- function copyProject ( projectDir : string ) {
139- const ignoreDirs = new Set ( [ 'dist' , 'node_modules' , '.wireit' , '.eslintcache' ] ) ;
140- cpSync ( projectDir , join ( ' dist' , projectDir ) , {
166+ function copyProject ( projectDir : string , dist : string ) {
167+ const ignoreDirs = new Set ( [ 'dist' , 'node_modules' , '.wireit' , '.eslintcache' , 'bin' ] ) ;
168+ cpSync ( projectDir , dist , {
141169 recursive : true ,
142170 filter : src => ! ignoreDirs . has ( basename ( src ) )
143171 } ) ;
144172}
145173
174+ function escapeRegExp ( value : string ) {
175+ return value . replace ( / [ . * + ? ^ $ { } ( ) | [ \] \\ ] / g, '\\$&' ) ;
176+ }
177+
178+ function getPackageVersion ( repoRoot : string , packageName : StarterCDNPackageName ) : string {
179+ const packageJsonPath = join ( repoRoot , starterCDNPackagePaths [ packageName ] ) ;
180+ const packageJson = JSON . parse ( readFileSync ( packageJsonPath , 'utf8' ) ) as { version ?: unknown } ;
181+ if ( typeof packageJson . version !== 'string' || ! packageJson . version ) {
182+ throw new Error ( `No version found for ${ packageName } in ${ packageJsonPath } ` ) ;
183+ }
184+ return packageJson . version ;
185+ }
186+
187+ export function getStarterCDNPackageVersions ( repoRoot : string ) : Record < StarterCDNPackageName , string > {
188+ return {
189+ '@nvidia-elements/core' : getPackageVersion ( repoRoot , '@nvidia-elements/core' ) ,
190+ '@nvidia-elements/styles' : getPackageVersion ( repoRoot , '@nvidia-elements/styles' ) ,
191+ '@nvidia-elements/themes' : getPackageVersion ( repoRoot , '@nvidia-elements/themes' )
192+ } ;
193+ }
194+
195+ export function createStarterCDNUrl ( packageName : StarterCDNPackageName , version : string , filePath : string ) {
196+ return `${ ELEMENTS_CDN_BASE_URL } /${ packageName } @${ version } /${ filePath } ` ;
197+ }
198+
199+ export function stampStarterCDNVersions ( content : string , versions : Record < StarterCDNPackageName , string > ) {
200+ return starterCDNAssets . reduce ( ( updatedContent , asset ) => {
201+ const versionedUrl = createStarterCDNUrl ( asset . packageName , versions [ asset . packageName ] , asset . filePath ) ;
202+ const urlPattern = new RegExp (
203+ `${ escapeRegExp ( ELEMENTS_CDN_BASE_URL ) } /${ escapeRegExp ( asset . packageName ) } (?:@[^/"']+)?/${ escapeRegExp ( asset . filePath ) } ` ,
204+ 'g'
205+ ) ;
206+ return updatedContent . replace ( urlPattern , versionedUrl ) ;
207+ } , content ) ;
208+ }
209+
210+ async function stampStarterCDNVersionFiles ( projectDir : string , dist : string ) {
211+ if ( ! starterDirsWithStampedCDNVersions . has ( projectDir ) ) {
212+ return ;
213+ }
214+
215+ const indexPath = join ( dist , 'src/index.html' ) ;
216+ const repoRoot = resolve ( REPO_WORKSPACE_DIR ) ;
217+ const versions = getStarterCDNPackageVersions ( repoRoot ) ;
218+ const content = await readFile ( indexPath , 'utf8' ) ;
219+ await writeFile ( indexPath , stampStarterCDNVersions ( content , versions ) ) ;
220+ }
221+
146222/* istanbul ignore next -- @preserve */
147223async function exportPackageFromWorkspace ( projectDir : string ) {
148- const REPO_WORKSPACE_DIR = '../../' ;
149224 const workspace = await readWorkspaceManifest ( REPO_WORKSPACE_DIR ) ;
150225 const catalogs = getCatalogsFromWorkspaceManifest ( workspace ) ;
151226 const manifest = await readProjectManifestOnly ( projectDir ) ;
0 commit comments