Advanced

Berkontribusi Membuat Penyedia

Pelajari cara berkontribusi membuat penyedia file baru untuk Nuxt PDF Kit

Berkontribusi Membuat Penyedia Baru

Ingin menambahkan dukungan untuk OneDrive, Dropbox, S3, atau layanan penyimpanan file lainnya? Panduan ini akan memandu kamu melalui prosesnya!

Ringkasan

Menambahkan penyedia baru melibatkan tiga langkah utama:

  1. Menambahkan tipe penyedia ke definisi TypeScript
  2. Membuat logika transformasi di dalam composable
  3. Menambahkan rute server (jika diperlukan untuk CORS/autentikasi)

Langkah 1: Tambahkan Tipe Penyedia

Edit file src/runtime/types.ts untuk menambahkan penyedia baru kamu:

// Sebelum
export type PdfProvider = "url" | "gdrive" | "custom";

// Sesudah
export type PdfProvider = "url" | "gdrive" | "onedrive" | "custom";

Langkah 2: Tambahkan Logika Transformasi

Edit file src/runtime/composables/usePdfKitProvider.ts:

/**
 * Mengubah tautan berbagi OneDrive menjadi URL unduhan langsung
 */
function transformOneDrive(src: string, config?: ProviderConfig): string {
  // Bersihkan ID share
  const shareId = src.trim();

  // Dapatkan rute proxy dari config atau gunakan default
  const proxyRoute = config?.baseUrl || "/pdf-proxy/onedrive";

  return `${proxyRoute}/${shareId}.pdf`;
}

// Tambahkan ke fungsi utama
export function usePdfKitProvider(
  provider: PdfProvider = "url",
  src: string,
  config?: ProviderConfig,
): string {
  if (!src) {
    console.warn("[nuxt-pdf-kit] Src kosong diberikan ke usePdfKitProvider");
    return "";
  }

  switch (provider) {
    case "gdrive":
      return transformGoogleDrive(src, config);
    case "onedrive": // Tambahkan ini
      return transformOneDrive(src, config);
    case "custom":
      return transformCustom(src, config);
    case "url":
    default:
      return src;
  }
}

Langkah 3: Buat Rute Server (Opsional)

Jika penyedia kamu membutuhkan penanganan CORS atau autentikasi, buatlah rute server:

Buat file rute

src/runtime/server/routes/pdf-proxy/onedrive/[id].ts:

import {
  createError,
  defineEventHandler,
  sendStream,
  setResponseHeader,
} from "h3";

export default defineEventHandler(async (event) => {
  // 1. Ekstrak ID file dari URL
  const path = event.path || event.node.req.url || "";
  const match = path.match(/\/pdf-proxy\/onedrive\/([^/]+?)(?:\.pdf)?$/);
  const shareId = match ? match[1] : "";

  if (!shareId) {
    throw createError({
      statusCode: 400,
      statusMessage: "ID berbagi OneDrive hilang",
    });
  }

  // 2. Buat URL unduhan OneDrive
  // Contoh: Ubah tautan berbagi menjadi unduhan langsung
  const oneDriveUrl = `https://api.onedrive.com/v1.0/shares/${shareId}/root/content`;

  try {
    // 3. Fetch dari OneDrive
    const response = await fetch(oneDriveUrl, {
      headers: {
        "User-Agent": "Mozilla/5.0...",
        Accept: "*/*",
      },
      redirect: "follow",
    });

    if (!response.ok) {
      throw createError({
        statusCode: response.status,
        statusMessage: `OneDrive Error: ${response.statusText}`,
      });
    }

    // 4. Periksa Content-Type
    const contentType = response.headers.get("content-type");
    if (contentType && !contentType.includes("application/pdf")) {
      throw createError({
        statusCode: 502,
        statusMessage: "OneDrive tidak mengembalikan file PDF",
      });
    }

    // 5. Atur header respons
    setResponseHeader(event, "Content-Type", "application/pdf");
    setResponseHeader(event, "Cache-Control", "public, max-age=86400");
    setResponseHeader(event, "Access-Control-Allow-Origin", "*");

    // 6. Stream respons
    if (!response.body) {
      throw createError({
        statusCode: 500,
        statusMessage: "Respons kosong dari OneDrive",
      });
    }

    return sendStream(event, response.body);
  } catch (error: any) {
    console.error("[nuxt-pdf-kit] OneDrive error:", error.message);

    if (error.statusCode) {
      throw error;
    }

    throw createError({
      statusCode: 500,
      statusMessage: error.message || "Internal Server Error",
    });
  }
});

Daftarkan rute

Edit src/module.ts untuk mendaftarkan rute server kamu:

