العمل مع S3 والتخزين السحابي في TypeScript: المكتبات والإعداد وأمثلة الكود
\n\nأصبحت مخازن الكائنات السحابية المتوافقة مع Amazon S3 API المعيار الفعلي لتخزين وتسليم الملفات في تطبيقات الويب الحديثة. في بيئة TypeScript وNode.js، توجد عدة أدوات قوية للعمل مع S3. في هذه المقالة، سنستعرض المكتبات الرئيسية، وكيفية إعدادها، وسنقدم أمثلة عملية لأكواد المهام النموذجية: رفع الملفات، تنزيلها، حذفها، وإدارة الحاويات (Buckets).
\n\nالمكتبات الرئيسية للعمل مع S3 في TypeScript
\n\nالحل الأكثر شيوعًا ورسميًا هو AWS SDK for JavaScript v3. هذه المكتبة أعيدت كتابتها بالكامل باستخدام TypeScript، وهي معيارية وتدعم خاصية tree-shaking. البديل هو MinIO JavaScript Client، وهي مكتبة خفيفة الوزن ومتوافقة تمامًا مع S3 API، ومناسبة تمامًا للعمل مع مخازن محلية أو ذاتية الاستضافة متوافقة مع S3 (مثل MinIO وCeph وDigitalOcean Spaces).
\n\nللسيناريوهات البسيطة، يمكن أيضًا استخدام @aws-sdk/client-s3، وهي حزمة منفصلة من AWS SDK v3 تحتوي فقط على الوظائف اللازمة لـ S3.
\n\nالتثبيت والتهيئة
\n\nسنقوم بتثبيت الحزمة الرئيسية للعمل مع S3 عبر AWS SDK v3:
\n\nnpm install @aws-sdk/client-s3 @aws-sdk/credential-providers\n\nللعمل مع MinIO:
\n\nnpm install minio\n\nمثال على تهيئة عميل S3 باستخدام AWS SDK v3:
\n\nimport { S3Client } from "@aws-sdk/client-s3";\nimport { fromEnv } from "@aws-sdk/credential-providers";\n\nconst s3Client = new S3Client({\n region: "us-east-1",\n credentials: fromEnv(), // يستخدم AWS_ACCESS_KEY_ID و AWS_SECRET_ACCESS_KEY من متغيرات البيئة\n});\n\nأما بالنسبة لعميل MinIO، فيتم إعداده على النحو التالي:
\n\nimport * as Minio from "minio";\n\nconst minioClient = new Minio.Client({\n endPoint: "play.min.io",\n port: 9000,\n useSSL: true,\n accessKey: "YOUR_ACCESS_KEY",\n secretKey: "YOUR_SECRET_KEY",\n});\n\nالتصنيف (Typing) والأنواع الصارمة
\n\nمن أهم مزايا TypeScript هو التصنيف الصارم (Strict Typing). توفر كلتا المكتبتين أنواعًا كاملة لجميع الطلبات والاستجابات. على سبيل المثال، عند رفع ملف إلى S3، ستحصل على الإكمال التلقائي لجميع المعاملات:
\n\nimport { PutObjectCommand } from "@aws-sdk/client-s3";\n\nconst uploadParams: PutObjectCommand["input"] = {\n Bucket: "my-bucket",\n Key: "uploads/photo.jpg",\n Body: fileBuffer,\n ContentType: "image/jpeg",\n ACL: "public-read",\n};\n\nconst command = new PutObjectCommand(uploadParams);\nconst result = await s3Client.send(command);\n\nالعمليات الأساسية: الرفع والتنزيل والحذف
\n\n1. رفع ملف (Upload)
\n\nimport { PutObjectCommand } from "@aws-sdk/client-s3";\n\nasync function uploadFile(bucket: string, key: string, body: Buffer | Uint8Array | string) {\n const command = new PutObjectCommand({\n Bucket: bucket,\n Key: key,\n Body: body,\n });\n return await s3Client.send(command);\n}\n\n// مثال على الاستخدام\nconst buffer = Buffer.from("Hello, S3!");\nawait uploadFile("my-bucket", "hello.txt", buffer);\n\n2. تنزيل ملف (Download)
\n\nimport { GetObjectCommand } from "@aws-sdk/client-s3";\n\nasync function downloadFile(bucket: string, key: string): Promise<Buffer> {\n const command = new GetObjectCommand({ Bucket: bucket, Key: key });\n const response = await s3Client.send(command);\n return Buffer.from(await response.Body!.transformToByteArray());\n}\n\n// مثال\nconst fileContent = await downloadFile("my-bucket", "hello.txt");\nconsole.log(fileContent.toString());\n\n3. حذف ملف
\n\nimport { DeleteObjectCommand } from "@aws-sdk/client-s3";\n\nasync function deleteFile(