TypeScript SDK

Tipe Data & Penanganan Galat (Errors)

Tangani eksepsi SDK secara aman dengan class CloudizeroError dan manfaatkan definisi tipe TypeScript yang lengkap.

Menangani `CloudizeroError`

Seluruh kegagalan jaringan klien dan respons error API mengembalikan instance CloudizeroError beserta kode status HTTP:

examples/error-handling.ts
import { Cloudizero, CloudizeroError } from "@cloudizero/sdk";

const cz = new Cloudizero({
  apiKey: process.env.CLOUDIZERO_API_KEY!,
});

try {
  await cz.storage.upload({
    file: myFile,
    fileName: "document.pdf",
    projectId: "invalid-or-forbidden-id",
  });
} catch (error) {
  if (error instanceof CloudizeroError) {
    console.error("Cloudizero API Error:", error.message);
    console.error("HTTP Status Code:", error.status); // e.g. 403 or 401

    if (error.status === 401) {
      // Minta user input ulang atau refresh API key
    } else if (error.status === 403) {
      // Kunci tidak berwenang untuk proyek ini
    }
  } else {
    console.error("Unexpected Error:", error);
  }
}

Daftar Kode Status Umum

StatusArtiSolusi Penanganan
400 Bad RequestParameter wajib hilang atau format file tidak valid.Periksa kembali opsi fileName dan projectId.
401 UnauthorizedKunci API tidak disertakan atau token tidak valid.Buat kunci baru pada menu /api-keys.
403 ForbiddenKunci API dibatasi untuk ID proyek yang berbeda.Pastikan cakupan kunci cocok dengan proyek target.
404 Not FoundFile atau folder target tidak ditemukan.Verifikasi ID file atau ID folder tujuan.

Antarmuka TypeScript

Setiap respons dan parameter telah memiliki tipe data kuat secara langsung:

@cloudizero/sdk/types.ts
// Tipe Utama yang Diekspor dari @cloudizero/sdk

export interface CloudizeroConfig {
  apiKey: string;
  baseUrl?: string;
  cdnUrl?: string;
}

export type UploadPayload =
  | File
  | Blob
  | Uint8Array
  | ArrayBuffer
  | { [key: string]: unknown };

export interface UploadOptions {
  file: UploadPayload;
  fileName: string;
  projectId: string;
  folderId?: string | null;
  mimeType?: string;
  width?: number | null;
  height?: number | null;
  onProgress?: (progress: { loaded: number; total: number; percent: number }) => void;
  autoExtract?: boolean;
}

export interface CreatePresignedUploadOptions {
  projectId: string;
  fileName: string;
  fileSize: number;
  mimeType?: string;
  folderId?: string | null;
  cacheControl?: string;
}

export interface PresignedUploadResult {
  uploadUrl: string;
  fileId: string;
  storageKey: string;
  r2Key: string;
  finalFileName: string;
  cacheControl?: string;
  thumbnailUploadUrl?: string | null;
  thumbnailKey?: string | null;
}

export interface CompleteUploadOptions {
  fileId: string;
  projectId: string;
  fileName: string;
  fileSize: number;
  mimeType: string;
  storageKey?: string;
  r2Key?: string;
  folderId?: string | null;
  width?: number | null;
  height?: number | null;
  etag?: string | null;
  thumbnailKey?: string | null;
  autoExtract?: boolean;
}

export interface UpdateFileOptions {
  fileId: string;
  name?: string;
  folderId?: string | null;
  isTrash?: boolean;
  altText?: string | null;
  aiMetadata?: AiMetadata | null;
  file?: UploadPayload;
  mimeType?: string;
  width?: number | null;
  height?: number | null;
  onProgress?: (progress: { loaded: number; total: number; percent: number }) => void;
}

export interface ReplaceFileOptions {
  fileId: string;
  file: UploadPayload;
  fileName?: string;
  folderId?: string | null;
  mimeType?: string;
  width?: number | null;
  height?: number | null;
  onProgress?: (progress: { loaded: number; total: number; percent: number }) => void;
}

