تخطَّ إلى المحتوى الرئيسي
PPDF123

@pdf123/sdk: حزمة PDF123 لـ TypeScript

@pdf123/sdk هو TypeScript SDK لواجهة PDF123 البرمجية الخاصة بملفات PDF. يشغّل 95 أداة مثل الدمج والتقسيم والضغط وOCR، ويحدّد أنواع خيارات كل أداة، ويضيف الدفعات والتسلسلات والتعامل مع كلمات المرور وأخطاء محدّدة الأنواع. وهو وحدة ES بلا أي اعتمادات وقت التشغيل.

@pdf123/sdkNode 20.3 أو أحدث، أو Bun

التثبيت

npm install @pdf123/sdk
في هذه الصفحة

كيف أثبّت SDK؟

ثبّت الحزمة بمدير الحزم الذي تستخدمه. يلزم Node 20.3 أو أحدث، أو Bun، أو أداة تجميع (bundler). أنواع TypeScript مضمّنة، ولا حاجة إلى @types/node.

Installbash
npm install @pdf123/sdk

يعمل bun add @pdf123/sdk وpnpm add @pdf123/sdk بالطريقة نفسها.

كيف أدمج ملفي PDF؟

أنشئ عميلًا، وشغّل الأداة merge على ملفين، واحفظ النتيجة. إذا لم تمرّر أي خيارات، يتصل العميل بواجهة API العامة بصورة مجهولة.

Merge and savets
import { Pdf123Client } from "@pdf123/sdk";
import { readFileInput, saveResult } from "@pdf123/sdk/node";

const client = new Pdf123Client();
const result = await client.run("merge", {
  input: [await readFileInput("a.pdf"), await readFileInput("b.pdf")],
});
const path = await saveResult(result, { output: "merged.pdf" });
console.log(path);

تحمل النتيجة البايتات في data، ونوع المحتوى في contentType، واسم الملف الذي حدّده الخادم في filename، والحقل json للأدوات التي تعيد تقريرًا. والعملية نفسها متاحة على الموقع باسم دمج PDF.

أي نقطة دخول أستورد؟

نقطة الدخولتحتاج إلىتوفّر
@pdf123/sdkfetch فقطPdf123Client وTOOLS وgetTool وPdf123Error ودوال الكتالوج المساعدة
@pdf123/sdk/nodeNode أو BunreadFileInput وfileSource وsaveResult وcheckOutput وclientFromEnv

استورد من نقطة الدخول الجذرية في المتصفحات وبيئات الحافة (edge)، وأضف نقطة الدخول node فقط حيث تقرأ الملفات أو تكتبها.

ما الدوال التي يوفرها العميل؟

الدالةوظيفتها
run(tool, { input, params })تشغّل أداة واحدة وتُرجع نتيجة
runBatch(tool, inputs, options)تشغّل أداة ذات ملف واحد على مدخلات كثيرة وتُرجع عنصرًا لكل مدخل
pipeline(steps, input, options)تشغّل عدة أدوات في طلب واحد
call(target, files, fields)ترسل طلبًا خامًا إلى معرّف أداة أو معرّف عملية أو مسار /api/...
upload(file)ترفع ملفًا واحدًا عبر واجهة الرفع المجزّأ وتُرجع معرّفه

دوال الكتالوج المساعدة دوال عادية: TOOLS تسرد كل الأدوات، وgetTool(id) تُرجع حقول أداة واحدة وقيمها الافتراضية وأنواع الملفات المقبولة، وتساعد toolGroup وtoolSummary وmatchesQuery وsuggestTools على بناء منتقيات الأدوات. يطبع سطر الأوامر الكتالوج نفسه بالأمرين pdfx list وpdfx describe.

كيف أمرّر الخيارات إلى أداة؟

الحقل params محدّد الأنواع لكل أداة. فهو يقبل حقول تلك الأداة فقط، ولا تقبل حقول الاختيار إلا قيمها المسموح بها. وتُفحص الحقول الرقمية مقابل حدّها الأدنى والأقصى، ويُفحص الملف مقابل الأنواع المقبولة، وذلك كله قبل رفع أي شيء. وتُملأ القيم الافتراضية التي يحتاجها الخادم.

