الوضع العادي
shadcn searchبيجيبregistry.jsonكله ويفلتر عنده على الجهاز.- ده كويس لأغلب الـ registries، ومحتاج ملف static بس.
- مع آلاف الـ items بيبقى تقيل، فتقدر تخلي السيرفر هو اللي يدوّر.
بيشتغل إزاي؟
الـ CLI بيزوّد query params على طلب الفهرس:
terminal
npx shadcn@latest search @nile --query money --limit 50الطلب
GET https://nile.dev/r/registry.json?q=money&limit=50&offset=0- registry static: بيتجاهل الـ params ويرجّع الفهرس كله، والـ CLI يفلتر هو.
- registry dynamic: بيفلتر عنده ويرجّع النتايج ومعاها
pagination. - وجود
paginationفي الرد هو الإشارة الوحيدة. أول ما الـ CLI يشوفها، يعتبر النتايج متفلترة وميفلترش تاني. ومفيش أي config أو negotiation.
الـ params
| الـ param | معناه |
|---|---|
q | كلمة البحث |
type | أنواع مفصولة بفاصلة، زي registry:ui,registry:block |
limit | أقصى عدد items |
offset | كام item يتعدّى |
- كلهم اختياريين.
- من غير
qوtype: المفروض يرجع كل الـ items مقسمة صفحات.
شكل الرد
registry.json?q=money&limit=2
{ "name": "nile", "homepage": "https://nile.dev", "items": [ { "name": "money-input", "type": "registry:ui", "description": "Input للمبالغ بالجنيه." }, { "name": "money-format", "type": "registry:lib", "description": "تنسيق المبالغ." } ], "pagination": { "total": 7, "offset": 0, "limit": 2, "hasMore": true }}- كل item محتاج
nameوtypeوdescriptionبس. مش محتاجfilesولاdependencies، لأن الـ CLI بيجيب الـ item كامل وقتadd. total: عدد كل النتايج المطابقة.offset: كام اتعدّى.limit: أقصى عدد في الرد ده.hasMore: فيه نتايج بعد الصفحة دي ولا لأ.
السيرفر
app/r/registry.json/route.ts
import { NextRequest, NextResponse } from "next/server"export async function GET(request: NextRequest) { const sp = request.nextUrl.searchParams const query = sp.get("q") const types = sp.get("type")?.split(",") const limit = Number(sp.get("limit") ?? 100) const offset = Number(sp.get("offset") ?? 0) const { items, total } = await searchItems({ query, types, limit, offset }) return NextResponse.json({ name: "nile", homepage: "https://nile.dev", items, pagination: { total, offset, limit, hasMore: offset + limit < total }, })}searchItems ممكن تبقى query على الداتابيز، أو full-text index، أو search service من برّه.
البحث في كذا registry
- registry واحدة: الـ CLI بيبعت كل الـ params ويستخدم الـ
paginationبتاعتك زي ما هي. - كذا registry زي
search @nile @lib: الـoffsetالعام مينفعش يتقسم عليهم. فالـ CLI بيبعت لكل واحدةqوtypeوlimitكبير كفاية يملا الصفحة (offset + limit)، وبعدين يدمج ويقسّم صفحات عنده. - السيرفر لسه بيفلتر في الحالة دي، فكل registry بترجّع المطابق بس.
مع الـ auth
الـ CLI بيبعت نفس الـ headers والـ params المتعرفة مع طلب البحث. فتقدر تقصر النتايج على اللي المستخدم ده يقدر يشوفه:
route.ts (جزء)
const token = request.headers.get("authorization")?.replace("Bearer ", "")const team = await getTeamFromToken(token)const { items, total } = await searchItems({ query: sp.get("q"), team })التوافق مع القديم
- الـ registries الـ static مش محتاجة أي تغيير، والـ file server بيتجاهل الـ params.
- إصدارات الـ CLI القديمة بتطلب الفهرس من غير params وبتتجاهل
pagination. عشان كده رد السيرفر من غير params لازم يبقى معقول، زي أول صفحة. - الترتيب قرارك إنت. لو رجّعت نتايج متفلترة، الـ CLI بيحافظ على ترتيبك ومش بيرتب تاني.
جرّب
terminal
curl "https://nile.dev/r/registry.json?q=money&limit=10"npx shadcn@latest search @nile --query moneyاتأكد إن الرد فيه pagination، وإن الـ items المطابقة بس هي اللي رجعت.
خلّصت الفصل لما
🧠 اختبر نفسك
١) الـ CLI عرف منين إن السيرفر فلتر النتايج؟
من وجود pagination في الرد.
٢) نتايج البحث محتاجة files؟
لأ. name وtype وdescription كفاية، والـ item الكامل بيتجاب وقت add.
٣) السيرفر بيرجّع 20 بالكتير والـ CLI طلب 50. إيه اللي هيحصل؟
الـ CLI ممكن يعتبر الـ registry خلصت في الصفحات اللي بعد كده، وبعض النتايج متوصلش.