// Tambahkan rute server untuk penyedia
nuxt.hook("nitro:config", (nitroConfig) => {
  nitroConfig.handlers = nitroConfig.handlers || [];

  // Rute proxy Google Drive
  nitroConfig.handlers.push({
    route: "/pdf-proxy/gdrive/**",
    handler: resolver.resolve("./runtime/server/routes/pdf-proxy/gdrive/[id]"),
  });

  // Rute proxy OneDrive (TAMBAHKAN INI)
  nitroConfig.handlers.push({
    route: "/pdf-proxy/onedrive/**",
    handler: resolver.resolve(
      "./runtime/server/routes/pdf-proxy/onedrive/[id]",
    ),
  });
});

Langkah 4: Tambahkan Pengujian (Tests)

Buat file pengujian test/providers.test.ts:

import { describe, it, expect } from "vitest";
import { usePdfKitProvider } from "../src/runtime/composables/usePdfKitProvider";

describe("usePdfKitProvider", () => {
  it("mengubah ID berbagi OneDrive dengan benar", () => {
    const result = usePdfKitProvider(
      "onedrive",
      "u!aHR0cHM6Ly8xZHJ2Lm1zL2IvcyFBcXRhYmNkZWY",
    );

    expect(result).toBe(
      "/pdf-proxy/onedrive/u!aHR0cHM6Ly8xZHJ2Lm1zL2IvcyFBcXRhYmNkZWY.pdf",
    );
  });

  it("menggunakan baseUrl kustom untuk OneDrive", () => {
    const result = usePdfKitProvider("onedrive", "share-123", {
      baseUrl: "/custom-proxy",
    });

    expect(result).toBe("/custom-proxy/share-123.pdf");
  });
});

Langkah 5: Tambahkan Dokumentasi

Buat dokumentasi untuk penyedia kamu di docs/content/en/5.advanced/2.providers.md:

### Penyedia OneDrive

Memuat PDF dari tautan berbagi OneDrive.

\`\`\`vue
<template>
<NuxtPdfKit
    provider="onedrive"
    src="u!aHR0cHM6Ly8xZHJ2Lm1zL2IvcyFBcXRhYmNkZWY"
  />
</template>
\`\`\`

**Cara mendapatkan ID Berbagi OneDrive:**

1. Klik kanan file kamu di OneDrive
2. Klik "Share" (Bagikan) → "Copy link" (Salin tautan)
3. Ekstrak ID berbagi dari URL tersebut
4. Gunakan ID tersebut sebagai prop `src`

Langkah 6: Kirim Pull Request

  1. Fork repositori di GitHub
  2. Buat branch fitur: git checkout -b feat/onedrive-provider
  3. Commit perubahan kamu: git commit -m "feat: add OneDrive provider support"
  4. Push ke fork kamu: git push origin feat/onedrive-provider
  5. Buka Pull Request dengan:
    • Deskripsi yang jelas tentang penyedia
    • Contoh penggunaan
    • Batasan atau masalah yang diketahui

Checklist Penyedia

Sebelum mengirimkan PR kamu, pastikan hal-hal berikut:

  • Tipe penyedia ditambahkan ke types.ts
  • Logika transformasi ditambahkan ke usePdfKitProvider.ts
  • Rute server dibuat (jika diperlukan)
  • Rute server didaftarkan di module.ts
  • Tes ditambahkan dan lolos
  • Dokumentasi ditambahkan
  • Contoh penggunaan di playground
  • Tipe TypeScript sudah benar
  • Tidak ada error linting

Praktik Terbaik

Penanganan Error

Selalu berikan pesan error yang jelas:

if (!fileId) {
  throw createError({
    statusCode: 400,
    statusMessage: "ID File hilang. Mohon berikan tautan berbagi yang valid.",
  });
}

Logging

Gunakan format logging yang konsisten:

console.log("[nuxt-pdf-kit] OneDrive - Memproses file:", fileId);
console.error("[nuxt-pdf-kit] OneDrive error:", error.message);

Caching

Atur header cache yang sesuai:

// Cache selama 24 jam
setResponseHeader(event, "Cache-Control", "public, max-age=86400");

// Atau nonaktifkan cache untuk file sensitif
setResponseHeader(
  event,
  "Cache-Control",
  "no-cache, no-store, must-revalidate",
);

Keamanan

  • Jangan pernah mengekspos API key atau rahasia di kode sisi klien
  • Validasi semua input pengguna
  • Gunakan HTTPS untuk semua permintaan eksternal
  • Atur header CORS yang sesuai

Butuh Bantuan?

  • Discord: Bergabung dengan server komunitas kami
  • GitHub Issues: Buat issue untuk pertanyaan
  • Email: [email protected]

Kami sangat antusias melihat penyedia apa yang akan kamu tambahkan! 🚀

Copyright © 2026