العمل مع YAML في TypeScript: تحليل، توليد، والتحقق من صحة البيانات

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

العمل مع YAML في TypeScript: تحليل، توليد، والتحقق من صحة البيانات

\n\n

YAML (YAML Ain't Markup Language) — أحد أشهر تنسيقات تسلسل البيانات، المستخدمة بنشاط في ملفات التكوين، DevOps (Docker، Kubernetes، Ansible)، وخطوط أنابيب CI/CD. في نظام TypeScript البيئي، تُستخدم مكتبة js-yaml للعمل مع YAML، والتي توفر دعمًا كاملاً لمواصفات YAML 1.2، بما في ذلك الهياكل المعقدة والعلامات وأنواع البيانات المخصصة.

\n\n

التثبيت والإعداد

\n\n

للبدء، قم بتثبيت المكتبة وأنواعها عبر npm:

\n\n
npm install js-yaml\nnpm install --save-dev @types/js-yaml
\n\n

بعد التثبيت، يمكنك استيراد المكتبة إلى مشروع TypeScript الخاص بك:

\n\n
import * as yaml from 'js-yaml';\nimport * as fs from 'fs';
\n\n

تحليل YAML في TypeScript

\n\n

الوظيفة الرئيسية لقراءة YAML هي yaml.load()، والتي تحول سلسلة YAML إلى كائن JavaScript/TypeScript. لنلق نظرة على مثال مع ملف تكوين:

\n\n
// config.yaml\n// server:\n//   port: 3000\n//   host: "localhost"\n// database:\n//   url: "mongodb://localhost:27017/mydb"\n//   poolSize: 10\n// features:\n//   - logging\n//   - authentication\n\ninterface Config {\n  server: {\n    port: number;\n    host: string;\n  };\n  database: {\n    url: string;\n    poolSize: number;\n  };\n  features: string[];\n}\n\nconst yamlContent = fs.readFileSync('config.yaml', 'utf8');\nconst config = yaml.load(yamlContent) as Config;\n\nconsole.log(config.server.port); // 3000\nconsole.log(config.features); // ['logging', 'authentication']
\n\n

للتحليل الآمن (بدون تنفيذ كود)، استخدم yaml.load() — فهو أكثر أمانًا من yaml.eval()، الذي قد ينفذ كود JavaScript عشوائي.

\n\n

توليد YAML من كائنات TypeScript

\n\n

العملية العكسية — تحويل كائن TypeScript إلى سلسلة YAML — تتم بواسطة الدالة yaml.dump(). هذا مفيد لإنشاء ملفات التكوين بشكل ديناميكي:

\n\n
interface DeploymentConfig {\n  apiVersion: string;\n  kind: string;\n  metadata: { name: string; labels?: Record<string, string> };\n  spec: { replicas: number; selector: Record<string, string> };\n}\n\nconst deployment: DeploymentConfig = {\n  apiVersion: 'apps/v1',\n  kind: 'Deployment',\n  metadata: {\n    name: 'my-app',\n    labels: { app: 'my-app', tier: 'backend' }\n  },\n  spec: {\n    replicas: 3,\n    selector: { matchLabels: { app: 'my-app' } }\n  }\n};\n\nconst yamlString = yaml.dump(deployment, {\n  indent: 2,\n  lineWidth: 120,\n  noRefs: true,\n  sortKeys: true\n});\n\nconsole.log(yamlString);\n// apiVersion: apps/v1\n// kind: Deployment\n// metadata:\n//   labels:\n//     app: my-app\n//     tier: backend\n//   name: my-app\n// spec:\n//   replicas: 3\n//   selector:\n//     matchLabels:\n//       app: my-app
\n\n

العمل مع الأنواع المخصصة

\n\n

تدعم مكتبة js-yaml المخططات وأنواع البيانات المخصصة. هذا مفيد بشكل خاص عند العمل مع التواريخ، التعبيرات العادية، أو الكائنات الخاصة:

\n\n
import * as yaml from 'js-yaml';\n\n// إنشاء نوع مخصص للتواريخ\nconst DateType = new yaml.Type('!date', {\n  kind: 'scalar',\n  resolve: (data: string) => !isNaN(Date.parse(data)),\n  construct: (data: string) => new Date(data),\n  instanceOf: Date,\n  represent: (date: Date) => date.toISOString()\n});\n\n// إنشاء مخطط يدعم الأنواع القياسية والمخصصة\nconst schema = yaml.DEFAULT_SCHEMA.extend([DateType]);\n\nconst yamlWithDates = `\nevent: !date 2024-12-25T10:00:00Z\ntitle: "ندوة عيد الميلاد"\n`;\n\nconst parsed = yaml.load(yamlWithDates, { schema });\nconsole.log(parsed.event instanceof Date); // true\nconsole.log(parsed.event.toLocaleDateString('ar-SA')); // 25/12/2024
\n\n

التحقق من صحة YAML مع

توصيات