8000 fix(meta): support latest Nuxt language tooling by Norbiros · Pull Request #175 · romhml/compodium · GitHub
[go: up one dir, main page]

Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
checks:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6

- uses: pnpm/action-setup@v4
name: Install pnpm
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
working-directory: docs

steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6

- uses: pnpm/action-setup@v4
name: Install pnpm
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:

steps:
- name: Checkout
uses: actions/checkout@v5
uses: actions/checkout@v6

- uses: pnpm/action-setup@v4
name: Install pnpm
Expand Down
8 changes: 4 additions & 4 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@
"typecheck": "nuxt typecheck"
},
"dependencies": {
"@iconify-json/lucide": "^1.2.71",
"@iconify-json/simple-icons": "^1.2.56",
"@iconify-json/lucide": "^1.2.72",
"@iconify-json/simple-icons": "^1.2.57",
"@iconify-json/vscode-icons": "^1.2.33",
"@nuxt/content": "^3.7.1",
"@nuxt/image": "^1.11.0",
"@nuxt/content": "^3.8.0",
"@nuxt/image": "^2.0.0",
"@nuxthub/core": "0.9.0",
"better-sqlite3": "^12.4.1",
"nuxt": "catalog:",
Expand Down
19 changes: 10 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,31 +17,32 @@
"bump": "jiti ./scripts/bump.ts"
},
"devDependencies": {
"@nuxt/eslint-config": "^1.9.0",
"@nuxt/test-utils": "^3.20.1",
"@types/node": "^22.18.12",
"@nuxt/eslint-config": "^1.10.0",
"@nuxt/test-utils": "^4.0.3",
"@types/node": "^22.19.0",
"@types/supertest": "^6.0.3",
"changelogen": "^0.6.2",
"eslint": "^9.38.0",
"happy-dom": "^17.4.4",
"eslint": "^9.39.4",
"happy-dom": "^20.9.0",
"supertest": "^7.1.4",
"typescript": "^5.9.2",
"unbuild": "^3.6.1",
"vite": "^7.1.12",
"vitest": "^3.2.4",
"wrangler": "^4.45.0"
"vitest": "^4.1.5",
"wrangler": "^4.45.3"
},
"resolutions": {
"@compodium/core": "workspace:^",
"@compodium/examples": "workspace:^",
"@compodium/meta": "workspace:^",
"@compodium/nuxt": "workspace:^",
"@compodium/vue": "workspace:^"
"@compodium/vue": "workspace:^",
"@compodium/testing": "workspace:^"
},
"pnpm": {
"onlyBuiltDependencies": [
"better-sqlite3"
]
},
"packageManager": "pnpm@10.19.0"
"packageManager": "pnpm@10.20.0"
}
1 change: 0 additions & 1 deletion packages/core/build.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ export default defineBuildConfig({
{ builder: 'copy', input: './src/runtime', outDir: './dist/runtime' }
],
replace: {
'process.env.COMPODIUM_TEST': 'false',
'process.env.COMPODIUM_DEVTOOLS_URL': undefined
}
})
7 changes: 6 additions & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,13 @@
"typecheck": "tsc --noEmit"
},
"peerDependencies": {
"@compodium/testing": "workspace:^",
"vite": ">=6",
"vitest": ">=4.0.2",
"vue": ">=3"
},
"peerDependenciesMeta": {
"vite": {
"@compodium/testing": {
"optional": true
}
},
Expand All @@ -56,5 +58,8 @@
"unplugin": "^2.3.10",
"unplugin-ast": "^0.15.3",
"zod": "^4.1.12"
},
"devDependencies": {
"vue": "catalog:"
}
}
18 changes: 16 additions & 2 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { Plugin } from 'vite'
import { collectionsPlugin } from './plugins/collections'
import { extendMetaPlugin, metaPlugin } from './plugins/meta'
import { examplePlugin } from './plugins/examples'
Expand All @@ -8,8 +9,8 @@ import type { PluginOptions } from './types'

export * from './types'

