UNPKG

@inweb/client

Version:

JavaScript REST API client for the Open Cloud Server

1,029 lines (943 loc) 35.9 kB
/////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2002-2025, Open Design Alliance (the "Alliance"). // All rights reserved. // // This software and its documentation and related materials are owned by // the Alliance. The software may only be incorporated into application // programs owned by members of the Alliance, subject to a signed // Membership Agreement and Supplemental Software License Agreement with the // Alliance. The structure and organization of this software are the valuable // trade secrets of the Alliance and its suppliers. The software is also // protected by copyright law and international treaty provisions. Application // programs incorporating this software must include the following statement // with their copyright notices: // // This application incorporates Open Design Alliance software pursuant to a // license agreement with Open Design Alliance. // Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance. // All rights reserved. // // By use of this software, its documentation or related materials, you // acknowledge and accept the above terms. /////////////////////////////////////////////////////////////////////////////// import { IHttpClient } from "./IHttpClient"; import { Endpoint } from "./Endpoint"; import { ICdaNode, IFileStatus, IFileReferences, IFileVersionInfo, IGrantedTo } from "./IFile"; import { IShortUserDesc } from "./IUser"; import { Model } from "./Model"; import { Permission } from "./Permission"; import { Job } from "./Job"; import { SharedLink } from "./SharedLink"; import { ISharedLinkPermissions } from "./ISharedLink"; import { waitFor, parseArgs, userFullName, userInitials } from "./Utils"; /** * Provides properties and methods for obtaining information about a file on the Open Cloud Server and * managing its data and versions. */ export class File extends Endpoint { private _data: any; /** * @param data - Raw file data received from the server. For more information, see * {@link https://cloud.opendesign.com/docs//pages/server/api.html#Files | Open Cloud Files API}. * @param httpClient - HTTP client instance used to send requests to the REST API server. */ constructor(data: any, httpClient: IHttpClient) { super(`/files/${data.id}`, httpClient); this.data = data; } /** * Active version number of the file. * * @readonly */ get activeVersion(): number { return this.data.activeVersion; } /** * File creation time (UTC) in the format specified in * {@link https://www.wikipedia.org/wiki/ISO_8601 | ISO 8601}. * * @readonly */ get created(): string { return this.data.created; } /** * File custom fields object, to store custom data. */ get customFields(): any { return this.data.customFields; } set customFields(value: any) { this.data.customFields = value; } /** * Raw file data received from the server. For more information, see * {@link https://cloud.opendesign.com/docs//pages/server/api.html#Files | Open Cloud Files API}. * * @readonly */ get data(): any { return this._data; } set data(value: any) { this._data = value; this._data.previewUrl = value.preview ? `${this.httpClient.serverUrl}${this.path}/preview?updated=${value.updatedAt}` : ""; // owner since 24.8 if (typeof this._data.owner === "string") this._data.owner = { userId: this._data.owner }; this._data.owner ??= {}; this._data.owner.avatarUrl = `${this.httpClient.serverUrl}/users/${this._data.owner.userId}/avatar`; this._data.owner.fullName = userFullName(this._data.owner); this._data.owner.initials = userInitials(this._data.owner.fullName); // status since 24.9 this._data.status ??= {}; this._data.status.geometry ??= { state: this._data.geometryStatus ?? "none" }; this._data.status.properties ??= { state: this._data.propertiesStatus ?? "none" }; this._data.status.validation ??= { state: this._data.validationStatus ?? "none" }; // updatedBy since 24.10 this._data.updatedBy ??= {}; this._data.updatedBy.avatarUrl = `${this.httpClient.serverUrl}/users/${this._data.updatedBy.userId}/avatar`; this._data.updatedBy.fullName = userFullName(this._data.updatedBy); this._data.updatedBy.initials = userInitials(this._data.updatedBy.fullName); // versions since 24.10 this._data.versions ??= [{ ...value }]; // geometryGltf status since 24.12 this._data.status.geometryGltf ??= { state: "none" }; // isFileDeleted since 25.7 this._data.isFileDeleted ??= false; // sharedLinkToken since 26.0 this._data.sharedLinkToken ??= null; } /** * Returns a list of file formats in which the active version of the file was exported. * * To export file to one of the supported formats create File Converter job using * {@link createJob | createJob()}. To download exported file use * {@link downloadResource | downloadResource()}. * * For an example of exporting files to other formats, see the {@link downloadResource} help. * * @readonly */ get exports(): string[] { return this.data.exports; } /** * Geometry data type of the active file version. Can be one of: * * - `vsfx` - `VSFX` format, file can be opened in `VisualizeJS` viewer. * - `gltf` - `glTF` format, file can be opened in `Three.js` viewer. * * Returns an empty string if geometry data has not yet been converted. A files without geometry data * can be exported to other formas, but cannot be opened in viewer. */ get geometryType(): string { if (this.status.geometryGltf.state === "done") return "gltf"; else if (this.status.geometry.state === "done") return "vsfx"; else return ""; } /** * Unique file ID. * * @readonly */ get id(): string { return this.data.id; } /** * Returns `true` if the source file of the active file version has been deleted. * * A files with deleted source file can be opened in the viewer, but cannot be exported to other * formats. * * @readonly */ get isFileDeleted(): boolean { return this.data.isFileDeleted; } /** * File name, including the extension. */ get name(): string { return this.data.name; } set name(value: string) { this.data.name = value; } /** * If the file is a version, then returns the ID of the original file. Otherwise, returns the file ID. * * @readonly */ get originalFileId(): string { return this.data.originalFileId; } /** * File owner information. * * @readonly */ get owner(): IShortUserDesc { return this.data.owner; } /** * File preview image URL or empty string if the file does not have a preview. Use * {@link setPreview | setPreview()} to change preview image. * * @readonly */ get previewUrl(): string { return this.data.previewUrl; } /** * The size of the active version of the file in bytes. * * @readonly */ get size(): number { return this.data.size; } /** * Total size of all versions of the file in bytes. * * @readonly */ get sizeTotal(): number { return this.data.sizeTotal; } /** * File shared link token or `null` if file is not shared yet. * * @readonly */ get sharedLinkToken(): string { return this.data.sharedLinkToken; } /** * Data status of the active version of the file. Contains: * * - `geometry` - status of geometry data of `vsfx` type. * - `geometryGltf` - status of geometry data of `gltf` type. * - `properties` - status of properties. * - `validation` - status of validation. * * Each status entity is a record with properties: * * - `state` - Data state. Can be `none`, `waiting`, `inprogress`, `done` or `failed`. * - `jobId` - Unique ID of the data job. * * @readonly */ get status(): IFileStatus { return this.data.status; } /** * File type, matches the file extension. * * @readonly */ get type(): string { return this.data.type; } /** * File last update time (UTC) in the format specified in * {@link https://www.wikipedia.org/wiki/ISO_8601 | ISO 8601}. * * @readonly */ get updatedAt(): string { return this.data.updatedAt; } /** * Information about the user who made the last update. * * @readonly */ get updatedBy(): IShortUserDesc { return this.data.updatedBy; } /** * Zero-based file version number for version files. The original file has version `0`. */ get version(): number { return this.data.version; } /** * List of the file versions. * * @readonly */ get versions(): IFileVersionInfo[] { return this.data.versions; } /** * Reloads file data from the server. */ async checkout(): Promise<this> { const response = await this.get(""); this.data = await response.json(); return this; } /** * Updates file data on the server. * * @param data - Raw file data. For more information, see * {@link https://cloud.opendesign.com/docs//pages/server/api.html#Files | Open Cloud Files API}. */ async update(data: any): Promise<this> { const response = await this.put("", data); this.data = await response.json(); return this; } /** * Deletes a file and all its versions from the server. * * You cannot delete a version file using `delete()`, only the original file. To delete a version file * use {@link deleteVersion | deleteVersion()}. * * @returns Returns the raw data of a deleted file. For more information, see * {@link https://cloud.opendesign.com/docs//pages/server/api.html#Files | Open Cloud Files API}. */ override delete(): Promise<any> { return super.delete("").then((response) => response.json()); } /** * Saves file properties changes to the server. Call this method to update file data on the server * after any property changes. */ save(): Promise<this> { return this.update(this.data); } /** * Sets or removes the file preview. * * @param image - Preview image. Can be a * {@link https://developer.mozilla.org/docs/Web/HTTP/Basics_of_HTTP/Data_URIs | Data URL} string, * {@link https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer | ArrayBuffer}, * {@link https://developer.mozilla.org/docs/Web/API/Blob/Blob | Blob} or * {@link https://developer.mozilla.org/docs/Web/API/File | Web API File} object. Setting the `image` * to `null` will remove the preview. */ async setPreview(image?: BodyInit | null): Promise<this> { if (!image) { await this.deletePreview(); } else { const response = await this.post("/preview", image); this.data = await response.json(); } return this; } /** * Removes the file preview. */ async deletePreview(): Promise<this> { const response = await super.delete("/preview"); this.data = await response.json(); return this; } /** * Returns a list of models of the active version of the file. */ getModels(): Promise<Model[]> { return this.get("/geometry") .then((response) => response.json()) .then((array) => array.map((data) => new Model(data, this))); } // File does not support model transformation. getModelTransformMatrix(handle: string): any { return undefined; } setModelTransformMatrix(handle: string, transform?: any): Promise<this> { console.warn("File does not support model transformation"); return Promise.resolve(this); } /** * Object properties. * * @typedef {any} Properties * @property {string} handle - Object original handle. * @property {string | any} - Object property. Can be `any` for nested properties. */ /** * Returns the properties for an objects in the active version of the file. * * @param handles - Object original handle or handles array. Specify `undefined` to get properties for * all objects in the file. */ getProperties(handles?: string | string[]): Promise<any[]> { const relativePath = handles !== undefined ? `/properties?handles=${handles}` : "/properties"; return this.get(relativePath).then((response) => response.json()); } /** * Search pattern. * * @typedef {any} SearchPattern * @property {string} key - Property name. * @property {string} value - Property value. */ /** * Query operator. Operator name can be `$and`, `$or`, `$not`, `$eq`, `$regex`. * * @typedef {any} QueryOperator * @property {string | SearchPattern[] | QueryOperator[]} * - Array of the query values or patterns for * operator. */ /** * Returns the list of original handles for an objects in the active version of the file that match the * specified patterns. Search patterns may be combined using query operators. * * @example Simple search pattern. * * ```javascript * searchPattern = { * key: "Category", * value: "OST_Stairs", * }; * ``` * * @example Search patterns combination. * * ```javascript * searchPattern = { * $or: [ * { * $and: [ * { key: "Category", value: "OST_GenericModel" }, * { key: "Level", value: "03 - Floor" }, * ], * }, * { key: "Category", value: "OST_Stairs" }, * ], * }; * ``` * * @param {SeacrhPattern | QueryOperator} searchPattern - Search pattern or combination of the * patterns, see example below. * @returns {Promise<Properties[]>} */ searchProperties(searchPattern: any): Promise<any[]> { return this.post("/properties/search", searchPattern).then((response) => response.json()); } /** * Returns the CDA tree for an active version of the file. */ getCdaTree(): Promise<ICdaNode[]> { return this.get(`/properties/tree`).then((response) => response.json()); } /** * Returns a list of file viewpoints. For more information, see * {@link https://cloud.opendesign.com/docs//pages/server/api.html#FileViewpoints | Open Cloud File Viewpoints API}. */ getViewpoints(): Promise<any[]> { return this.get("/viewpoints") .then((response) => response.json()) .then((viewpoints) => viewpoints.result); } /** * Saves a new file viewpoint to the server. To create a viewpoint use `Viewer.createViewpoint()`. * * @param viewpoint - Viewpoint object. For more information, see * {@link https://cloud.opendesign.com/docs//pages/server/api.html#FileViewpoints | Open Cloud File Viewpoints API}. */ saveViewpoint(viewpoint: any): Promise<any> { return this.post("/viewpoints", viewpoint).then((response) => response.json()); } /** * Deletes the specified file viewpoint. * * @param guid - Viewpoint GUID. * @returns Returns the raw data of a deleted viewpoint. For more information, see * {@link https://cloud.opendesign.com/docs//pages/server/api.html#FileViewpoints | Open Cloud File Viewpoints API}. */ deleteViewpoint(guid: string): Promise<any> { return super.delete(`/viewpoints/${guid}`).then((response) => response.json()); } /** * Returns viewpoint snapshot as base64-encoded * {@link https://developer.mozilla.org/docs/Web/HTTP/Basics_of_HTTP/Data_URIs | Data URL}. * * @param guid - Viewpoint GUID. */ getSnapshot(guid: string): Promise<string> { return this.get(`/viewpoints/${guid}/snapshot`).then((response) => response.text()); } /** * Returns viewpoint snapshot data. * * @param guid - Viewpoint GUID. * @param bitmapGuid - Bitmap GUID. */ getSnapshotData(guid: string, bitmapGuid: string): Promise<string> { return this.get(`/viewpoints/${guid}/bitmaps/${bitmapGuid}`).then((response) => response.text()); } /** * Downloads the source file of active version of the file from the server. * * @param onProgress - Download progress callback. * @param signal - An * {@link https://developer.mozilla.org/docs/Web/API/AbortController | AbortController} signal. Allows * to communicate with a fetch request and abort it if desired. */ download(onProgress?: (progress: number) => void, signal?: AbortSignal): Promise<ArrayBuffer> { return this.httpClient .downloadFile(this.getEndpointPath("/downloads"), onProgress, { signal, headers: this.headers }) .then((response) => response.arrayBuffer()); } /** * Downloads a resource file of the active version of the file. Resource files are files that contain * model scene descriptions, or geometry data, or exported files. * * @example Export file to DWG. * * ```javascript * const job = await file.crateJob("dwg"); * await job.waitForDone(); * const dwgFileName = file.exports.find((x) => x.endsWith(".dwg")); * const arrayBuffer = await file.downloadResource(dwgFileName); * const blob = new Blob([arrayBuffer]); * const fileName = file.name + ".dwg"; * FileSaver.saveAs(blob, fileName); * ``` * * @param dataId - Resource file name. * @param onProgress - Download progress callback. * @param signal - An * {@link https://developer.mozilla.org/docs/Web/API/AbortController | AbortController} signal. Allows * to communicate with a fetch request and abort it if desired. */ downloadResource( dataId: string, onProgress?: (progress: number, chunk: Uint8Array) => void, signal?: AbortSignal ): Promise<ArrayBuffer> { return this.httpClient .downloadFile(this.getEndpointPath(`/downloads/${dataId}`), onProgress, { signal, headers: this.headers }) .then((response) => response.arrayBuffer()); } /** * Downloads a part of resource file of the active version of the file. Resource files are files that * contain model scene descriptions, or geometry data, or exported files. * * @param dataId - Resource file name. * @param ranges - A range of resource file contents to download. * @param requestId - Request ID for download progress callback. * @param onProgress - Download progress callback. * @param signal - An * {@link https://developer.mozilla.org/docs/Web/API/AbortController | AbortController} signal. Allows * to communicate with a fetch request and abort it if desired. */ downloadResourceRange( dataId: string, requestId: number, ranges: Array<{ begin: number; end: number; requestId: number }>, onProgress?: (progress: number, chunk: Uint8Array, requestId: number) => void, signal?: AbortSignal ): Promise<ArrayBuffer> { return this.httpClient .downloadFileRange( this.getEndpointPath(`/downloads/${dataId}?requestId=${requestId}`), requestId, ranges, onProgress, { signal, headers: this.headers } ) .then((response) => response.arrayBuffer()); } /** * Deprecated since `25.3`. Use {@link downloadResource | downloadResource()} instead. * * @deprecated */ partialDownloadResource( dataId: string, onProgress?: (progress: number, downloaded: Uint8Array) => void, signal?: AbortSignal ): Promise<ArrayBuffer> { console.warn( "File.partialDownloadResource() has been deprecated since 25.3 and will be removed in a future release, use File.downloadResource() instead." ); return this.downloadResource(dataId, onProgress, signal); } /** * Deprecated since `25.3`. Use {@link downloadResourceRange | downloadResourceRange()} instead. * * @deprecated */ async downloadFileRange( requestId: number, records: any | null, dataId: string, onProgress?: (progress: number, downloaded: Uint8Array, requestId: number) => void, signal?: AbortSignal ): Promise<void> { await this.downloadResourceRange(dataId, requestId, records, onProgress, signal); } /** * Returns a list of file references. * * References are images, fonts, or any other files to correct rendering of the file. * * @param signal - An * {@link https://developer.mozilla.org/docs/Web/API/AbortController | AbortController} signal, which * can be used to abort waiting as desired. */ getReferences(signal?: AbortSignal): Promise<IFileReferences> { return this.get("/references", signal).then((response) => response.json()); } /** * Sets the file references. * * References are images, fonts, or any other files to correct rendering of the file. Reference files * must be uploaded to the server before they can be assigned to the current file. * * @param references - File references. */ setReferences(references: IFileReferences): Promise<IFileReferences> { return this.put("/references", references).then((response) => response.json()); } /** * Runs a new job on the server for the active version of the file. * * @param outputFormat - The job type. Can be one of: * * - `geometry` - Convert file geometry data to `VSFX` format suitable for `VisualizeJS` viewer. * - `geometryGltf` - Convert file geometry data to `glTF` format suitable for `Three.js` viewer. * - `properties` - Extract file properties. * - `validation` - Validate the file. Only for `IFC` files. * - `dwg`, `obj`, `gltf`, `glb`, `vsf`, `pdf`, `3dpdf` - Export file to the one of the supported format. * Use {@link exports | exports()} to get the list of completed file exports. Use * {@link downloadResource | downloadResource()} to download the exported file. * - Other custom job name. Custom job runner must be registered in the job templates before creating a * job. * * @param parameters - Parameters for the job runner. Can be given as command line arguments for the * File Converter tool in form `--arg=value`. */ createJob(outputFormat: string, parameters?: string | object): Promise<Job> { const jobs = new Endpoint("/jobs", this.httpClient, this.headers); return jobs .post(this.appendVersionParam(""), { fileId: this.id, outputFormat, parameters: parseArgs(parameters), }) .then((response) => response.json()) .then((data) => new Job(data, this.httpClient)); } /** * Runs a job to convert geometry data of active version of the file. This is alias to * {@link createJob | createJob("geometry")}. * * @param type - Geometry data type. Can be one of: * * - `vsfx` - `VSFX` format (default), for opening a file in `VisualizeJS` viewer. * - `gltf` - `glTF` format, for opening a file in `Three.js` viewer. * * @param parameters - Parameters for the job runner. Can be given as command line arguments for the * File Converter tool in form `--arg=value`. */ extractGeometry(type?: string, parameters?: string | object): Promise<Job> { return this.createJob(type === "gltf" ? "geometryGltf" : "geometry", parameters); } /** * Runs a job to extract properties of the active version of the file. This is alias to * {@link createJob | createJob("properties")}. * * @param parameters - Parameters for the job runner. Can be given as command line arguments for the * File Converter tool in form `--arg=value`. */ extractProperties(parameters?: string | object): Promise<Job> { return this.createJob("properties", parameters); } /** * Runs a job to validate the active version of the file. This is alias to * {@link createJob | createJob("validation")}. * * To get validation report use {@link downloadResource | downloadResource("validation_report.json")}. * * @param parameters - Parameters for the job runner. Can be given as command line arguments for the * File Converter tool in form `--arg=value`. */ validate(parameters?: string | object): Promise<Job> { return this.createJob("validation", parameters); } /** * Waits for jobs of the active version of the file to be done. Job is done when it changes to `none`, * `done` or `failed` status. * * @param jobs - Job or job array to wait on. Can be `geometry`, `geometryGltf`, `properties`, * `validation`, `dwg`, `obj`, `gltf`, `glb`, `vsf`, `pdf`, `3dpdf` or custom job name. * @param waitAll - If this parameter is `true`, the function returns when all the specified jobs have * done. If `false`, the function returns when any one of the jobs are done. * @param params - An object containing waiting parameters. * @param params.timeout - The time, in milliseconds that the function should wait jobs. If no one jobs * are done during this time, the `TimeoutError` exception will be thrown. * @param params.interval - The time, in milliseconds, the function should delay in between checking * jobs status. * @param params.signal - An * {@link https://developer.mozilla.org/docs/Web/API/AbortController | AbortController} signal, which * can be used to abort waiting as desired. * @param params.onCheckout - Waiting progress callback. Return `true` to cancel waiting. */ waitForDone( jobs: string | string[], waitAll?: boolean, params?: { timeout?: number; interval?: number; signal?: AbortSignal; onCheckout?: (file: File, ready: boolean) => boolean; } ): Promise<this> { const waitJobs = Array.isArray(jobs) ? jobs : [jobs]; if (waitAll === undefined) waitAll = true; const checkDone = () => this.checkout().then((file) => { const readyJobs = waitJobs.filter((job: string) => { const jobStatus = file.status[job] || {}; return ["none", "done", "failed"].includes(jobStatus.state || "none"); }); const ready = waitAll ? readyJobs.length === waitJobs.length : readyJobs.length > 0; const cancel = params?.onCheckout?.(file, ready); return cancel || ready; }); return waitFor(checkDone, params).then(() => this); } /** * Returns a list of file permissions. */ getPermissions(): Promise<Permission[]> { return this.get("/permissions") .then((response) => response.json()) .then((array) => array.map((data) => new Permission(data, this.id, this.httpClient))); } /** * Returns information about specified file permission. * * @param permissionId - Permission ID. */ getPermission(permissionId: string): Promise<Permission> { return this.get(`/permissions/${permissionId}`) .then((response) => response.json()) .then((data) => new Permission(data, this.id, this.httpClient)); } /** * Creates a new file permission for a user, project, or group. * * @example Grant the specified user permission to "update" the file. * * ```javascript * const action = "update"; * const grantedTo = [{ user: { id: myUser.id, email: myUser.email } }]; * await file.createPermission(action, grantedTo); * ``` * * @example Add a file to the specified project in "read-only" mode. * * ```javascript * const actions = ["read", "readSourceFile"]; * const grantedTo = [{ project: { id: myProject.id, name: myProject.name } }]; * await file.createPermission(actions, grantedTo); * ``` * * @param actions - Actions are allowed to be performed on a file with this permission: * * - `read` - The ability to read file description, geometry data and properties. * - `readSourceFile` - The ability to download source file. * - `write` - The ability to modify file name, description and references. * - `readViewpoint` - The ability to read file viewpoints. * - `createViewpoint` - The ability to create file viewpoints. * * @param grantedTo - A list of entities that will get access to the file. * @param _public - Specifies whether all users have access to the file or not. */ createPermission(actions: string | string[], grantedTo: IGrantedTo[], _public: boolean): Promise<Permission> { return this.post("/permissions", { actions: Array.isArray(actions) ? actions : [actions], grantedTo, public: _public, }) .then((response) => response.json()) .then((data) => new Permission(data, this.id, this.httpClient)); } /** * Removes the specified permission from the file. * * @param permissionId - Permission ID. * @returns Returns the raw data of a deleted permission. For more information, see * {@link https://cloud.opendesign.com/docs//pages/server/api.html#Permission | Open Cloud File Permissions API}. */ deletePermission(permissionId: string): Promise<any> { return super.delete(`/permissions/${permissionId}`).then((response) => response.json()); } /** * Uploads the new version of the file to the server, convert the geometry data and extract properties * as needed. * * @param file - {@link https://developer.mozilla.org/docs/Web/API/File | Web API File} object are * generally retrieved from a {@link https://developer.mozilla.org/docs/Web/API/FileList | FileList} * object returned as a result of a user selecting files using the HTML `<input>` element. * @param params - An object containing upload parameters. * @param params.geometry - Create job to convert file geometry data. The geometry data type is the * same as the original file. * @param params.properties - Create job to extract file properties. * @param params.waitForDone - Wait for geometry and properties jobs to complete. * @param params.timeout - The time, in milliseconds that the function should wait jobs. If no one jobs * are done during this time, the `TimeoutError` exception will be thrown. * @param params.interval - The time, in milliseconds, the function should delay in between checking * jobs status. * @param params.signal - An * {@link https://developer.mozilla.org/docs/Web/API/AbortController | AbortController} signal, which * can be used to abort waiting as desired. * @param params.onProgress - Upload progress callback. */ async uploadVersion( file: globalThis.File, params: { geometry?: boolean; properties?: boolean; waitForDone?: boolean; timeout?: number; interval?: number; signal?: AbortSignal; onProgress?: (progress: number, file: globalThis.File) => void; } = { waitForDone: false, } ): Promise<File> { const result = await this.httpClient .uploadFile(this.getEndpointPath("/versions"), file, (progress) => params.onProgress?.(progress, file), { headers: this.headers, }) .then((xhr: XMLHttpRequest) => JSON.parse(xhr.responseText)) .then((data) => new File(data, this.httpClient)); let geometryType = ""; if (this.versions[0].status.geometryGltf.state !== "none") geometryType = "gltf"; if (this.versions[0].status.geometry.state !== "none") geometryType = "vsfx"; params = { ...params }; if (params.geometry === undefined) params.geometry = geometryType !== ""; if (params.properties === undefined) params.properties = this.versions[0].status.properties.state !== "none"; const jobs: string[] = []; if (params.geometry) jobs.push((await result.extractGeometry(geometryType)).outputFormat); if (params.properties) jobs.push((await result.extractProperties()).outputFormat); if (jobs.length > 0) if (params.waitForDone) await result.waitForDone(jobs, true, params); else await result.checkout(); await this.checkout(); return result; } /** * Returns a list of version files. */ getVersions(): Promise<File[]> { return this.get("/versions") .then((response) => response.json()) .then((files) => files.map((data) => new File(data, this.httpClient))) .then((files) => files.map((file) => (file.id == file.originalFileId ? file.useVersion(0) : file))); } /** * Returns information about the specified version file. * * @param version - Desired version. */ getVersion(version: number): Promise<File> { return this.get(`/versions/${version}`) .then((response) => response.json()) .then((data) => new File(data, this.httpClient)) .then((file) => (file.id == file.originalFileId ? file.useVersion(0) : file)); } /** * Deletes the specified version file. * * @param version - Version to delete. * @returns Returns the raw data of a deleted version file. For more information, see * {@link https://cloud.opendesign.com/docs//pages/server/api.html#Files | Open Cloud Files API}. */ async deleteVersion(version: number): Promise<any> { const response = await super.delete(`/versions/${version}`); const data = await response.json(); await this.checkout(); return data; } /** * Replaces the active version of the file with the selected version. * * @param version - Desired active version. */ setActiveVersion(version: number): Promise<this> { return this.update({ activeVersion: version }); } /** * Makes the given version active on client side. Does not change the active file version on the * server. * * This version change will affect the result: * * - {@link getModels | getModels()} * - {@link getProperties | getProperties()} * - {@link searchProperties | searchProperties()} * - {@link getCdaTree | getCdaTree()} * - {@link download | download()} * - {@link downloadResource | downloadResource()} * - {@link createJob | createJob()} * - {@link extractGeometry | extractGeometry()} * - {@link extractProperties | extractProperties()} * - {@link validate | validate()} * - {@link waitForDone | waitForDone()} * - Viewer.open() * * Other clients will still continue to use the current active version of the file. Use `undefined` to * revert back to the active version. * * You need to reload the file data using {@link checkout | checkout()} to match the size and status * fields to the version you selected. */ override useVersion(version?: number): this { return super.useVersion(version); } /** * Deletes the source file of the active file version from the server. */ async deleteSource(): Promise<this> { const response = await super.delete("/source"); this.data = await response.json(); return this; } /** * Creates a file shared link. * * @param permissions - Share permissions. */ async createSharedLink(permissions?: ISharedLinkPermissions): Promise<SharedLink> { const shares = new Endpoint("/shares", this.httpClient, this.headers); const response = await shares.post("", { fileId: this.id, permissions }); const data = await response.json(); await this.checkout(); return new SharedLink(data, this.httpClient); } /** * Returns information about the file shared link or `undefined` if file is not shared. */ async getSharedLink(): Promise<SharedLink> { if (!this.sharedLinkToken) return Promise.resolve(undefined); const shares = new Endpoint("/shares", this.httpClient, this.headers); const response = await shares.get(`/${this.sharedLinkToken}`); const data = await response.json(); return new SharedLink(data, this.httpClient); } /** * Deletes the file shared link. * * @returns Returns the raw data of a deleted shared link. For more information, see * {@link https://cloud.opendesign.com/docs//pages/server/api.html#ShareLinks | Open Cloud SharedLinks API}. */ async deleteSharedLink(): Promise<any> { const shares = new Endpoint("/shares", this.httpClient, this.headers); const response = await shares.delete(`/${this.sharedLinkToken}`); const data = await response.json(); await this.checkout(); return data; } }