export interface UploadedFile {
  id: string;
  projectId: string;
  folderId: string | null;
  name: string;
  mimeType: string;
  size: number;
  width: number | null;
  height: number | null;
  storageKey?: string;
  r2Key: string;
  thumbnailKey?: string | null;
  thumbnailUrl?: string | null;
  processingStatus?: "ready" | "failed" | "processing" | "pending" | string | null;
  pageCount?: number | null;
  chapters?: Array<{ title: string; page: number; level?: number }> | null;
  etag: string | null;
  altText?: string | null;
  aiMetadata?: AiMetadata | null;
  isTrash?: boolean;
  createdAt: string;
  updatedAt: string;
  url?: string;
}

export interface FilePageItem {
  pageNumber: number;
  r2Key: string;
  url: string;
  width: number;
  height: number;
  size: number;
}

export interface FilePagesResult {
  fileId: string;
  fileName: string;
  mimeType: string;
  processingStatus: "ready" | "failed" | "processing" | "pending" | string;
  pageCount: number;
  thumbnailKey: string | null;
  thumbnailUrl: string | null;
  chapters: Array<{ title: string; page: number; level?: number }>;
  pages: FilePageItem[];
}

export interface ExtractPdfResult {
  success: boolean;
  message: string;
  jobId?: string;
  [key: string]: unknown;
}

export interface StorageFolder {
  id: string;
  projectId: string;
  parentId: string | null;
  name: string;
  path: string;
  createdAt: string;
  updatedAt: string;
}

export interface CreateFolderOptions {
  projectId: string;
  name: string;
  parentId?: string | null;
  path?: string;
}

export interface ListFoldersOptions {
  projectId: string;
  parentId?: string | null;
}

export interface UpdateFolderOptions {
  folderId: string;
  name?: string;
  parentId?: string | null;
}

export interface DeleteFolderResult {
  success: boolean;
  message: string;
  deletedFoldersCount: number;
  deletedFilesCount: number;
}

export interface Project {
  id: string;
  userId: string;
  workspaceId?: string | null;
  name: string;
  description?: string | null;
  sortOrder: number;
  createdAt: string;
  updatedAt: string;
  totalSize?: number;
  fileCount?: number;
}

export interface ListProjectsOptions {
  workspaceId?: string;
}

export interface CreateProjectOptions {
  name: string;
  description?: string;
  workspaceId?: string;
}

export interface UpdateProjectOptions {
  name?: string;
  description?: string;
}

export interface DeleteProjectResult {
  success: boolean;
  message: string;
}

export interface ReorderProjectsResult {
  success: boolean;
}

export interface StorageContents {
  project: { id: string; name: string };
  isRoot: boolean;
  breadcrumbs: { id: string; name: string }[];
  folders: StorageFolder[];
  files: UploadedFile[];
}

export interface AiMetadata {
  altText?: string;
  tags?: string[];
  description?: string;
  dominantColors?: string[];
  generatedAt?: string;
  locale?: string;
}

export interface DescribeImageOptions {
  locale?: "en" | "id";
  force?: boolean;
}

export interface DescribeImageResult {
  success: boolean;
  cached?: boolean;
  altText: string;
  aiMetadata: AiMetadata;
  file?: UploadedFile;
}

export interface SearchFilesOptions {
  projectId: string;
  query: string;
}

export interface SearchResultItem extends UploadedFile {
  similarityScore: number;
  matchType: "semantic" | "keyword" | "hybrid";
}

export interface SearchResults {
  results: SearchResultItem[];
  query: string;
  mode: "semantic" | "keyword" | "hybrid" | "empty";
  totalCount: number;
}

export interface ApiKeyScope {
  workspaceId?: string | null;
  projectIds?: string[] | null;
}

export interface ApiKeySummary {
  id: string;
  name: string;
  keyPrefix: string;
  workspaceId: string | null;
  workspaceName: string | null;
  workspaceSlug?: string | null;
  projectId: string | null;
  projectName: string | null;
  projects?: { id: string; name: string }[];
  lastUsedAt: string | null;
  expiresAt: string | null;
  createdAt: string;
}

export interface CreateApiKeyOptions {
  name: string;
  workspaceId?: string | null;
  projectId?: string | null;
  projectIds?: string[] | null;
  expiresInDays?: number | null;
}