diff --git a/.changeset/batch-hidden-files.md b/.changeset/batch-hidden-files.md new file mode 100644 index 0000000..12a07f6 --- /dev/null +++ b/.changeset/batch-hidden-files.md @@ -0,0 +1,8 @@ +--- +"@thatopen/services": minor +--- + +Add `EngineServicesClient.createHiddenFilesBatch()` to upload many hidden files +in a single request, for large 3D-tile sets (point clouds / gaussian splats) +without hitting the per-file upload throttle. Exports the +`CreateHiddenItemsBatchResult` type. diff --git a/src/core/client.ts b/src/core/client.ts index 277ca12..d0a5066 100644 --- a/src/core/client.ts +++ b/src/core/client.ts @@ -18,6 +18,7 @@ import { import { CreateItemResponse, UpdateItemResponse } from '../types/response'; import { CreateHiddenItemResult, + CreateHiddenItemsBatchResult, HiddenFileEntity, Metadata, } from '../types/files'; @@ -1181,6 +1182,30 @@ export class EngineServicesClient { ); } + /** + * Creates many hidden files attached to a parent item in a single request. + * Use this instead of many `createHiddenFile` calls when uploading large sets + * (e.g. 3D Tiles); upload in chunks of up to 100 files per call. + * @param files - The files to upload. + * @param parentFileId - The parent item's unique identifier. + * @returns One result per uploaded file, in order, each with its hidden file ID. + */ + async createHiddenFilesBatch(files: (File | Blob)[], parentFileId: string) { + const formData = new FormData(); + for (const file of files) { + formData.append('files', file); + } + formData.append('parentItemId', parentFileId); + + return await this.#requestApi( + 'POST', + `${ITEM_PATH}/${HIDDEN_PATH}/batch`, + { + body: formData, + }, + ); + } + /** * Deletes a hidden file by its ID. * @param hiddenId - The hidden file's unique identifier. diff --git a/src/types/files.ts b/src/types/files.ts index c28f34f..fd3d545 100644 --- a/src/types/files.ts +++ b/src/types/files.ts @@ -13,6 +13,10 @@ export type CreateHiddenItemResult = { hiddenFileId: string; }; +export type CreateHiddenItemsBatchResult = { + results: { originalName: string; hiddenFileId: string }[]; +}; + export type MetadataValue = string | number | boolean | null; export type Metadata = Record;