export const compodium = /* #__PURE__ */ (options: PluginOptions) => {
return [
export const compodium = /* #__PURE__ */ async (options: PluginOptions) => {
const plugins: Plugin[] = [
collectionsPlugin(options),
metaPlugin(options),
extendMetaPlugin(options),
Expand All @@ -18,4 +19,17 @@ export const compodium = /* #__PURE__ */ (options: PluginOptions) => {
iconifyPlugin(options),
colorsPlugin(options)
]

if (options.testing?.enabled) {
try {
const { compodiumTesting } = await import('@compodium/testing')
compodiumTesting(options).forEach(p => plugins.push(p))
} catch {
throw new Error(
'The `@compodium/testing` package is required when tests are enabled.'
)
}
}

return plugins
}
127 changes: 76 additions & 51 deletions packages/core/src/plugins/collections.ts
10BC8
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import { resolve } from 'pathe'
import { joinURL } from 'ufo'
import type { ResolvedConfig } from 'vite'

const VIRTUAL_MODULE_ID = 'virtual:compodium/collections'
const RESOLVED_VIRTUAL_MODULE_ID = '\0' + VIRTUAL_MODULE_ID

export function resolveCollections(options: PluginOptions, viteConfig: ResolvedConfig): Collection[] {
const rootDir = options.rootDir ?? viteConfig.root

Expand Down Expand Up @@ -54,52 +57,76 @@ export function resolveCollections(options: PluginOptions, viteConfig: ResolvedC
]
}

async function generateCollectionsData(collections: Collection[]) {
const result = await Promise.all(collections.map(async (col) => {
const components = await scanComponents(col.dirs)
const examples = await scanComponents([col.exampleDir])

const collectionComponents = components.flatMap((c) => {
const componentExamples = examples?.filter(e => e.pascalName.startsWith(`${c.pascalName}Example`)).map(e => ({
...e,
isExample: true,
componentPath: c.filePath,
componentName: c.pascalName,
collectionName: col.name
}))

const mainExample = componentExamples.find(e => e.pascalName === `${c.pascalName}Example`)
const component = mainExample ?? c

if (col.name !== 'Components' && !mainExample) return []

return [{
...component,
wrapperComponent: col.wrapperComponent,
docUrl: col.getDocUrl?.(c.pascalName),
examples: componentExamples.filter(e => e.pascalName !== mainExample?.pascalName),
collectionName: col.name
}]
})

return {
...col,
components: collectionComponents
}
}))

return result
}

export function collectionsPlugin(options: PluginOptions): VitePlugin {
let collections: Collection[]
let server: any

return {
name: 'compodium:collections',
apply: 'serve',
enforce: 'post',
enforce: 'pre',

configResolved(viteConfig) {
collections = resolveCollections(options, viteConfig)
},

configureServer(server) {
server.middlewares.use('/__compodium__/api/collections', async (_, res) => {
try {
const result = await Promise.all(collections.map(async (col) => {
const components = await scanComponents(col.dirs)
const examples = await scanComponents([col.exampleDir])

const collectionComponents = components.flatMap((c) => {
const componentExamples = examples?.filter(e => e.pascalName.startsWith(`${c.pascalName}Example`)).map(e => ({
...e,
isExample: true,
componentPath: c.filePath
}))

const mainExample = componentExamples.find(e => e.pascalName === `${c.pascalName}Example`)
const component = mainExample ?? c

// Hides third party library components if no example can be found.
if (col.name !== 'Components' && !mainExample) return []

return [{
...component,
wrapperComponent: col.wrapperComponent,
docUrl: col.getDocUrl?.(c.pascalName),
examples: componentExamples.filter(e => e.pascalName !== mainExample?.pascalName)
}]
})

return {
...col,
components: collectionComponents
}
}))
resolveId(id) {
if (id === VIRTUAL_MODULE_ID) {
return RESOLVED_VIRTUAL_MODULE_ID
}
},

async load(id) {
if (id === RESOLVED_VIRTUAL_MODULE_ID) {
const data = await generateCollectionsData(collections)
return `export default ${JSON.stringify(data, null, 2)}`
}
},

configureServer(_server) {
server = _server

// Existing middleware endpoint
server.middlewares.use('/__compodium__/api/collections', async (_: any, res: any) => {
try {
const result = await generateCollectionsData(collections)
res.setHeader('Content-Type', 'application/json')
res.write(JSON.stringify(result))
res.end()
Expand All @@ -116,7 +143,6 @@ export function collectionsPlugin(options: PluginOptions): VitePlugin {
componentCollection.exampleDir
].map(d => d.path)

// Watch for changes in example directory
const watcher = watch(watchedPaths, {
persistent: true,
awaitWriteFinish: {
Expand All @@ -125,34 +151,33 @@ export function collectionsPlugin(options: PluginOptions): VitePlugin {
}
})

watcher.on('add', async (filePath: string) => {
const handleFileChange = async (filePath: string, event: string) => {
if (watchedPaths.find(p => filePath.startsWith(p))) {
// Existing WebSocket HMR
server.ws.send({
type: 'custom',
event: 'compodium:hmr',
data: { path: filePath, event: 'component:added' }
data: { path: filePath, event }
})

// Virtual module invalidation
const module = server.moduleGraph.getModuleById(RESOLVED_VIRTUAL_MODULE_ID)
if (module) {
server.reloadModule(module)
}
}
}

watcher.on('add', async (filePath: string) => {
await handleFileChange(filePath, 'component:added')
})

watcher.on('addDir', async (filePath: string) => {
if (watchedPaths.find(p => filePath.startsWith(p))) {
server.ws.send({
type: 'custom',
event: 'compodium:hmr',
data: { path: filePath, event: 'component:added' }
})
}
await handleFileChange(filePath, 'component:added')
})

watcher.on('unlink', async (filePath: string) => {
if (watchedPaths.find(p => filePath.startsWith(p))) {
server.ws.send({
type: 'custom',
event: 'compodium:hmr',
data: { path: filePath, event: 'component:removed' }
})
}
await handleFileChange(filePath, 'component:removed')
})
}
}
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/plugins/colors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export function colorsPlugin(options: PluginOptions): VitePlugin {
return {
name: 'compodium:colors',
apply: 'serve',
enforce: 'pre',
configureServer(server) {
server.middlewares.use('/__compodium__/api/colors', async (req, res) => {
try {
Expand Down
16 changes: 2 additions & 14 deletions packages/core/src/plugins/devtools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,15 @@ export function devtoolsPlugin(options: PluginOptions): VitePlugin {

return {
name: 'compodium:devtools',
enforce: 'pre',
apply: 'serve',

configResolved(viteConfig) {
userPreview = resolve(joinURL(options.rootDir ?? viteConfig.root, options.dir, 'preview.vue'))
},
config(config) {
if (process.env.COMPODIUM_DEVTOOLS_URL) {
config.server ||= {}
config.server.proxy ||= {}
config.server.proxy['/__compodium__/devtools'] = {
target: process.env.COMPODIUM_DEVTOOLS_URL,
ws: true,
rewriteWsOrigin: true,
changeOrigin: true,
followRedirects: true
}
}
},

configureServer(server) {
if (process.env.COMPODIUM_DEVTOOLS_URL || process.env.COMPODIUM_TEST) return
if (process.env.COMPODIUM_DEVTOOLS_URL || process.env.VITEST) return
server.middlewares.use('/__compodium__/devtools',
sirv(resolve(dirname(fileURLToPath(import.meta.url)), './client/devtools'),
{ single: true, setHeaders: res => res.setHeader('Cache-Control', 'public, max-age=3600, stale-while-revalidate=86400') }
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/plugins/examples.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export function examplePlugin(options: PluginOptions): VitePlugin {

return {
name: 'compodium:examples',
enforce: 'pre',
apply: 'serve',

configResolved(viteConfig) {
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/plugins/iconify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import { joinURL } from 'ufo'
export function iconifyPlugin(_options: PluginOptions): VitePlugin {
return {
name: 'compodium:iconify',
enforce: 'pre',
apply: 'serve',

configureServer(server) {
server.middlewares.use('/__compodium__/api/iconify', async (req, res) => {
try {
Expand Down
Loading
Loading
0