@@ -5,13 +5,50 @@ import type { Context, Next } from 'koa';
55import { readFile } from 'node:fs/promises' ;
66import { dirname , join } from 'node:path' ;
77import { fileURLToPath } from 'node:url' ;
8+ import { glob } from 'glob' ;
89
910import nunjucks from 'nunjucks' ;
1011
1112import { Manifest } from '../../custom-elements-manifest/lib/Manifest.js' ;
1213
13- function isPFEManifest ( x : Manifest ) {
14- return x . packageJson ?. name === '@patternfly/elements' ;
14+ const env = nunjucks . configure ( join ( dirname ( fileURLToPath ( import . meta. url ) ) , 'templates' ) ) ;
15+ env . addFilter ( 'log' , x => ( console . log ( x ) , x ) ) ; // eslint-disable-line no-console
16+ // TODO: regexing html is stupid
17+ const MOD_STYLE_RE = / ( < s c r i p t t y p e = " m o d u l e " > .* < \/ s c r i p t > ) | ( < s t y l e > .* < \/ s t y l e > ) / g;
18+ env . addFilter ( 'noModulesOrStyles' , x => x . replaceAll ( MOD_STYLE_RE , '' ) ) ;
19+ env . addFilter ( 'noElement' , ( x , tagName ) => x . replaceAll ( new RegExp ( `<${ tagName } >.*</${ tagName } >` , 'gm' ) , '' ) ) ;
20+ env . addFilter ( 'getSourceControlUrl' , function (
21+ manifest : Manifest ,
22+ sourceControlURLPrefix : string ,
23+ cwd : string ,
24+ ) {
25+ if ( ! manifest || ! sourceControlURLPrefix ) {
26+ return '' ;
27+ } else {
28+ return `${ sourceControlURLPrefix . replace ( 'tree/main/' , '' ) } ${ (
29+ `tree/main${
30+ manifest . path . replace ( cwd , '' )
31+ . replace ( '/custom-elements.json' , '/' ) } `
32+ ) } `;
33+ }
34+ } ) ;
35+
36+ async function getElementsPkgJson ( config : PfeDevServerInternalConfig ) {
37+ let dir = config . elementsDir ;
38+ let pkgPath ;
39+ while ( dir !== config . rootDir && ! pkgPath ) {
40+ [ pkgPath ] = await glob ( 'package.json' , { cwd : dir , absolute : true } ) ;
41+ if ( ! pkgPath ) {
42+ dir = dirname ( dir ) ;
43+ }
44+ }
45+ try {
46+ if ( pkgPath ) {
47+ return JSON . parse ( await readFile ( pkgPath , 'utf8' ) ) ;
48+ }
49+ } catch {
50+ return ;
51+ }
1552}
1653
1754/**
@@ -21,16 +58,15 @@ function isPFEManifest(x: Manifest) {
2158async function waitForManifestFileThenReadIt ( config : PfeDevServerInternalConfig ) {
2259 let count = 0 ;
2360 let manifests = Manifest . getAll ( config . rootDir ) ;
24- while ( count < 1000 && manifests . find ( isPFEManifest ) ?. manifest === null ) {
61+ while ( count < 1000 && manifests . length < 0 ) {
2562 await new Promise ( r => setTimeout ( r , 50 ) ) ;
2663 count ++ ;
2764 manifests = Manifest . getAll ( config . rootDir ) ;
2865 }
2966 return manifests ;
3067}
3168
32- async function getDemos ( config : PfeDevServerInternalConfig ) {
33- const manifests = await waitForManifestFileThenReadIt ( config ) ;
69+ function getDemos ( config : PfeDevServerInternalConfig , manifests : Manifest [ ] ) {
3470 return manifests
3571 . flatMap ( manifest =>
3672 manifest
@@ -47,20 +83,31 @@ async function getTemplateContent(demo?: DemoRecord) {
4783 }
4884}
4985
86+ async function getManifest (
87+ config : PfeDevServerInternalConfig ,
88+ manifests : Manifest [ ] ,
89+ demo ?: DemoRecord ,
90+ ) {
91+ const elementsPkgJson = await getElementsPkgJson ( config ) ;
92+ const manifest =
93+ demo ?. manifest ?? manifests . find ( x => x . packageJson ?. name === elementsPkgJson . name ) ;
94+ return manifest ;
95+ }
96+
5097/**
5198 * Render the demo page whenever there's a trailing slash
5299 * @param config Normalized dev server options
53100 */
54101export function pfeDevServerTemplateMiddleware ( config : PfeDevServerInternalConfig ) {
55- const env = nunjucks . configure ( join ( dirname ( fileURLToPath ( import . meta. url ) ) , 'templates' ) ) ;
56102 return async function ( ctx : Context , next : Next ) : Promise < void > {
57103 const { method, path } = ctx ;
58104 if ( config . loadDemo && ! ( method !== 'HEAD' && method !== 'GET' || path . includes ( '.' ) ) ) {
105+ const manifests = await waitForManifestFileThenReadIt ( config ) ;
59106 const url = new URL ( ctx . request . url , `http://${ ctx . request . headers . host } ` ) ;
60- const demos = await getDemos ( config ) ;
107+ const demos = getDemos ( config , manifests ) ;
61108 const demo = demos . find ( x => x . permalink === url . pathname ) ;
62- const manifest = demo ?. manifest ;
63109 const templateContent = await getTemplateContent ( demo ) ;
110+ const manifest = await getManifest ( config , manifests , demo ) ;
64111 ctx . cwd = process . cwd ( ) ;
65112 ctx . type = 'html' ;
66113 ctx . status = 200 ;
0 commit comments