import { exec } from "child_process" import { promises as fs } from "fs" import path from "path" import { rimraf } from "rimraf" import { getAllBlocks } from "@/lib/blocks" import { registry } from "@/registry/index" async function buildRegistryIndex() { let index = `/* eslint-disable @typescript-eslint/ban-ts-comment */ /* eslint-disable @typescript-eslint/no-explicit-any */ // @ts-nocheck // This file is autogenerated by scripts/build-registry.ts // Do not edit this file directly. import * as React from "react" export const Index: Record = {` for (const item of registry.items) { const resolveFiles = item.files?.map( (file) => `registry/new-york-v4/${file.path}` ) if (!resolveFiles) { continue } const componentPath = item.files?.[0]?.path ? `@/registry/new-york-v4/${item.files[0].path}` : "" index += ` "${item.name}": { name: "${item.name}", description: "${item.description ?? ""}", type: "${item.type}", registryDependencies: ${JSON.stringify(item.registryDependencies)}, files: [${item.files?.map((file) => { const filePath = `registry/new-york-v4/${typeof file === "string" ? file : file.path}` const resolvedFilePath = path.resolve(filePath) return typeof file === "string" ? `"${resolvedFilePath}"` : `{ path: "${filePath}", type: "${file.type}", target: "${file.target ?? ""}" }` })}], component: ${ componentPath ? `React.lazy(async () => { const mod = await import("${componentPath}") const exportName = Object.keys(mod).find(key => typeof mod[key] === 'function' || typeof mod[key] === 'object') || item.name return { default: mod.default || mod[exportName] } })` : "null" }, categories: ${JSON.stringify(item.categories)}, meta: ${JSON.stringify(item.meta)}, },` } index += ` }` console.log(`#️⃣ ${Object.keys(registry.items).length} items found`) // Write style index. rimraf.sync(path.join(process.cwd(), "registry/__index__.tsx")) await fs.writeFile(path.join(process.cwd(), "registry/__index__.tsx"), index) } async function buildRegistryJsonFile() { // 1. Fix the path for registry items. const fixedRegistry = { ...registry, items: registry.items.map((item) => { const files = item.files?.map((file) => { return { ...file, path: `registry/new-york-v4/${file.path}`, } }) return { ...item, files, } }), } // 2. Write the content of the registry to `registry.json` rimraf.sync(path.join(process.cwd(), `registry.json`)) await fs.writeFile( path.join(process.cwd(), `registry.json`), JSON.stringify(fixedRegistry, null, 2) ) // 3. Copy the registry.json to the www/public/r/styles/new-york-v4 directory. await fs.cp( path.join(process.cwd(), "registry.json"), path.join( process.cwd(), "../www/public/r/styles/new-york-v4/registry.json" ), { recursive: true } ) } async function buildRegistry() { return new Promise((resolve, reject) => { // Use local shadcn copy. const process = exec( `node ../../packages/shadcn/dist/index.js build registry.json --output ../www/public/r/styles/new-york-v4` ) // exec( // `pnpm dlx shadcn build registry.json --output ../www/public/r/styles/new-york-v4` // ) process.on("exit", (code) => { if (code === 0) { resolve(undefined) } else { reject(new Error(`Process exited with code ${code}`)) } }) }) } async function syncRegistry() { // Store the current registry content const registryDir = path.join(process.cwd(), "registry") const registryIndexPath = path.join(registryDir, "__index__.tsx") let registryContent = null try { registryContent = await fs.readFile(registryIndexPath, "utf8") } catch { // File might not exist yet, that's ok } // 1. Call pnpm registry:build for www. await exec("pnpm --filter=www registry:build") // 2. Copy the www/public/r directory to v4/public/r. rimraf.sync(path.join(process.cwd(), "public/r")) await fs.cp( path.resolve(process.cwd(), "../www/public/r"), path.resolve(process.cwd(), "public/r"), { recursive: true } ) // 3. Restore the registry content if we had it if (registryContent) { await fs.writeFile(registryIndexPath, registryContent, "utf8") } } async function buildBlocksIndex() { const blocks = await getAllBlocks(["registry:block"]) const payload = blocks.map((block) => ({ name: block.name, description: block.description, categories: block.categories, })) rimraf.sync(path.join(process.cwd(), "registry/__blocks__.json")) await fs.writeFile( path.join(process.cwd(), "registry/__blocks__.json"), JSON.stringify(payload, null, 2) ) } try { console.log("🗂️ Building registry/__index__.tsx...") await buildRegistryIndex() console.log("🗂️ Building registry/__blocks__.json...") await buildBlocksIndex() console.log("💅 Building registry.json...") await buildRegistryJsonFile() console.log("🏗️ Building registry...") await buildRegistry() console.log("🔄 Syncing registry...") await syncRegistry() } catch (error) { console.error(error) process.exit(1) }