الفكرة
الـ shadcn package فيه API برمجي غير الـ CLI. وكل جزء ليه subpath:
import { getRegistryItems } from "shadcn/registry"import { registryItemSchema } from "shadcn/schema"import { encodePreset } from "shadcn/preset"shadcn/registry — الـ options المشتركة
config
- النوع:
Partial<Config>. - الـ default: الـ registries المدمجة بس.
registries: بتربط كل namespace بـ URL، ومعاه الـ headers والـ env vars اللي محتاجها.
const items = await getRegistryItems(["@nile/money-input"], { config: { registries: { "@nile": "https://nile.dev/r/{name}.json" } },})useCache
- النوع:
boolean، والـ default بتاعهtrue. - الـ cache في الـ memory طول عمر الـ process، والـ key بتاعه هو الـ URL بعد الحل.
- الـ promise نفسه بيتخزن، فلو طلبين لنفس الـ URL في نفس الوقت، بيبقوا fetch واحد.
- سيبه
trueفي الـ scripts والـ CLI. - خليه
falseفي الـ processes اللي شغالة على طول، زي السيرفرات والـ watchers والـ MCP server، لأن الـ registry ممكن تتغير بين الطلبات.
الدوال
getRegistriesConfig(cwd)
بتقرا components.json لو موجود. ولو مش موجود، بتقرا حقل registries من package.json.
getRegistry(name, opts)
- بتجيب registry واحدة بالاسم (
@nile)، أو بـ URL، أو بعنوان GitHub. - الفهرس لازم يكون flat: بترفض أي فهرس remote لسه فيه
include.
getRegistryItems(names, opts)
- بتجيب items بأسمائها الكاملة.
- بترجّع array، وكل item جواه الـ files بالـ
content.
resolveRegistryItems(names, opts)
- بتمشي على
registryDependenciesلكل item. - بتعمل flatten لكل حاجة في object واحد يتسطب:
dependenciesوfilesوcssVarsوdocs.
addRegistryItems(names, opts)
ده shadcn add بس من الكود: بيكتب الملفات، ويسطّب الـ packages، ويضيف الـ env vars والـ CSS والـ Tailwind config.
import { addRegistryItems, getRegistriesConfig } from "shadcn/registry"const cwd = process.cwd()const config = await getRegistriesConfig(cwd)await addRegistryItems(["@nile/agent-rules"], { cwd, config, overwrite: false, silent: true })- مش بيقرا ملفات الـ config لوحده. لازم تديله
configمنgetRegistriesConfigأو تكتبه بإيدك. configفيهregistriesبس بيكفي لو كل الـ items والـ dependencies universal، يعنيregistry:itemأوregistry:fileوكل ملفاتهم ليهاtargetصريح.- الـ items التانية محتاجة config كامل للمشروع، فيه الـ aliases والـ
resolvedPaths. - أي namespace مذكور في item أو dependency لازم يكون موجود في
config. - بيرمي errors بدل ما يقفل الـ process، وعمره ما بيسأل المستخدم.
- الملفات الموجودة بتتساب إلا لو
overwrite: true. - مع npm بيستخدم
--forceلو فيه تعارض peer dependencies مع React 19.
getRegistries(opts)
بتجيب الـ Registry Directory كـ array، وكل عنصر فيه name وurl وhomepage.
searchRegistries(names, opts)
const results = await searchRegistries(["@shadcn", "@nile"], { query: "button", types: ["registry:ui"], limit: 100, offset: 0, config, continueOnError: true, // لو registry وقعت، يكمّل بالباقي})- البحث fuzzy.
- بترجّع
paginationوitems، وكل item فيهregistryوaddCommandArgument، زي@shadcn/button.
loadRegistry(opts) وloadRegistryItem(name, opts)
دول للـ local، يعني اللي بتستخدمهم في route handlers (فصل ٥):
بيقرا registry.json من الـ disk ويحل الـ include. وبيرجّع الفهرس من غير محتوى الملفات. والـ options بتاعته cwd وregistryFile.
بيبني item واحد من الـ source، ويقرا كل ملف من الـ disk ويحطه في content.
getRegistryوgetRegistryItems: remote من الشبكة، والفهرس لازم يكون flat.loadRegistryوloadRegistryItem: local من الـ disk، وبيحلّواincludeلوحدهم.
الـ errors
كل الـ errors بتورث من RegistryError، وتقدر تفرّق بينهم بـ instanceof أو بالـ enum RegistryErrorCode:
import { getRegistry, RegistryNotFoundError, RegistryUnauthorizedError } from "shadcn/registry"try { await getRegistry("@nile")} catch (error) { if (error instanceof RegistryNotFoundError) console.log("مش موجودة") else if (error instanceof RegistryUnauthorizedError) console.log("الـ token غلط") else throw error}shadcn/schema — الـ Zod schemas
import { registryItemSchema } from "shadcn/schema"const result = registryItemSchema.safeParse(json)if (!result.success) console.error(result.error)- الـ schemas:
registrySchemaوregistryItemSchemaوregistryItemFileSchemaوregistryItemTypeSchemaوregistryItemCssVarsSchemaوregistryItemTailwindSchemaوregistryBaseColorSchemaوconfigSchemaوpresetSchema. - الـ types:
RegistryوRegistryItemوRegistryBaseItemوRegistryFontItemوPresetوConfigJson.
shadcn/preset — الـ theme presets
الـ preset هو كود قصير بيختصر إعدادات الـ theme، زي style ولون أساسي وtheme وradius وخط.
import { encodePreset, decodePreset } from "shadcn/preset"const code = encodePreset({ style: "vega", baseColor: "stone", theme: "blue", radius: "large", font: "geist" })// كود قصير URL-safe وأوله رقم الإصدار، زي "bJ4FLU0"const config = decodePreset(code) // كل الحقول، واللي ناقص بياخد الـ defaultdecodePreset("not-a-code") // nullencodePreset: أي حقل مش موجود بياخد قيمته منDEFAULT_PRESET_CONFIG.decodePreset: بيرجّعstyleوbaseColorوthemeوchartColorوiconLibraryوfontوfontHeadingوradiusوmenuAccentوmenuColor.- دوال تانية:
isPresetCodeوisValidPresetوgenerateRandomConfigوgenerateRandomPresetوtoBase62وfromBase62. - constants:
PRESET_BASESوPRESET_STYLESوPRESET_BASE_COLORSوPRESET_THEMESوPRESET_ICON_LIBRARIESوPRESET_FONTSوPRESET_FONT_HEADINGSوPRESET_RADIIوPRESET_MENU_ACCENTSوPRESET_MENU_COLORSوPRESET_CHART_COLORSوDEFAULT_PRESET_CONFIG.