UNPKG

@inweb/client

Version:

JavaScript REST API client for the Open Cloud Server

1,456 lines (1,427 loc) 86.2 kB
import { EventEmitter2 } from "@inweb/eventemitter2"; class Endpoint { constructor(path, httpClient, headers = {}) { this.path = path; this.httpClient = httpClient; this.headers = headers; } appendVersionParam(relativePath) { if (this._useVersion === undefined) return relativePath; const delimiter = relativePath.includes("?") ? "&" : "?"; return `${relativePath}${delimiter}version=${this._useVersion}`; } getEndpointPath(relativePath) { return this.appendVersionParam(`${this.path}${relativePath}`); } get(relativePath, signal) { return this.httpClient.get(this.getEndpointPath(relativePath), { signal: signal, headers: this.headers }); } post(relativePath, body) { return this.httpClient.post(this.getEndpointPath(relativePath), body, { headers: this.headers }); } put(relativePath, body) { return this.httpClient.put(this.getEndpointPath(relativePath), body, { headers: this.headers }); } delete(relativePath) { return this.httpClient.delete(this.getEndpointPath(relativePath), { headers: this.headers }); } useVersion(version) { this._useVersion = version; return this; } } const STATUS_CODES = { 100: "Continue", 101: "Switching Protocols", 102: "Processing", 103: "Early Hints", 200: "OK", 201: "Created", 202: "Accepted", 203: "Non-Authoritative Information", 204: "No Content", 205: "Reset Content", 206: "Partial Content", 207: "Multi-Status", 208: "Already Reported", 226: "IM Used", 300: "Multiple Choices", 301: "Moved Permanently", 302: "Found", 303: "See Other", 304: "Not Modified", 305: "Use Proxy", 307: "Temporary Redirect", 308: "Permanent Redirect", 400: "Bad Request", 401: "Unauthorized", 402: "Payment Required", 403: "Forbidden", 404: "Not Found", 405: "Method Not Allowed", 406: "Not Acceptable", 407: "Proxy Authentication Required", 408: "Request Time-out", 409: "Conflict", 410: "Gone", 411: "Length Required", 412: "Precondition Failed", 413: "Payload Too Large", 414: "URI Too Long", 415: "Unsupported Media Type", 416: "Range Not Satisfiable", 417: "Expectation Failed", 418: "I'm a teapot", 421: "Misdirected Request", 422: "Unprocessable Entity", 423: "Locked", 424: "Failed Dependency", 425: "Too Early", 426: "Upgrade Required", 428: "Precondition Required", 429: "Too Many Requests", 431: "Header Fields Too Large", 451: "Unavailable For Legal Reasons", 500: "Internal Server Error", 501: "Not Implemented", 502: "Bad Gateway", 503: "Service Unavailable", 504: "Gateway Timeout", 505: "HTTP Version Not Supported", 506: "Variant Also Negotiates", 507: "Insufficient Storage", 508: "Loop Detected", 509: "Bandwidth Limit Exceeded", 510: "Not Extended", 511: "Network Authentication Required" }; function statusText(status) { return STATUS_CODES[status] || `Error ${status}`; } function error400(text, _default = "400") { try { return JSON.parse(text).description; } catch { return _default; } } class FetchError extends Error { constructor(status, message) { super(message || statusText(status)); this.name = "FetchError"; this.status = status; this.statusText = statusText(status); } } class Model extends Endpoint { constructor(data, file) { super(`${file.path}/downloads`, file.httpClient); this._data = data; this._file = file; } get assembly() { return this._file; } get data() { return this._data; } set data(value) { this._data = value; } get database() { return this.data.database; } get default() { return this.data.default; } get file() { return this._file; } get fileId() { return this.data.fileId; } get geometry() { return this.data.geometry; } get id() { return this.data.id; } get name() { return this.data.name; } get type() { return this.file.type; } get version() { return this.data.version; } getModels() { return Promise.resolve([ this ]); } getModelTransformMatrix(handle) { return this.file.getModelTransformMatrix(handle); } setModelTransformMatrix(handle, transform) { return this.file.setModelTransformMatrix(handle, transform).then((() => this)); } getViewpoints() { return this._file.getViewpoints().then((array => array.filter((({custom_fields: custom_fields = {}}) => custom_fields.modelId === this.id || custom_fields.modelName === this.name)))); } saveViewpoint(viewpoint) { return this._file.saveViewpoint({ ...viewpoint, custom_fields: { ...viewpoint.custom_fields, modelId: this.id, modelName: this.name } }); } deleteViewpoint(guid) { return this._file.deleteViewpoint(guid); } getSnapshot(guid) { return this._file.getSnapshot(guid); } getSnapshotData(guid, bitmapGuid) { return this._file.getSnapshotData(guid, bitmapGuid); } downloadResource(dataId, onProgress, signal) { return this._file.downloadResource(dataId, onProgress, signal); } downloadResourceRange(dataId, requestId, ranges, onProgress, signal) { return this._file.downloadResourceRange(dataId, requestId, ranges, onProgress, signal); } partialDownloadResource(dataId, onProgress, signal) { console.warn("Model.partialDownloadResource() has been deprecated since 25.3 and will be removed in a future release, use Model.downloadResource() instead."); return this.downloadResource(dataId, onProgress, signal); } async downloadFileRange(requestId, records, dataId, onProgress, signal) { if (!records) return; let ranges = []; if (records.length) { ranges = records.map((record => ({ begin: Number(record.begin), end: Number(record.end), requestId: record.reqId }))); } else { for (let i = 0; i < records.size(); i++) { const record = records.get(i); ranges.push({ begin: Number(record.begin), end: Number(record.end), requestId: requestId }); record.delete(); } } await this.downloadResourceRange(dataId, requestId, ranges, onProgress, signal); } getReferences(signal) { return this._file.getReferences(signal); } } function delay(ms, signal) { return new Promise((resolve => { let timeoutId = 0; const abortHandler = () => { clearTimeout(timeoutId); resolve(true); }; timeoutId = window.setTimeout((() => { signal.removeEventListener("abort", abortHandler); resolve(false); }), ms); signal.addEventListener("abort", abortHandler, { once: true }); })); } async function waitFor(func, params = {}) { var _a, _b, _c; const timeout = params.timeout || 6e5; const interval = params.interval || 3e3; const signal = (_a = params.signal) !== null && _a !== undefined ? _a : (new AbortController).signal; const abortError = (_b = params.abortError) !== null && _b !== undefined ? _b : new DOMException("Aborted", "AbortError"); const timeoutError = (_c = params.timeoutError) !== null && _c !== undefined ? _c : new DOMException("Timeout", "TimeoutError"); const end = performance.now() + timeout; let count = timeout / interval; do { if (await func(params)) return Promise.resolve(params.result); if (await delay(interval, signal) || signal.aborted) return Promise.reject(abortError); } while (performance.now() < end && --count > 0); return Promise.reject(timeoutError); } function parseArgs(args) { if (typeof args === "string") { const firstArg = args.indexOf("--"); if (firstArg !== -1) args = args.slice(firstArg); const argArray = args.split("--").map((x => x.split("=").map((y => y.split(" "))).flat())).filter((x => x[0])).map((x => x.concat([ "" ]))); return Object.fromEntries(argArray); } return args || {}; } function userFullName(firstName, lastName = "", userName = "") { var _a; if (firstName && typeof firstName !== "string") { return userFullName((_a = firstName.firstName) !== null && _a !== undefined ? _a : firstName.name, firstName.lastName, firstName.userName); } return `${firstName !== null && firstName !== undefined ? firstName : ""} ${lastName !== null && lastName !== undefined ? lastName : ""}`.trim() || userName; } function userInitials(fullName = "") { const names = fullName.split(" ").filter((x => x)); return names.reduce(((initials, name, index) => { if (index === 0 || index === names.length - 1) initials += name.charAt(0); return initials; }), "").toUpperCase(); } class ClashTest extends Endpoint { constructor(data, path, httpClient) { super(`${path}/clashes/${data.id}`, httpClient); this.data = data; } get clearance() { return this.data.clearance; } get createdAt() { return this.data.createdAt; } get data() { return this._data; } set data(value) { this._data = value; 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); } get id() { return this.data.id; } get lastModifiedAt() { return this.data.lastModifiedAt; } get name() { return this.data.name; } set name(value) { this.data.name = value; } get owner() { return this.data.owner; } get selectionSetA() { return this.data.selectionSetA; } get selectionTypeA() { return this.data.selectionTypeA; } get selectionSetB() { return this.data.selectionSetB; } get selectionTypeB() { return this.data.selectionTypeB; } get status() { return this.data.status; } get tolerance() { return this.data.tolerance; } async checkout() { const response = await this.get(""); this.data = await response.json(); return this; } async update(data) { const response = await this.put("", data); this.data = await response.json(); return this; } delete() { return super.delete("").then((response => response.json())); } save() { return this.update(this.data); } waitForDone(params) { const checkDone = () => this.checkout().then((test => { var _a; const ready = [ "done", "failed" ].includes(test.status); const cancel = (_a = params === null || params === undefined ? undefined : params.onCheckout) === null || _a === undefined ? undefined : _a.call(params, test, ready); return cancel || ready; })); return waitFor(checkDone, params).then((() => this)); } getReport() { return this.get("/report").then((response => response.json())); } } class Assembly extends Endpoint { constructor(data, httpClient) { super(`/assemblies/${data.id}`, httpClient); this.data = data; } get activeVersion() { return this.data.activeVersion; } get associatedFiles() { return this.data.associatedFiles; } get created() { return this.data.created; } get data() { return this._data; } set data(value) { var _a; var _b; this._data = value; 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); (_a = (_b = this._data).associatedFiles) !== null && _a !== undefined ? _a : _b.associatedFiles = []; this._data.associatedFiles.forEach((file => file.link = `${this.httpClient.serverUrl}/files/${file.fileId}`)); } get files() { return this.data.files; } get geometryType() { return this.status === "done" ? "vsfx" : ""; } get id() { return this.data.id; } get name() { return this.data.name; } set name(value) { this.data.name = value; } get originalAssemblyId() { return this.data.originalAssemblyId; } get owner() { return this.data.owner; } get previewUrl() { return this.data.previewUrl || ""; } get relatedJobs() { return this.data.relatedJobs; } get status() { return this.data.status; } get type() { return "assembly"; } get version() { return this.data.version; } get versions() { return this.data.versions; } async checkout() { const response = await this.get(""); this.data = await response.json(); return this; } async update(data) { const response = await this.put("", data); this.data = await response.json(); return this; } delete() { return super.delete("").then((response => response.json())); } save() { return this.update(this.data); } setPreview(image) { console.warn("Assembly does not support preview"); return Promise.resolve(this); } deletePreview() { console.warn("Assembly does not support preview"); return Promise.resolve(this); } getModels() { return this.get("/geometry").then((response => response.json())).then((array => array.map((data => new Model(data, this))))); } getModelTransformMatrix(handle) { return this.data.transform[handle]; } setModelTransformMatrix(handle, transform) { const obj = { ...this.data.transform }; obj[handle] = transform; return this.update({ transform: obj }); } getProperties(handles) { const relativePath = handles !== undefined ? `/properties?handles=${handles}` : "/properties"; return this.get(relativePath).then((response => response.json())); } searchProperties(searchPattern) { return this.post("/properties/search", searchPattern).then((response => response.json())); } getCdaTree() { return this.get(`/properties/tree`).then((response => response.json())); } getViewpoints() { return this.get("/viewpoints").then((response => response.json())).then((viewpoints => viewpoints.result)); } saveViewpoint(viewpoint) { return this.post("/viewpoints", viewpoint).then((response => response.json())); } deleteViewpoint(guid) { return super.delete(`/viewpoints/${guid}`).then((response => response.json())); } getSnapshot(guid) { return this.get(`/viewpoints/${guid}/snapshot`).then((response => response.text())); } getSnapshotData(guid, bitmapGuid) { return this.get(`/viewpoints/${guid}/bitmaps/${bitmapGuid}`).then((response => response.text())); } downloadResource(dataId, onProgress, signal) { return this.httpClient.downloadFile(this.getEndpointPath(`/downloads/${dataId}`), onProgress, { signal: signal, headers: this.headers }).then((response => response.arrayBuffer())); } downloadResourceRange(dataId, requestId, ranges, onProgress, signal) { return this.httpClient.downloadFileRange(this.getEndpointPath(`/downloads/${dataId}?requestId=${requestId}`), requestId, ranges, onProgress, { signal: signal, headers: this.headers }).then((response => response.arrayBuffer())); } partialDownloadResource(dataId, onProgress, signal) { console.warn("Assembly.partialDownloadResource() has been deprecated since 25.3 and will be removed in a future release, use Assembly.downloadResource() instead."); return this.downloadResource(dataId, onProgress, signal); } async downloadFileRange(requestId, records, dataId, onProgress, signal) { await this.downloadResourceRange(dataId, requestId, records, onProgress, signal); } async getReferences(signal) { const files = new Endpoint("/files", this.httpClient, this.headers); const references = await Promise.all(this.associatedFiles.map((file => `/${file.fileId}/references`)).map((link => files.get(link, signal).then((response => response.json()))))).then((references => references.map((x => x.references)))).then((references => references.reduce(((x, v) => [ ...v, ...x ]), []))).then((references => [ ...new Set(references.map(JSON.stringify)) ].map((x => JSON.parse(x))))); return { id: "", references: references }; } waitForDone(params) { const checkDone = () => this.checkout().then((assembly => { var _a; const ready = [ "done", "failed" ].includes(assembly.status); const cancel = (_a = params === null || params === undefined ? undefined : params.onCheckout) === null || _a === undefined ? undefined : _a.call(params, assembly, ready); return cancel || ready; })); return waitFor(checkDone, params).then((() => this)); } getClashTests(start, limit, name, ids, sortByDesc, sortField) { const searchParams = new URLSearchParams; if (start > 0) searchParams.set("start", start.toString()); if (limit > 0) searchParams.set("limit", limit.toString()); if (name) searchParams.set("name", name); if (ids) { if (Array.isArray(ids)) ids = ids.join("|"); if (typeof ids === "string") ids = ids.trim(); if (ids) searchParams.set("id", ids); } if (sortByDesc !== undefined) searchParams.set("sortBy", sortByDesc ? "desc" : "asc"); if (sortField) searchParams.set("sortField", sortField); let queryString = searchParams.toString(); if (queryString) queryString = "?" + queryString; return this.get(`/clashes${queryString}`).then((response => response.json())).then((tests => ({ ...tests, result: tests.result.map((data => new ClashTest(data, this.path, this.httpClient))) }))); } getClashTest(testId) { return this.get(`/clashes/${testId}`).then((response => response.json())).then((data => new ClashTest(data, this.path, this.httpClient))); } createClashTest(name, selectionTypeA, selectionTypeB, selectionSetA, selectionSetB, params) { const {tolerance: tolerance, clearance: clearance, waitForDone: waitForDone} = params !== null && params !== undefined ? params : {}; if (!Array.isArray(selectionSetA)) selectionSetA = [ selectionSetA ]; if (!Array.isArray(selectionSetB)) selectionSetB = [ selectionSetB ]; return this.post("/clashes", { name: name, selectionTypeA: selectionTypeA, selectionTypeB: selectionTypeB, selectionSetA: selectionSetA, selectionSetB: selectionSetB, tolerance: tolerance, clearance: clearance }).then((response => response.json())).then((data => new ClashTest(data, this.path, this.httpClient))).then((result => waitForDone ? result.waitForDone(params) : result)); } deleteClashTest(testId) { return super.delete(`/clashes/${testId}`).then((response => response.json())); } updateVersion(files, params = { waitForDone: false }) { return Promise.reject(new Error("Assembly version support will be implemeted in a future release")); } getVersions() { return Promise.resolve(undefined); } getVersion(version) { return Promise.reject(new FetchError(404)); } deleteVersion(version) { return Promise.reject(new FetchError(404)); } setActiveVersion(version) { return this.update({ activeVersion: version }); } createSharedLink(permissions) { return Promise.reject(new Error("Assembly shared link will be implemeted in a future release")); } getSharedLink() { return Promise.resolve(undefined); } deleteSharedLink() { return Promise.reject(new FetchError(404)); } } function handleFetchError(response) { if (!response.ok) { switch (response.status) { case 400: { return response.text().then((text => { console.error(text); return Promise.reject(new FetchError(400, error400(text))); })); } case 500: { return response.text().then((text => { console.error(error400(text, text)); return Promise.reject(new FetchError(500)); })); } default: return Promise.reject(new FetchError(response.status)); } } return Promise.resolve(response); } function $fetch(url, init = { method: "GET" }) { const headers = { ...init.headers }; delete headers["Content-Type"]; Object.keys(headers).filter((x => headers[x] === undefined)).forEach((x => delete headers[x])); let body = undefined; if (init.method === "POST" || init.method === "PUT") { if (init.body instanceof FormData) { body = init.body; } else if (init.body instanceof Blob) { body = new FormData; body.append("file", init.body); } else if (init.body instanceof ArrayBuffer) { body = new FormData; body.append("file", new Blob([ init.body ])); } else if (typeof init.body === "object") { body = JSON.stringify(init.body); headers["Content-Type"] = "application/json"; } else if (typeof init.body === "string") { body = init.body; headers["Content-Type"] = "text/plain"; } } return fetch(url, { ...init, headers: headers, body: body }).then(handleFetchError); } function handleXMLHttpError(xhr) { if (xhr.status === 0) { return Promise.reject(new FetchError(0, "Network error")); } if (xhr.status < 200 || xhr.status > 299) { switch (xhr.status) { case 400: { console.error(xhr.responseText); return Promise.reject(new FetchError(400, error400(xhr.responseText))); } case 500: { console.error(error400(xhr.responseText, xhr.responseText)); return Promise.reject(new FetchError(500)); } default: { return Promise.reject(new FetchError(xhr.status)); } } } return Promise.resolve(xhr); } function $xmlhttp(url, params = { method: "GET" }) { return new Promise(((resolve, reject) => { const xhr = new XMLHttpRequest; xhr.open(params.method, url, true); for (const key in params.headers) { xhr.setRequestHeader(key, params.headers[key]); } function calcProgress(event) { return event.lengthComputable ? event.loaded / event.total : 1; } xhr.upload.onprogress = event => params.uploadProgress && params.uploadProgress(calcProgress(event)); xhr.onprogress = event => params.downloadProgress && params.downloadProgress(calcProgress(event)); xhr.onloadend = event => handleXMLHttpError(event.target).then(resolve, reject); xhr.send(params.body); })); } class HttpClient { constructor(serverUrl) { this.headers = {}; this.signInUserId = ""; this.signInUserIsAdmin = false; this.serverUrl = serverUrl; } get(relativePath, init = {}) { return $fetch(`${this.serverUrl}${relativePath}`, { ...init, method: "GET", headers: { ...this.headers, ...init.headers } }); } post(relativePath, body, init = {}) { return $fetch(`${this.serverUrl}${relativePath}`, { ...init, method: "POST", headers: { ...this.headers, ...init.headers }, body: body }); } put(relativePath, body, init = {}) { return $fetch(`${this.serverUrl}${relativePath}`, { ...init, method: "PUT", headers: { ...this.headers, ...init.headers }, body: body }); } delete(relativePath, init = {}) { return $fetch(`${this.serverUrl}${relativePath}`, { ...init, method: "DELETE", headers: { ...this.headers, ...init.headers } }); } uploadFile(relativePath, file, onProgress, init = {}) { const data = new FormData; data.append("file", file); return $xmlhttp(`${this.serverUrl}${relativePath}`, { method: "POST", headers: { ...this.headers, ...init.headers }, body: data, uploadProgress: onProgress }); } async downloadFile(relativePath, onProgress, init = {}) { const response = await this.get(relativePath, init); const contentLength = response.headers.get("Content-Length"); const total = parseInt(contentLength || "", 10) || 1; return new Response(new ReadableStream({ async start(controller) { const reader = response.body.getReader(); let loaded = 0; while (true) { const {done: done, value: value} = await reader.read(); if (done) break; controller.enqueue(value); loaded += value.length; if (onProgress) onProgress(loaded / total, value); } controller.close(); } })); } async downloadFileRange(relativePath, reserved, ranges, onProgress, init = {}) { const headers = { ...init.headers }; headers["Range"] = "bytes=" + ranges.map((x => `${x.begin}-${x.end}`)).join(","); const response = await this.get(relativePath, { ...init, headers: headers }); const contentLength = response.headers.get("content-length"); const total = parseInt(contentLength || "", 10) || 1; return new Response(new ReadableStream({ async start(controller) { const reader = response.body.getReader(); let loaded = 0; let rangedIndex = 0; let rangePos = 0; while (true) { const {done: done, value: value} = await reader.read(); if (done) break; controller.enqueue(value); loaded += value.length; let chunkLeft = value.length; let chunkPos = 0; while (chunkLeft > 0) { const range = ranges[rangedIndex]; const rangeLeft = range.end - range.begin - rangePos; if (chunkLeft < rangeLeft) { const chunk = value.subarray(chunkPos, chunkPos + chunkLeft); if (onProgress) onProgress(loaded / total, chunk, range.requestId); rangePos += chunkLeft; chunkLeft = 0; } else { const chunk = value.subarray(chunkPos, chunkPos + rangeLeft); if (onProgress) onProgress(loaded / total, chunk, range.requestId); chunkPos += rangeLeft; chunkLeft -= rangeLeft; rangedIndex++; rangePos = 0; } } } controller.close(); } })); } } class Permission extends Endpoint { constructor(data, fileId, httpClient) { super(`/files/${fileId}/permissions/${data.id}`, httpClient); this.data = data; } get actions() { return this.data.actions; } set actions(value) { this._data.actions = value; } get data() { return this._data; } set data(value) { this._data = value; } get id() { return this.data.id; } get grantedTo() { return this.data.grantedTo; } set grantedTo(value) { this.data.grantedTo = value; } get public() { return this.data.public; } set public(value) { this.data.public = value; } async checkout() { const response = await this.get(""); this.data = await response.json(); return this; } async update(data) { const response = await this.put("", data); this.data = await response.json(); return this; } delete() { return super.delete("").then((response => response.json())); } save() { return this.update(this.data); } } class Job extends Endpoint { constructor(data, httpClient) { super(`/jobs/${data.id}`, httpClient); this.data = data; } get assemblyId() { return this.data.assemblyId; } get authorId() { return this.data.authorId; } get createdAt() { return this.data.createdAt; } get data() { return this._data; } set data(value) { this._data = value; } get done() { return this.data.status === "done" || this.data.status === "failed"; } get fileId() { return this.data.fileId; } get id() { return this.data.id; } get lastUpdate() { return this.data.lastUpdate; } get outputFormat() { return this.data.outputFormat; } get parameters() { return this.data.parameters; } get status() { return this.data.status; } get statusMessage() { return this.data.statusMessage; } get startedAt() { return this.data.startedAt; } async checkout() { const response = await this.get(""); this.data = await response.json(); return this; } async update(data) { const response = await this.put("", data); this.data = await response.json(); return this; } delete() { return super.delete("").then((response => response.json())); } waitForDone(params) { const checkDone = () => this.checkout().then((job => { var _a; const ready = [ "done", "failed" ].includes(job.status); const cancel = (_a = params === null || params === undefined ? undefined : params.onCheckout) === null || _a === undefined ? undefined : _a.call(params, job, ready); return cancel || ready; })); return waitFor(checkDone, params).then((() => this)); } } class SharedLink extends Endpoint { constructor(data, httpClient) { super(`/shares/${data.token}`, httpClient); this.data = data; } get createdAt() { return this.data.createdAt; } get data() { return this._data; } set data(value) { this._data = value; } get permissions() { return this.data.permissions; } set permissions(value) { this.data.permissions = { ...this.data.permissions, ...value }; } get token() { return this.data.token; } get url() { return this.data.url; } async checkout() { const response = await this.get(""); this.data = await response.json(); return this; } async update(data) { const response = await this.put("", data); this.data = await response.json(); return this; } delete() { return super.delete("").then((response => response.json())); } save() { return this.update(this.data); } } class File extends Endpoint { constructor(data, httpClient) { super(`/files/${data.id}`, httpClient); this.data = data; } get activeVersion() { return this.data.activeVersion; } get created() { return this.data.created; } get customFields() { return this.data.customFields; } set customFields(value) { this.data.customFields = value; } get data() { return this._data; } set data(value) { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o; var _p, _q, _r, _s, _t, _u, _v, _w, _x, _y; this._data = value; this._data.previewUrl = value.preview ? `${this.httpClient.serverUrl}${this.path}/preview?updated=${value.updatedAt}` : ""; if (typeof this._data.owner === "string") this._data.owner = { userId: this._data.owner }; (_a = (_p = this._data).owner) !== null && _a !== undefined ? _a : _p.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); (_b = (_q = this._data).status) !== null && _b !== undefined ? _b : _q.status = {}; (_c = (_r = this._data.status).geometry) !== null && _c !== undefined ? _c : _r.geometry = { state: (_d = this._data.geometryStatus) !== null && _d !== undefined ? _d : "none" }; (_e = (_s = this._data.status).properties) !== null && _e !== undefined ? _e : _s.properties = { state: (_f = this._data.propertiesStatus) !== null && _f !== undefined ? _f : "none" }; (_g = (_t = this._data.status).validation) !== null && _g !== undefined ? _g : _t.validation = { state: (_h = this._data.validationStatus) !== null && _h !== undefined ? _h : "none" }; (_j = (_u = this._data).updatedBy) !== null && _j !== undefined ? _j : _u.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); (_k = (_v = this._data).versions) !== null && _k !== undefined ? _k : _v.versions = [ { ...value } ]; (_l = (_w = this._data.status).geometryGltf) !== null && _l !== undefined ? _l : _w.geometryGltf = { state: "none" }; (_m = (_x = this._data).isFileDeleted) !== null && _m !== undefined ? _m : _x.isFileDeleted = false; (_o = (_y = this._data).sharedLinkToken) !== null && _o !== undefined ? _o : _y.sharedLinkToken = null; } get exports() { return this.data.exports; } get geometryType() { if (this.status.geometryGltf.state === "done") return "gltf"; else if (this.status.geometry.state === "done") return "vsfx"; else return ""; } get id() { return this.data.id; } get isFileDeleted() { return this.data.isFileDeleted; } get name() { return this.data.name; } set name(value) { this.data.name = value; } get originalFileId() { return this.data.originalFileId; } get owner() { return this.data.owner; } get previewUrl() { return this.data.previewUrl; } get size() { return this.data.size; } get sizeTotal() { return this.data.sizeTotal; } get sharedLinkToken() { return this.data.sharedLinkToken; } get status() { return this.data.status; } get type() { return this.data.type; } get updatedAt() { return this.data.updatedAt; } get updatedBy() { return this.data.updatedBy; } get version() { return this.data.version; } get versions() { return this.data.versions; } async checkout() { const response = await this.get(""); this.data = await response.json(); return this; } async update(data) { const response = await this.put("", data); this.data = await response.json(); return this; } delete() { return super.delete("").then((response => response.json())); } save() { return this.update(this.data); } async setPreview(image) { if (!image) { await this.deletePreview(); } else { const response = await this.post("/preview", image); this.data = await response.json(); } return this; } async deletePreview() { const response = await super.delete("/preview"); this.data = await response.json(); return this; } getModels() { return this.get("/geometry").then((response => response.json())).then((array => array.map((data => new Model(data, this))))); } getModelTransformMatrix(handle) { return undefined; } setModelTransformMatrix(handle, transform) { console.warn("File does not support model transformation"); return Promise.resolve(this); } getProperties(handles) { const relativePath = handles !== undefined ? `/properties?handles=${handles}` : "/properties"; return this.get(relativePath).then((response => response.json())); } searchProperties(searchPattern) { return this.post("/properties/search", searchPattern).then((response => response.json())); } getCdaTree() { return this.get(`/properties/tree`).then((response => response.json())); } getViewpoints() { return this.get("/viewpoints").then((response => response.json())).then((viewpoints => viewpoints.result)); } saveViewpoint(viewpoint) { return this.post("/viewpoints", viewpoint).then((response => response.json())); } deleteViewpoint(guid) { return super.delete(`/viewpoints/${guid}`).then((response => response.json())); } getSnapshot(guid) { return this.get(`/viewpoints/${guid}/snapshot`).then((response => response.text())); } getSnapshotData(guid, bitmapGuid) { return this.get(`/viewpoints/${guid}/bitmaps/${bitmapGuid}`).then((response => response.text())); } download(onProgress, signal) { return this.httpClient.downloadFile(this.getEndpointPath("/downloads"), onProgress, { signal: signal, headers: this.headers }).then((response => response.arrayBuffer())); } downloadResource(dataId, onProgress, signal) { return this.httpClient.downloadFile(this.getEndpointPath(`/downloads/${dataId}`), onProgress, { signal: signal, headers: this.headers }).then((response => response.arrayBuffer())); } downloadResourceRange(dataId, requestId, ranges, onProgress, signal) { return this.httpClient.downloadFileRange(this.getEndpointPath(`/downloads/${dataId}?requestId=${requestId}`), requestId, ranges, onProgress, { signal: signal, headers: this.headers }).then((response => response.arrayBuffer())); } partialDownloadResource(dataId, onProgress, signal) { 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); } async downloadFileRange(requestId, records, dataId, onProgress, signal) { await this.downloadResourceRange(dataId, requestId, records, onProgress, signal); } getReferences(signal) { return this.get("/references", signal).then((response => response.json())); } setReferences(references) { return this.put("/references", references).then((response => response.json())); } createJob(outputFormat, parameters) { const jobs = new Endpoint("/jobs", this.httpClient, this.headers); return jobs.post(this.appendVersionParam(""), { fileId: this.id, outputFormat: outputFormat, parameters: parseArgs(parameters) }).then((response => response.json())).then((data => new Job(data, this.httpClient))); } extractGeometry(type, parameters) { return this.createJob(type === "gltf" ? "geometryGltf" : "geometry", parameters); } extractProperties(parameters) { return this.createJob("properties", parameters); } validate(parameters) { return this.createJob("validation", parameters); } waitForDone(jobs, waitAll, params) { const waitJobs = Array.isArray(jobs) ? jobs : [ jobs ]; if (waitAll === undefined) waitAll = true; const checkDone = () => this.checkout().then((file => { var _a; const readyJobs = waitJobs.filter((job => { 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 = (_a = params === null || params === undefined ? undefined : params.onCheckout) === null || _a === undefined ? undefined : _a.call(params, file, ready); return cancel || ready; })); return waitFor(checkDone, params).then((() => this)); } getPermissions() { return this.get("/permissions").then((response => response.json())).then((array => array.map((data => new Permission(data, this.id, this.httpClient))))); } getPermission(permissionId) { return this.get(`/permissions/${permissionId}`).then((response => response.json())).then((data => new Permission(data, this.id, this.httpClient))); } createPermission(actions, grantedTo, _public) { return this.post("/permissions", { actions: Array.isArray(actions) ? actions : [ actions ], grantedTo: grantedTo, public: _public }).then((response => response.json())).then((data => new Permission(data, this.id, this.httpClient))); } deletePermission(permissionId) { return super.delete(`/permissions/${permissionId}`).then((response => response.json())); } async uploadVersion(file, params = { waitForDone: false }) { const result = await this.httpClient.uploadFile(this.getEndpointPath("/versions"), file, (progress => { var _a; return (_a = params.onProgress) === null || _a === undefined ? undefined : _a.call(params, progress, file); }), { headers: this.headers }).then((xhr => 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 = []; 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; } getVersions() { 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)))); } getVersion(version) { 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)); } async deleteVersion(version) { const response = await super.delete(`/versions/${version}`); const data = await response.json(); await this.checkout(); return data; } setActiveVersion(version) { return this.update({ activeVersion: version }); } useVersion(version) { return super.useVersion(version); } async deleteSource() { const response = await super.delete("/source"); this.data = await response.json(); return this; } async createSharedLink(permissions) { const shares = new Endpoint("/shares", this.httpClient, this.headers); const response = await shares.post("", { fileId: this.id, permissions: permissions }); const data = await response.json(); await this.checkout(); return new SharedLink(data, this.httpClient); } async getSharedLink() { 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); } async deleteSharedLink() { 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; } } class Role extends Endpoint { constructor(data, projectId, httpClient) { super("", httpClient); this.projectId = projectId; this.data = data; } get description() { return this.data.description; } set description(value) { this._data.description = value; } get data() { return this._data; } set data(value) { this._data = value; this.path = `/projects/${this.projectId}/roles/${value.name}`; } get name() { return this.data.name; } set name(value) { this._data.name = value; } get permissions() { return this.data.permissions; } set permissions(value) { this.data.permissions = value || {}; } async checkout() { const response = await this.get(""); this.data = await response.json(); return this; } async update(data) { const response = await this.put("", data); this.data = await response.json(); return this; } delete() { return super.delete("").then((response => response.json())); } save() { return this.update(this.data); } } class Member extends Endpoint { constructor(data, projectId, httpClient) { super(`/projects/${projectId}/members/${data.id}`, httpClient); this.data = data; } get data() { return this._data; } set data(value) { this._data = value; this._data.user.avatarUrl = `${this.httpClient.serverUrl}/users/${this._data.user.userId}/avatar`; this._data.user.fullName = userFullName(this._data.user); this._data.user.initials = userInitials(this._data.user.fullName); } get id() { return this.data.id; } get role() { return this.data.role; } set role(value) { this.data.role = value; } get type() { return this.data.type; } get user() { return this.data.user; } async checkout() { const response = await this.get(""); this.data = await response.json(); return this; } async update(data) { const response = await this.put("", data); this.data = await response.json(); return this; } delete() { return super.delete("").then((response => response.json())); } save() { return this.update(this.data); } } class Project extends Endpoint { constructor(data, httpClient) { super(`/projects/${data.id}`, httpClient); this.data = data; } get authorization() { return this.data.authorization; } get createdAt() { return this.data.createdAt; } get customFields() { return this.data.custom