Skip to content

Commit

Permalink
Merge branch 'main' into staging/4.0
Browse files Browse the repository at this point in the history
  • Loading branch information
bennypowers committed Jul 1, 2024
2 parents c687880 + b6c3a1f commit 6927cd5
Show file tree
Hide file tree
Showing 8 changed files with 2,533 additions and 4,143 deletions.
12 changes: 0 additions & 12 deletions docs/_data/importMap.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ function readPackageVersion(module) {
const LIT_VERSION = readPackageVersion('lit');
const FUSE_VERSION = readPackageVersion('fuse.js');
const PRISM_VERSION = readPackageVersion('prismjs');
const PWA_HELPER_VERSION = readPackageVersion('pwa-helpers');

const LIT_DEPS = [
{
Expand Down Expand Up @@ -63,16 +62,6 @@ const LIT_DEPS = [
},
];

const PWA_DEPS = [
{
target: `pwa-helpers@${PWA_HELPER_VERSION}`,
subpaths: [
'.',
'./router.js',
],
},
];

module.exports = async function() {
const { Generator } = await import('@jspm/generator');

Expand All @@ -91,7 +80,6 @@ module.exports = async function() {
'element-internals-polyfill',
`fuse.js@${FUSE_VERSION}`,
...LIT_DEPS,
...PWA_DEPS,
]);

const map = generator.getMap();
Expand Down
6,267 changes: 2,317 additions & 3,950 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion tools/pfe-tools/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { readFileSync } from 'node:fs';
import { join } from 'node:path';
import slugify from 'slugify';

interface SiteOptions {
export interface SiteOptions {
/** The site's default page description */
description?: string;
/** URL to the site's favicon */
Expand Down
2 changes: 1 addition & 1 deletion tools/pfe-tools/dev-server/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ function normalizeOptions(options?: PfeDevServerConfigOptions) {
config.watchFiles ??= '{elements,core}/**/*.{css,html}';
config.litcssOptions ??= {
include: /\.css$/,
exclude: /(((fonts|demo)|(demo\/.*))\.css$)|(.*(-lightdom.css$))/,
exclude: /(?:@patternfly\/pfe-tools\/dev-server\/(?:fonts|demo).css)|-lightdom(?:-shim)?\.css$/,
};
return config as Required<PfeDevServerConfigOptions> & { site: Required<PfeConfig['site']> };
}
Expand Down
109 changes: 109 additions & 0 deletions tools/pfe-tools/dev-server/plugins/dev-server-router.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import type { PfeDevServerInternalConfig } from './pfe-dev-server.js';

import Router, { type Middleware } from '@koa/router';

import { makeDemoEnv } from '../../environment.js';
import { deslugify } from '../../config.js';

type PfeMiddleware = (config: PfeDevServerInternalConfig) => Middleware;

/**
* The environment file contains information from the serverside
* which is useful on the client side, for example the list of all elements
* or a list of all icons. Typically, the information in the environment file
* is data which requires access to the filesystem.
* @see environment.js
* @param config normalized PFE dev server config
*/
const environmentMiddleware: PfeMiddleware = config => async ctx => {
ctx.body = await makeDemoEnv(config.rootDir);
ctx.type = 'application/javascript';
};

/**
* Redirects pfe-core files to their typescript sources, in the case where
* the request is relative to the `@patternfly/elements` monorepo root
* FROM `core/pfe-core/controllers/thingy.js`
* TO: `core/pfe-core/controllers/thingy.ts`
*/
const coreMiddleware: PfeMiddleware = () => ctx =>
ctx.redirect(`/core/pfe-core/${ctx.params.splatPath}.ts`);

/**
* Invalidate the browser cache for element css / js / html subresources on every request
* in order that the user always receive the file on disk
*/
const cacheBustingMiddleware: PfeMiddleware = () => async function(ctx, next) {
ctx.response.etag = performance.now().toString();
return next();
};

/**
* Loads the typescript sources for element declaration source requests
* This is useful when the typescript build runs in parallel.
* FROM: `components/jazz-hands/*.js`
* TO: `elements/pf-jazz-hands/*.ts`
* @param config normalized PFE dev server config
*/
const elementDeclarationTypeScriptMiddleware: PfeMiddleware = config => async ctx => {
const { unprefixedElementSlug, moduleName } = ctx.params;
const tagName = deslugify(unprefixedElementSlug);
return ctx.redirect(`/${config.elementsDir}/${tagName}/${moduleName}.ts`);
};

/**
* Redirects to lightdom shim files, in the element definition dir
* FROM: `components/jazz-hands/pf-jazz-hands-lightdom.css`
* TO: `elements/pf-jazz-hands/pf-jazz-hands-lightdom.css`
* @param config normalized PFE dev server config
*/
const lightdomShimMiddleware: PfeMiddleware = config => (ctx, next) => {
const { unprefixedElementSlug, sheetName, suffix } = ctx.params;
const tagName = deslugify(unprefixedElementSlug);
const redirect = `/${config.elementsDir}/${tagName}/${sheetName}-lightdom${suffix ?? ''}.css`;
if (ctx.path !== redirect) {
return ctx.redirect(redirect);
} else {
return next();
}
};

/**
* Redirects to subresources in /demo/ from pretty urls
* FROM: `components/jazz-hands/demo/**\/*`
* TO: `elements/pf-jazz-hands/demo/*.*`
* @param config normalized PFE dev server config
*/
const demoSubresourceMiddleware: PfeMiddleware = config => (ctx, next) => {
const { unprefixedElementSlug, fileName, ext } = ctx.params;
const tagName = deslugify(unprefixedElementSlug);
const redirect = `/${config.elementsDir}/${tagName}/demo/${fileName}.${ext}`;
if (ctx.path !== redirect) {
return ctx.redirect(redirect);
} else {
return next();
}
};

/**
* Creates a router Koa middleware for PFE dev server
* @param config Normalized dev server options
*/
export function pfeDevServerRouterMiddleware(config: PfeDevServerInternalConfig) {
const { elementsDir, site: { componentSubpath } } = config;
const router = new Router();
return router
.get('/tools/pfe-tools/environment.js(.js)?',
environmentMiddleware(config))
.get(`/core/pfe-core/:splatPath*.js`,
coreMiddleware(config))
.get(`/${elementsDir}/:tagName/:splat.(css|html|js)`,
cacheBustingMiddleware(config))
.get(`/${componentSubpath}/:unprefixedElementSlug/:moduleName*.js`,
elementDeclarationTypeScriptMiddleware(config))
.get(`/${componentSubpath}/:unprefixedElementSlug/{demo/}?:sheetName-lightdom{:suffix}?.css`,
lightdomShimMiddleware(config))
.get(`/${componentSubpath}/:unprefixedElementSlug/demo/{:demoName/}?:fileName.:ext`,
demoSubresourceMiddleware(config))
.routes();
}
80 changes: 80 additions & 0 deletions tools/pfe-tools/dev-server/plugins/dev-server-templates.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import type { PfeDevServerInternalConfig } from './pfe-dev-server.js';
import type { DemoRecord } from '../../custom-elements-manifest/lib/Manifest.js';
import type { Context, Next } from 'koa';

import { readFile } from 'node:fs/promises';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';

import nunjucks from 'nunjucks';

import { Manifest } from '../../custom-elements-manifest/lib/Manifest.js';

function isPFEManifest(x: Manifest) {
return x.packageJson?.name === '@patternfly/elements';
}

/**
* cludge to ensure the dev server starts up only after the manifests are generated
* @param config Normalized dev server options
*/
async function waitForManifestFileThenReadIt(config: PfeDevServerInternalConfig) {
let count = 0;
let manifests = Manifest.getAll(config.rootDir);
while (count < 1000 && manifests.find(isPFEManifest)?.manifest === null) {
await new Promise(r => setTimeout(r, 50));
count++;
manifests = Manifest.getAll(config.rootDir);
}
return manifests;
}

async function getDemos(config: PfeDevServerInternalConfig) {
const manifests = await waitForManifestFileThenReadIt(config);
return manifests
.flatMap(manifest =>
manifest
.getTagNames()
.flatMap(tagName =>
manifest.getDemoMetadata(tagName, config as PfeDevServerInternalConfig)));
}

async function getTemplateContent(demo?: DemoRecord) {
if (typeof demo?.filePath === 'string') {
return readFile(demo.filePath, 'utf8');
} else {
return undefined;
}
}

/**
* Render the demo page whenever there's a trailing slash
* @param config Normalized dev server options
*/
export function pfeDevServerTemplateMiddleware(config: PfeDevServerInternalConfig) {
const env = nunjucks.configure(join(dirname(fileURLToPath(import.meta.url)), 'templates'));
return async function(ctx: Context, next: Next) {
const { method, path } = ctx;
if (config.loadDemo && !(method !== 'HEAD' && method !== 'GET' || path.includes('.'))) {
const url = new URL(ctx.request.url, `http://${ctx.request.headers.host}`);
const demos = await getDemos(config);
const demo = demos.find(x => x.permalink === url.pathname);
const manifest = demo?.manifest;
const templateContent = await getTemplateContent(demo);
ctx.cwd = process.cwd();
ctx.type = 'html';
ctx.status = 200;
ctx.body = env.render('index.html', {
context: ctx,
options: config,
demo,
demos,
manifest,
templateContent,
});
}
return next();
};
}


Loading

0 comments on commit 6927cd5

Please sign in to comment.