UNPKG

@knapsack/app

Version:

Build Design Systems on top of knapsack, by Basalt

156 lines (139 loc) 3.86 kB
import express from 'express'; import { readFile, existsSync } from 'fs-extra'; import { hbsRenderString } from '@knapsack/core'; import { join, dirname } from 'path'; import { apiUrlBase } from '../lib/constants'; import { createDemoUrl } from '../lib/routes'; import { KnapsackConfig } from '../schemas/knapsack-config'; const router = express.Router(); export function setupRoutes({ patterns, knapsackDistDir, distDir, publicDir, cacheDir, plugins, }: { patterns: import('./patterns').Patterns; knapsackDistDir: string; distDir?: string; publicDir?: string; cacheDir: string; plugins: KnapsackConfig['plugins']; }): typeof router { router.use('*', async (req, res, next) => { res.header('Access-Control-Allow-Origin', '*'); res.header( 'Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept', ); next(); }); router.use(`${apiUrlBase}`, (req, res, next) => { if (process.env.NODE_ENV === 'production') { next(); } else { // faking a slight delay in local development to better reflect re-world delays setTimeout(next, 500); } }); router.use( express.static(knapsackDistDir, { maxAge: '1d', }), ); const designSystemDistDir = dirname( require.resolve('@knapsack/design-system'), ); router.use('/ks-design-system', express.static(designSystemDistDir)); if (distDir) { router.use( express.static(distDir, { maxAge: '1d', }), ); } if (cacheDir) { router.use( express.static(cacheDir, { maxAge: '1d', }), ); } if (publicDir) { router.use(express.static(publicDir)); } if (plugins) { plugins .filter(p => p.publicDir) .forEach(plugin => { router.use(`/plugins/${plugin.id}`, express.static(plugin.publicDir)); }); } function getDemoUrls(): { id: string; title: string; templates: { id: string; title: string; demoUrls: string[]; }[]; }[] { return patterns.getPatterns().map(pattern => { return { id: pattern.id, title: pattern.title, templates: pattern.templates.map(template => { return { id: template.id, title: template.title ?? template.id, demoUrls: [ ...template.demos.map(demoId => createDemoUrl({ patternId: pattern.id, templateId: template.id, demoId, wrapHtml: true, isInIframe: false, }), ), ], }; }), }; }); } router.get('/demo-urls-data', (req, res) => { res.send(getDemoUrls()); }); const demoUrlsHbsPath = join(__dirname, './templates/demo-urls.html.hbs'); if (!existsSync(demoUrlsHbsPath)) { throw new Error( `Demo URLs handlebars template does not exist: ${demoUrlsHbsPath}`, ); } // This page is mainly so IE can get a list of links to view the individual templates outside of the system router.route('/demo-urls').get(async (req, res) => { const patternDemos = getDemoUrls(); const demoUrlsHbs = await readFile(demoUrlsHbsPath, 'utf-8'); const result = hbsRenderString({ hbsString: demoUrlsHbs, data: { patternDemos, }, }); res.send(result); }); // Since this is a Single Page App, we will send all html requests to the `index.html` file in the dist router.use('*', (req, res, next) => { const { accept = '' } = req.headers; const accepted = accept.split(','); // this is for serving up a Netlify CMS folder if present if (accepted.includes('text/html')) { res.sendFile(join(knapsackDistDir, 'index.html')); } else { next(); } }); return router; }