Skip to content

Commit 1b92d48

Browse files
committed
fix(registry): add missing component files to build assets (#19)
1 parent 5aa894b commit 1b92d48

File tree

1 file changed

+43
-24
lines changed

1 file changed

+43
-24
lines changed

apps/registry/server/utils/registry-builder.ts

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { promises as fs } from 'node:fs'
2-
import { join, relative } from 'node:path'
2+
import { basename, join, relative } from 'node:path'
3+
import { parse as parseSFC } from '@vue/compiler-sfc'
34
import { Project } from 'ts-morph'
4-
import { parse as parseSFC } from 'vue/compiler-sfc'
55

66
interface FileRec { type: string, path: string, target?: string, content: string }
77

@@ -128,7 +128,7 @@ function analyzeDependencies(
128128
return { dependencies, devDependencies, registryDependencies }
129129
}
130130

131-
async function walkVueFiles(dir: string): Promise<string[]> {
131+
async function walkComponentFiles(dir: string, rootDir: string): Promise<string[]> {
132132
const out: string[] = []
133133
let entries: any[] = []
134134
try {
@@ -140,15 +140,21 @@ async function walkVueFiles(dir: string): Promise<string[]> {
140140
for (const entry of entries) {
141141
const full = join(dir, entry.name)
142142
if (entry.isDirectory()) {
143-
const nested = await walkVueFiles(full)
143+
const nested = await walkComponentFiles(full, rootDir)
144144
out.push(...nested)
145145
}
146-
else if (entry.isFile() && entry.name.endsWith('.vue')) {
147-
out.push(full)
148-
}
149-
else if (entry.isFile() && entry.name === 'index.ts' && !full.endsWith('/src/index.ts')) {
150-
// Only include index.ts files that are not the root src/index.ts
151-
out.push(full)
146+
else if (entry.isFile()) {
147+
// Include all .vue files
148+
if (entry.name.endsWith('.vue')) {
149+
out.push(full)
150+
}
151+
// Include all .ts files except the root src/index.ts
152+
else if (entry.name.endsWith('.ts')) {
153+
const isRootIndex = full === join(rootDir, 'index.ts')
154+
if (!isRootIndex) {
155+
out.push(full)
156+
}
157+
}
152158
}
153159
}
154160
return out
@@ -185,9 +191,9 @@ export async function generateRegistryAssets(ctx: { rootDir: string }) {
185191
const allowedDeps = new Set(Object.keys(allDeps || {}).filter((d: string) => !['vue', '@repo/shadcn-vue', ...Array.from(internalDeps)].includes(d)))
186192
const allowedDevDeps = new Set(Object.keys(allDevDeps || {}).filter((d: string) => !['typescript'].includes(d)))
187193

188-
const vueFiles = await walkVueFiles(srcDir)
194+
const componentFiles = await walkComponentFiles(srcDir, srcDir)
189195
const files: FileRec[] = []
190-
for (const abs of vueFiles) {
196+
for (const abs of componentFiles) {
191197
const raw = await fs.readFile(abs, 'utf-8')
192198
const parsed = raw
193199
.replace(/@repo\/shadcn-vue\//g, '@/')
@@ -204,7 +210,7 @@ export async function generateRegistryAssets(ctx: { rootDir: string }) {
204210
for (const abs of candidates) {
205211
const raw = await fs.readFile(abs, 'utf-8')
206212
const parsed = raw.replace(/@repo\/elements\//g, '@/components/ai-elements/')
207-
const name = abs.split('/').pop() as string
213+
const name = basename(abs)
208214
exampleFiles.push({ type: 'registry:block', path: `components/ai-elements/examples/${name}`, target: '', content: parsed })
209215
}
210216
}
@@ -229,7 +235,8 @@ export async function generateRegistryAssets(ctx: { rootDir: string }) {
229235
}))
230236

231237
const exampleItems = exampleFiles.map((ef) => {
232-
const name = (ef.path.split('/').pop() as string).replace('.vue', '')
238+
const fileName = basename(ef.path)
239+
const name = fileName.replace('.vue', '')
233240
return {
234241
name: `example-${name}`,
235242
type: 'registry:block',
@@ -257,15 +264,26 @@ export async function generateRegistryAssets(ctx: { rootDir: string }) {
257264
const groupRegistryDeps = new Set<string>()
258265

259266
for (const f of groupFiles) {
260-
const { descriptor } = parseSFC(f.content)
261-
const code = [descriptor.script?.content || '', descriptor.scriptSetup?.content || ''].join('\n')
262-
const imports = parseImportsFromCode(code)
263-
const analysis = analyzeDependencies(imports, allowedDeps, allowedDevDeps)
264-
265-
// Merge results
266-
analysis.dependencies.forEach(dep => groupDeps.add(dep))
267-
analysis.devDependencies.forEach(dep => groupDevDeps.add(dep))
268-
analysis.registryDependencies.forEach(dep => groupRegistryDeps.add(dep))
267+
let code = ''
268+
// Handle Vue SFC files
269+
if (f.path.endsWith('.vue')) {
270+
const { descriptor } = parseSFC(f.content)
271+
code = [descriptor.script?.content || '', descriptor.scriptSetup?.content || ''].join('\n')
272+
}
273+
// Handle TypeScript files
274+
else if (f.path.endsWith('.ts')) {
275+
code = f.content
276+
}
277+
278+
if (code) {
279+
const imports = parseImportsFromCode(code)
280+
const analysis = analyzeDependencies(imports, allowedDeps, allowedDevDeps)
281+
282+
// Merge results
283+
analysis.dependencies.forEach(dep => groupDeps.add(dep))
284+
analysis.devDependencies.forEach(dep => groupDevDeps.add(dep))
285+
analysis.registryDependencies.forEach(dep => groupRegistryDeps.add(dep))
286+
}
269287
}
270288

271289
const itemJson = {
@@ -290,7 +308,8 @@ export async function generateRegistryAssets(ctx: { rootDir: string }) {
290308
}
291309

292310
for (const ef of exampleFiles) {
293-
const name = (ef.path.split('/').pop() as string).replace('.vue', '')
311+
const fileName = basename(ef.path)
312+
const name = fileName.replace('.vue', '')
294313

295314
// Analyze dependencies for example files
296315
const { descriptor } = parseSFC(ef.content)

0 commit comments

Comments
 (0)