Watermark with optionsts
const marked = await client.run("watermark", {
  input: await readFileInput("a.pdf"),
  params: { watermarkText: "DRAFT", fontSize: 40, rotation: -45 },
});
await saveResult(marked, { output: "draft.pdf" });

السلسلة الفارغة تعني «غير معيَّن»، فتُطبَّق القيمة الافتراضية. راجع علامة مائية PDF لمعرفة وظيفة كل خيار.

كيف أعالج ملفات كثيرة؟

تشغّل runBatch أداة ذات ملف واحد، مثل الضغط أو التدوير أو الحماية، على كل مدخل بالخيارات نفسها. وتعالج ملفين في وقت واحد افتراضيًا. ولا يوقف ملف معطوب بقية الملفات.

Batch with cancellationts
import { fileSource, saveResult } from "@pdf123/sdk/node";

const controller = new AbortController();
const entries = await client.runBatch("compress", [fileSource("a.pdf"), fileSource("b.pdf")], {
  concurrency: 2,
  signal: controller.signal,
  onResult: async (entry, index) => {
    if (entry.ok) await saveResult(entry.result, { output: "compressed/" });
  },
});
console.log(entries.map((entry) => entry.ok));
  • fileSource(path) مصدر كسول لا يُقرأ إلا حين يأخذه أحد العاملين، فلا تجتمع ملفات كبيرة كثيرة في الذاكرة معًا.
  • يتلقى onResult كل نتيجة فور اكتمالها. احفظها هناك، فإذا أُلغيت العملية عند الملف 50 من 100 بقيت الملفات التسعة والأربعون الأولى. ومع retainData: false لا تحتفظ المصفوفة المُعادة بالبايتات.
  • يقبل أي استدعاء الخيار timeoutMs وsignal لإلغائه.
  • يتحول idempotencyKey إلى <key>:<index> لكل ملف.

أدوات المرشِّح (المعرّفات التي تبدأ بـ filter-) تُرجع matched: false بدلًا من رمي خطأ حين لا يتحقق شرطها. وفي الدفعة يُحتسب مثل هذا الملف ضمن ok.

كيف أسلسل الأدوات في طلب واحد؟

ترسل pipeline قائمة خطوات ومدخلًا واحدًا أو أكثر. ويمرّر الخادم ناتج كل خطوة إلى الخطوة التالية.

Merge, watermark, compressts
const piped = await client.pipeline(
  [{ tool: "merge" }, { tool: "watermark", params: { watermarkText: "DRAFT" } }, { tool: "compress" }],
  [await readFileInput("a.pdf"), await readFileInput("b.pdf")],
);
await saveResult(piped, { output: "out.pdf" });

تقبل التسلسلات خيارات كلمة المرور نفسها التي تقبلها run.

كيف أتعامل مع ملفات PDF المشفّرة؟

مرّر password إلى run لفتح المدخل المشفّر أولًا. يتم فتح القفل وتشغيل الأداة في طلب واحد. وللأدوات التي تقبل عدة ملفات، مثل الدمج، مرّر passwords بعنصر لكل مدخل، واستخدم سلسلة فارغة للملف المفتوح. يُفتح قفل كل ملف على حدة.

Passwordsts
await client.run("compress", { input: await readFileInput("locked.pdf"), password: "secret" });
await client.run("merge", {
  input: [await readFileInput("locked.pdf"), await readFileInput("open.pdf")],
  passwords: ["secret", ""],
});

وفي الدفعة تُرجع passwordFor(file, index) كلمة المرور لكل مدخل. ولإزالة الحماية بصورة دائمة استخدم أداة فتح القفل.

كيف تعمل الأخطاء؟

تُرمى حالات الفشل على هيئة Pdf123Error. وله الحقل status (يكون undefined إذا لم تصل استجابة)، وcode، وreason للسبب الدقيق مثل password_required، وproblem الذي يحمل تفاصيل المشكلة من الخادم، وتتضمن hint إن وُجد. وتُرمى أخطاء التحقق قبل رفع أي شيء.

Handle an errorts
import { Pdf123Error } from "@pdf123/sdk";

try {
  await client.run("compress", { input: await readFileInput("locked.pdf") });
} catch (error) {
  if (error instanceof Pdf123Error) {
    console.error(error.status, error.code, error.reason, error.problem?.hint);
  } else {
    throw error;
  }
}

