/** * Palantir Foundry Datasets API. * Datasets, branches, transactions, files, schemas, table reads. * * File upload uses binary PUT with application/octet-stream content type * (NOT FormData). Schema endpoints use /getSchema and /putSchema verbs. * * @see https://www.palantir.com/docs/foundry/api/v2/datasets-v2-resources/ */ import type { PalantirClient } from "./client.js"; import type { Dataset, CreateDatasetParams, Branch, CreateBranchParams, Transaction, CreateTransactionParams, FileMetadata, DatasetSchema, PageResponse, PageParams, } from "./types.js"; export class DatasetsNamespace { constructor(private client: PalantirClient) {} // ─── Datasets ─────────────────────────────────────────────────── /** Create a new dataset. */ async create(params: CreateDatasetParams): Promise { return this.client.post("/api/v2/datasets", params); } /** Get a dataset by RID. */ async get(datasetRid: string): Promise { return this.client.get(`/api/v2/datasets/${datasetRid}`); } // ─── Branches ─────────────────────────────────────────────────── /** Get a specific branch. */ async getBranch(datasetRid: string, branchId: string): Promise { return this.client.get(`/api/v2/datasets/${datasetRid}/branches/${branchId}`); } /** List branches for a dataset. */ async listBranches( datasetRid: string, params?: PageParams ): Promise> { return this.client.get( `/api/v2/datasets/${datasetRid}/branches`, params ); } /** Create a branch. */ async createBranch( datasetRid: string, params: CreateBranchParams ): Promise { return this.client.post( `/api/v2/datasets/${datasetRid}/branches`, params ); } /** Delete a branch. */ async deleteBranch(datasetRid: string, branchId: string): Promise { return this.client.delete( `/api/v2/datasets/${datasetRid}/branches/${branchId}` ); } // ─── Transactions ─────────────────────────────────────────────── /** Create a transaction. */ async createTransaction( datasetRid: string, params: CreateTransactionParams ): Promise { return this.client.post( `/api/v2/datasets/${datasetRid}/transactions`, params ); } /** Get a transaction. */ async getTransaction(datasetRid: string, transactionRid: string): Promise { return this.client.get( `/api/v2/datasets/${datasetRid}/transactions/${transactionRid}` ); } /** List transactions for a dataset. Requires preview=true. */ async listTransactions( datasetRid: string, params?: PageParams ): Promise> { return this.client.get( `/api/v2/datasets/${datasetRid}/transactions`, { ...params, preview: true } as Record ); } /** Commit a transaction. */ async commitTransaction( datasetRid: string, transactionRid: string ): Promise { return this.client.post( `/api/v2/datasets/${datasetRid}/transactions/${transactionRid}/commit` ); } /** Abort a transaction. */ async abortTransaction( datasetRid: string, transactionRid: string ): Promise { return this.client.post( `/api/v2/datasets/${datasetRid}/transactions/${transactionRid}/abort` ); } // ─── File Operations ──────────────────────────────────────────── // File upload uses binary PUT (application/octet-stream), NOT FormData. // @see https://www.palantir.com/docs/foundry/api/v2/datasets-v2-resources/files/upload-file /** List files in a dataset. */ async listFiles( datasetRid: string, params?: PageParams & { branch?: string; endTransactionRid?: string; pathPrefix?: string } ): Promise> { return this.client.get( `/api/v2/datasets/${datasetRid}/files`, params as Record ); } /** Get file metadata. */ async getFile( datasetRid: string, filePath: string, params?: { branch?: string; endTransactionRid?: string } ): Promise { return this.client.get( `/api/v2/datasets/${datasetRid}/files/${encodeURIComponent(filePath)}`, params as Record ); } /** * Delete a file from a dataset. * Uses query params (branchName or transactionRid), not path params. * @see https://www.palantir.com/docs/foundry/api/v2/datasets-v2-resources/files/delete-file */ async deleteFile( datasetRid: string, filePath: string, params: { branchName?: string; transactionRid?: string } ): Promise { const queryParams = new URLSearchParams(); if (params.branchName) queryParams.set("branchName", params.branchName); if (params.transactionRid) queryParams.set("transactionRid", params.transactionRid); const qs = queryParams.toString(); return this.client.delete( `/api/v2/datasets/${datasetRid}/files/${encodeURIComponent(filePath)}${qs ? `?${qs}` : ""}` ); } /** * Upload a file to a dataset transaction. * Uses binary PUT with application/octet-stream content type. * The file path is URL-encoded in the endpoint path. */ async uploadFile( datasetRid: string, transactionRid: string, filePath: string, content: string | Blob | ArrayBuffer | Uint8Array ): Promise { const token = await this.client.getAccessToken(); const encodedPath = encodeURIComponent(filePath); const url = `${this.client.stackUrl}/api/v2/datasets/${datasetRid}/transactions/${transactionRid}/files/${encodedPath}/upload`; const body = typeof content === "string" ? new TextEncoder().encode(content) : content; const response = await this.client.rawFetch(url, { method: "PUT", headers: { Authorization: `Bearer ${token ?? ""}`, "Content-Type": "application/octet-stream", } as Record, body: body as Blob | ArrayBuffer | Uint8Array, }); if (!response.ok) { throw new Error(`File upload failed: ${response.status} ${response.statusText}`); } return response.json() as Promise; } /** * Read file content from a dataset as a raw Response stream. * Returns the fetch Response so the caller can consume the body as needed. */ async readFileContent( datasetRid: string, filePath: string, params?: { branch?: string; endTransactionRid?: string } ): Promise { const token = await this.client.getAccessToken(); const queryParams = new URLSearchParams(); if (params?.branch) queryParams.set("branch", params.branch); if (params?.endTransactionRid) queryParams.set("endTransactionRid", params.endTransactionRid); const url = `${this.client.stackUrl}/api/v2/datasets/${datasetRid}/files/${encodeURIComponent(filePath)}/content?${queryParams.toString()}`; return this.client.rawFetch(url, { headers: { Authorization: `Bearer ${token ?? ""}` }, }); } // ─── Schema ───────────────────────────────────────────────────── // Schema endpoints use /getSchema (GET) and /putSchema (PUT) verbs. // @see https://www.palantir.com/docs/foundry/api/v2/datasets-v2-resources/datasets/get-schema /** Get the schema of a dataset. */ async getSchema( datasetRid: string, params?: { branchName?: string; endTransactionRid?: string; versionId?: string } ): Promise { return this.client.get( `/api/v2/datasets/${datasetRid}/getSchema`, params as Record ); } /** * Get schemas for multiple datasets in a single request. * Max batch size: 1000. */ async getSchemaBatch( items: Array<{ datasetRid: string; branchName?: string; endTransactionRid?: string; versionId?: string }> ): Promise { return this.client.post( "/api/v2/datasets/getSchemaBatch", items ); } /** Set the schema of a dataset. Supports optional query params for branch/transaction/reader. */ async putSchema( datasetRid: string, schema: DatasetSchema, params?: { branchName?: string; endTransactionRid?: string; dataframeReader?: string } ): Promise { const queryParams = new URLSearchParams(); if (params?.branchName) queryParams.set("branchName", params.branchName); if (params?.endTransactionRid) queryParams.set("endTransactionRid", params.endTransactionRid); if (params?.dataframeReader) queryParams.set("dataframeReader", params.dataframeReader); const qs = queryParams.toString(); return this.client.put( `/api/v2/datasets/${datasetRid}/putSchema${qs ? `?${qs}` : ""}`, schema ); } /** Get schedules targeting this dataset. */ async getSchedules( datasetRid: string, params?: PageParams & { branchName?: string } ): Promise { return this.client.get( `/api/v2/datasets/${datasetRid}/getSchedules`, params as Record ); } /** Get health checks configured for a dataset. */ async getHealthChecks( datasetRid: string, params?: { branchName?: string; preview?: boolean } ): Promise { return this.client.get( `/api/v2/datasets/${datasetRid}/getHealthChecks`, { ...params, preview: true } as Record ); } /** Get health check reports for a dataset. */ async getHealthCheckReports( datasetRid: string, params?: { branchName?: string; preview?: boolean } ): Promise { return this.client.get( `/api/v2/datasets/${datasetRid}/getHealthCheckReports`, { ...params, preview: true } as Record ); } /** Get job RIDs for a dataset. */ async getJobs( datasetRid: string, params?: PageParams & { branchName?: string; where?: Record; orderBy?: Record[] } ): Promise { return this.client.post( `/api/v2/datasets/${datasetRid}/jobs`, { ...params, preview: true } ); } // ─── Table ────────────────────────────────────────────────────── /** * Read dataset as a table (structured rows). * Supports ARROW and CSV formats, column selection, and transaction scoping. * @see https://www.palantir.com/docs/foundry/api/v2/datasets-v2-resources/tables/read-table */ async readTable( datasetRid: string, params?: PageParams & { branch?: string; rowLimit?: number; format?: "ARROW" | "CSV"; columns?: string[]; startTransactionRid?: string; } ): Promise { return this.client.post( `/api/v2/datasets/${datasetRid}/readTable`, params ); } }