طبقة التحميل load.ts
تحميل JSON + تحقق Ajv schema + التسطيح.
لا تقوم load.ts إلا بالتحقق الهيكلي (JSON Schema). أما التحقق الدلالي (مطابقة الأنواع للقيم، سلامة المراجع، الكشف عن الحلقات) فيتم في resolve.ts.
الأنواع
Section titled “الأنواع”interface LoadedTokenFile { fileName: string namespace: string // بادئة مساحة الأسماء (color / radius / zIndex؛ سلسلة فارغة تعني أن المفاتيح العلوية هي مساحة الأسماء) isDark: boolean defaultType?: TokenType // $type على مستوى الملف description?: string flat: Map<string, RawToken> // path ← RawToken (مُسطَّحة، وتشمل بادئة مساحة الأسماء)}قائمة الدوال
Section titled “قائمة الدوال”readJson<T>(filePath: string): T
Section titled “readJson<T>(filePath: string): T”قراءة ملف JSON ثم JSON.parse. دالة أداة داخلية.
listJsonFiles(dir: string): string[]
Section titled “listJsonFiles(dir: string): string[]”إدراج ملفات .json في الدليل، مع استثناء schema.json، ثم ترتيبها وتحويلها إلى مسارات مطلقة. يضمن الترتيب ثبات تسلسل التحميل (وهو ما يؤثر في رسائل الأخطاء وقابلية إعادة إنتاج المنتجات).
namespaceFromFileName(fileName: string): string
Section titled “namespaceFromFileName(fileName: string): string”اشتقاق مساحة الأسماء من اسم الملف (منطق التراجع عند غياب $namespace): حذف لاحقة .json ثم التقسيم على -، مع إبقاء المقطع الأول كما هو وكتابة الحرف الأول من المقاطع الأخرى كبيرًا، ثم الدمج.
| اسم الملف | نتيجة الاشتقاق |
|---|---|
color.json |
color |
z-index.json |
zIndex |
color-dark.json |
colorDark |
flatten(obj, prefix, out, inheritedType?): void
Section titled “flatten(obj, prefix, out, inheritedType?): void”طي JSON المتداخل بشكل متكرر إلى Map<path, RawToken> مسطحة:
- تخطي جميع المفاتيح التي تبدأ بـ
$(الخصائص الوصفية) - وصل المسار:
prefix ? prefix + '.' + key : key - العقدة التي ليست رمزًا طرفيًا ولا كائنًا ← يُطلق
مسار الرمز X ليس رمزًا طرفيًا ولا مجموعة
المنطق الأساسي لوراثة النوع: يُنقل $type المُعلَن في المجموعة (بما في ذلك جذر الملف) نزولًا على الشجرة، لكنه يُخبز في الرموز الحرفية فقط:
// ترث الرموز الحرفية نوع المجموعة؛ أما رموز ref فتبقى undefined، ويُترك التحديد لـ resolve ليأخذ النوع من الهدف المُشار إليهif (node.type === undefined && node.ref === undefined && groupType !== undefined) { out.set(path, { ...node, type: groupType })}لا تُخبز رموز ref عمدًا، ويُترك قرار النوع لمرحلة resolve (الخطوة الأولى من أولويات الأنواع ذات الطبقات الثلاث، راجع نظام الأنواع).
isRawToken(node: unknown): node is RawToken
Section titled “isRawToken(node: unknown): node is RawToken”حارس نوع: العقدة التي تحتوي على مفتاح value أو ref تُعتبر رمزًا طرفيًا؛ وإلا فتُعتبر مجموعة.
loadTokenFiles(tokensDir = <root>/tokens): LoadedTokenFile[]
Section titled “loadTokenFiles(tokensDir = <root>/tokens): LoadedTokenFile[]”تحميل دليل الرموز:
- قراءة
tokens/schema.jsonوتجميعه عبر Ajv (allErrors: true, strict: false) - قراءة كل ملف JSON والتحقق منه، وعند الفشل يُطلق
فشل التحقق من ملف الرموز: <path>مع قائمة أخطاء منسَّقة - مساحة الأسماء: الأولوية لـ
raw.$namespace(عندما يكون سلسلة نصية)، وإلاnamespaceFromFileName - الطي عبر
flatten(raw, namespace, flat) - التجميع
{ fileName, namespace, isDark: raw.$dark === true, defaultType: raw.$type, description: raw.$description, flat }
loadSpecs(specsDir = <root>/specs): ComponentSpec[]
Section titled “loadSpecs(specsDir = <root>/specs): ComponentSpec[]”تحميل specs/*.json بالبنية نفسها، ويُطلق عند فشل التحقق فشل التحقق من عقد المكوّن.
loadCases(casesDir = <root>/cases): ComponentCases[]
Section titled “loadCases(casesDir = <root>/cases): ComponentCases[]”تحميل cases/*.json بالبنية نفسها، ويُطلق عند فشل التحقق فشل التحقق من الحالات الذهبية.
formatErrors(errors: ErrorObject[]): string
Section titled “formatErrors(errors: ErrorObject[]): string”تحويل كائنات أخطاء Ajv إلى قائمة ذات مسافات بادئة (instancePath + message).
readVersion(): string
Section titled “readVersion(): string”قراءة version من package.json، كجزء من تعليق رأس كل منتج («المصدر: @lh-ui/core tokens @ v0.0.1»).
طبقات التحقق
Section titled “طبقات التحقق”| الطبقة | أين | ماذا تفعل |
|---|---|---|
| التحقق الهيكلي | load.ts |
JSON Schema: الحقول الإلزامية، قيم التعداد، التعابير القياسية للتسمية، additionalProperties: false |
| التحقق الدلالي | resolve.ts |
مطابقة النوع للقيمة (assertTypedValue)، وجود المراجع، الكشف عن حلقات المراجع |
| التحقق الاتساقي | scripts/verify-specs.mts |
الاتساق المتبادل بين المواصفات والحالات |
سبب هذا التقسيم الطبقي هو عجز JSON Schema عن التعبير عن قيود عبر الملفات والعقد مثل «يجب أن يكون هدف ref موجودًا» و«يجب أن يطابق النوع القيمة».
Copyright © 2024-2026 FengMo WenXue