رموز الخادم مسرودة في رموز الأخطاء. ويضيف العميل رموزه الخاصة التالية:

الرمزالمعنى
network_errorلم يصل أي ردّ على الطلب
timeoutتجاوز طلب المهلة timeoutMs
cancelledأوقف signal الخاص بك الاستدعاء
input_unreadableتعذّرت قراءة مسار محلي
output_unwritableتعذّر حفظ النتيجة في المسار المعطى
output_mismatchرفضت saveResult كتابة ملف ZIP باسم ينتهي بـ .pdf
unsupported_file_typeنوع الملف غير مقبول في الأداة
unknown_toolمعرّف الأداة غير موجود؛ وتقترح الرسالة معرّفات قريبة
invalid_targetرفضت call مسار /api/... يحتوي على مقاطع .. أو . أو فارغة
no_contentلم يكن لدى الأداة ما تُرجعه (HTTP 204)

لا تستبدل saveResult أبدًا ملفًا موجودًا داخل مجلد. استدعِ checkOutput(output, { several }) أولًا لتعرف قبل الرفع إن كان يمكن الكتابة في المسار.

أي إعدادات TypeScript والوحدات تعمل؟

تُحلّ الأنواع ضمن إعدادات moduleResolution التالية: nodenext وnode16 وbundler وnode10 الأقدم، بما في ذلك المسار الفرعي @pdf123/sdk/node. الحزمة وحدة ES، لذا يعمل import في كل مكان. ويعمل require("@pdf123/sdk") من CommonJS على Node 22.12 أو أحدث، وهو غير متاح على Node 20.

كيف أضبط العميل؟

الخيارمتغيّر البيئةالقيمة الافتراضية
baseUrlPDFX_API_BASEhttps://pdf123.xyz
apiKeyPDFX_API_KEYلا شيء، أي مجهول
timeoutMsلا يوجد300000

لا يقرأ new Pdf123Client() متغيّرات البيئة أبدًا. أما clientFromEnv() من @pdf123/sdk/node فتقرأ المتغيّرين، وتتقدّم عليها الخيارات التي تمرّرها. يُرسل المفتاح في الترويسة X-API-KEY؛ راجع المصادقة.

لاستخدام خادمك الخاص، عيّن baseUrl على عنوانه، مثل http://localhost:8080. راجع الاستضافة الذاتية.

هل يمكنني استخدام SDK في المتصفح؟

نعم. نقطة الدخول الجذرية @pdf123/sdk تحتاج إلى fetch فقط وليس لها اعتماد على Node. أنشئ كائنات FileInput بنفسك من File أو Uint8Array، لأن دوال الملفات موجودة في نقطة الدخول node. ولا تضمّن مفتاح API في شيفرة متصفح يستطيع الآخرون قراءتها.

الأسئلة الشائعة

هل يحتاج SDK إلى مفتاح API؟

لا. العميل المُنشأ بلا خيارات يستدعي واجهة API العامة بصورة مجهولة. مرّر apiKey لإرسال الترويسة X-API-KEY.

أي إصدار من Node يحتاج إليه SDK؟

Node 20.3 أو أحدث، أو Bun. تحتاج نقطة الدخول الجذرية إلى fetch فقط، لذا تعمل أيضًا في المتصفحات وأدوات التجميع.

كيف أستخدم أداة أحدث من SDK؟

استخدم client.call. تقبل معرّف أداة، أو معرّف عملية مثل general/merge-pdfs، أو مسار /api/...، إضافة إلى الملفات والحقول. لا يجري أي تحقق أو ملء للقيم الافتراضية محليًا.

ما أكبر ملف يمكنني رفعه؟

تمرّ المدخلات التي يتجاوز مجموعها 95 MB عبر واجهة الرفع المجزّأ تلقائيًا. أما جسم الطلب المباشر الواحد فحدّه 100 MiB.

لماذا رمى استدعائي خطأ مع ملف PDF بلا جداول؟

تردّ أدوات مثل pdf-to-csv وpdf-to-xlsx بلا محتوى حين لا يحتوي ملف PDF على جدول يمكن اكتشافه. يرمي SDK الخطأ Pdf123Error بالرمز no_content بدلًا من إرجاع ملف فارغ. افحص هذا الرمز إن كانت النتيجة الفارغة مقبولة عندك.