| 7 | import type { TWConfig, ViewerConfig } from './types' |
| 8 | |
| 9 | export const setupViewer = async (twConfig: string | Partial<TWConfig>, config: ViewerConfig, nuxt = useNuxt()) => { |
| 10 | const route = joinURL(nuxt.options.app?.baseURL, config.endpoint) |
| 11 | const [routeWithSlash, routeWithoutSlash] = [withTrailingSlash(route), withoutTrailingSlash(route)] |
| 12 | |
| 13 | const viewerServer = await Promise.all([ |
| 14 | // @ts-expect-error untyped package export |
| 15 | import('tailwind-config-viewer/server/index.js').then(r => r.default || r), |
| 16 | typeof twConfig === 'string' ? import('tailwindcss/loadConfig.js').then(r => r.default || r).then(loadConfig => () => loadConfig(twConfig)) : () => twConfig, |
| 17 | ]).then(([server, tailwindConfigProvider]) => server({ tailwindConfigProvider }).asMiddleware()) |
| 18 | const viewerDevMiddleware = eventHandler(event => viewerServer(event.node?.req || event.req, event.node?.res || event.res)) |
| 19 | |
| 20 | if (!isNuxtMajorVersion(2, nuxt)) { |
| 21 | addDevServerHandler({ |
| 22 | handler: eventHandler((event) => { |
| 23 | if (event.path === routeWithoutSlash) { |
| 24 | return sendRedirect(event, routeWithSlash, 301) |
| 25 | } |
| 26 | }), |
| 27 | }) |
| 28 | addDevServerHandler({ route, handler: viewerDevMiddleware }) |
| 29 | } |
| 30 | else { |
| 31 | // @ts-expect-error untyped nuxt2 property |
| 32 | nuxt.options.serverMiddleware.push( |
| 33 | // @ts-expect-error untyped handler parameters |
| 34 | (req, res, next) => { |
| 35 | if (req.url === routeWithoutSlash) { |
| 36 | return sendRedirect(new H3Event(req, res), routeWithSlash, 301) |
| 37 | } |
| 38 | |
| 39 | next() |
| 40 | }, |
| 41 | // @ts-expect-error untyped handler parameters |
| 42 | { route, handler: (req, res) => viewerDevMiddleware(new H3Event(req, res)) }, |
| 43 | ) |
| 44 | } |
| 45 | |
| 46 | nuxt.hook('devtools:customTabs', (tabs: import('@nuxt/devtools').ModuleOptions['customTabs']) => { |
| 47 | tabs?.push({ |
| 48 | title: 'Tailwind CSS', |
| 49 | name: 'tailwindcss', |
| 50 | icon: 'logos-tailwindcss-icon', |
| 51 | category: 'modules', |
| 52 | view: { type: 'iframe', src: route }, |
| 53 | }) |
| 54 | }) |
| 55 | |
| 56 | const shouldLogUrl = 'devtools' in nuxt.options ? !nuxt.options.devtools.enabled : true |
| 57 | |
| 58 | // eslint-disable-next-line @typescript-eslint/no-unused-expressions |
| 59 | shouldLogUrl && nuxt.hook('listen', (_, listener) => { |
| 60 | const viewerUrl = cleanDoubleSlashes(joinURL(listener.url, config.endpoint)) |
| 61 | logger.info(`Tailwind Viewer: ${colors.underline(colors.yellow(withTrailingSlash(viewerUrl)))}`) |
| 62 | }) |
| 63 | } |
| 64 | |
| 65 | export const exportViewer = async (twConfig: string, config: ViewerConfig, nuxt = useNuxt()) => { |
| 66 | if (!config.exportViewer) { |