forma-embedded-view-sdk
Version:
The Forma Embedded View SDK is a JavaScript library for creating custom extensions in Autodesk Forma (previously Spacemaker).
290 lines (289 loc) • 10.2 kB
TypeScript
import { type IframeMessenger } from "./iframe-messenger.js";
/**
* Access extension-specific services, e.g. registered endpoints and cloud storage.
*
* @remarks
* Available via {@link auto.Forma | Forma}.{@link index.EmbeddedViewSdk.extensions | extensions}.
*/
export declare class ExtensionsApi {
#private;
readonly storage: ExtensionsStorageApi;
/** @hidden */
constructor(iframeMessenger: IframeMessenger);
/**
* Invoke an extension-specific endpoint.
*
* Requires edit access. See {@link EmbeddedViewSdk.getCanEdit | getCanEdit} for more info.
*
* @typeParam T - Type of data returned by endpoint.
*
* @returns The data returned by the endpoint.
*
* @throws {@link index.RequestError | RequestError} with type set to `invoke-endpoint-unsuccessful` if
* the endpoint returns an unsuccesful status code. The data field of RequestError will be an
* object with the fields `status`, `statusText`, `contentType` and `body` (string). If you
* return JSON errors from your API you can parse the body field after checking the status
* and content type.
*/
invokeEndpoint<T>(request: {
/**
* Authcontext to use with the request.
*
* As of now, the currently open project id is both default
* and only allowed value.
*/
authcontext?: string | undefined;
/** Id of the extension to invoke the endpoint for. */
extensionId: string;
/** Id of the endpoint to invoke, as registered in the extension. */
endpointId: string;
/** Payload to send to the endpoint. */
payload: unknown;
}): Promise<T>;
}
/**
* A string of metadata that can be stored on the object
*
* Can often be useful when storing binary data or png's
* and you need to add some additional context on that particular object,
* for example parameters that was used in an analysis calculation
* that can remove unnecessary computation later
*
* NOTE: This will be returned in a specific HTTP header when fetching the object and is
* restricted to 1kb in size.
*/
export type StorageObjectMetadata = string;
export type StorageObjectAsText = {
data: string;
metadata?: StorageObjectMetadata | undefined;
};
export type StorageObject = {
data: ArrayBuffer;
metadata?: StorageObjectMetadata | undefined;
};
export type StorageListObject = {
/**
* Name of the object
*/
key: string;
/**
* Last modified date string in ISO 8601 format
*/
lastModified: string;
/**
* size of the object
*/
size: number;
/**
* Temporary presigned url to fetch the object
*/
tempGetObjectUrl: string;
/**
* Expiry time for tempGetObjectUrl as date string in ISO 8601 format
*/
tempGetObjectExpiry: string;
};
/**
* Extension storage provides a way for extension authors to save data in a given authcontext
* which the extension is installed for without needing their own storage layer.
*
* Any data can be stored and fetched directly via the SDK. Data is stored in
* AWS S3 and accessed using presigned URLs. This way we only act as a proxy for
* generating the presigned links without ever having an opinion on what data is
* actually stored.
*
* NOTE: Even though extension authors can write data on behalf of a user in a specific context, it's
* still the user who owns the data, and can they can access it without going through the extension
* itself.
*
* @see https://aws.amazon.com/s3/
*
* @remarks
* Available via {@link auto.Forma | Forma}.{@link index.EmbeddedViewSdk.extensions | extensions}.{@link extensions.ExtensionsApi.storage | storage}.
*/
export declare class ExtensionsStorageApi {
#private;
/** @hidden */
constructor(iframeMessenger: IframeMessenger);
/**
* Add or replace a storage object.
*
* Requires edit access. See {@link EmbeddedViewSdk.getCanEdit | getCanEdit} for more info.
* If you wish to store an object to the hub of the current project, the user needs
* edit access to the hub See {@link EmbeddedViewSdk.getCanEditHub | getCanEditHub}
*
* @example
* // STORE JSON
* const myObject = {
* someData: "someValue"
* }
*
* await Forma.extensions.storage.setObject({key: "some-key", data: JSON.stringify(myObject)})
*
* @example
* // STORE Float32Array
*
* function arrayToBuffer(array: Float32Array): ArrayBuffer {
* const buffer = new ArrayBuffer(array.length * Float32Array.BYTES_PER_ELEMENT);
* const arr = new Float32Array(buffer);
* arr.set(array);
* return arr;
* }
*
* const arr = new Float32Array(100).fill(Math.random())
* await Forma.extensions.storage.setObject({key: "someKey", data: arrayToBuffer(arr)})
*
*/
setObject(request: {
/** The key of the object. Max length: 200. Allowed characters: [a-zA-Z0-9!-_.*'()] */
key: string;
/** Data to be stored. */
data: ArrayBuffer | string;
/**
* The authcontext you want to read the data under.
* Only the current project or the project's hub are valid authcontext
*/
authcontext?: string;
/** Optional metadata to be stored on the object. See {@link StorageObjectMetadata} for more information. */
metadata?: StorageObjectMetadata | undefined;
}): Promise<void>;
/**
* Utility function to fetch string objects without needing to decode an array buffer.
*
* If you wish to get an object on the current project's hub, the user needs
* view access to the hub See {@link EmbeddedViewSdk.getCanViewHub | getCanViewHub}
*
* @returns The data parsed as UTF-8, including metadata if present.
*
* @example
* // READING JSON
* const res = await Forma.extensions.storage.getTextObject({
* key: "some-key",
* })
* if (!res) {
* return
* }
* const metadata = JSON.parse(data.metadata ?? "{}")
* const data = res.data
*
* @example
* function loadImageFromEncodedPng(
* url: string,
* ): Promise<HtmlImageElement> {
* return new Promise((resolve, reject) => {
* const img = new Image()
* img.onload = () => {
* resolve(img)
* }
* img.onerror = () => {
* reject(new Error("Failed to load image"))
* }
* img.src = url
* })
* }
*
* async function createCanvasFromDataUrl(
* url: string,
* ): Promise<HtmlCanvasElement | void> {
* const canvas = document.createElement("canvas")
* const ctx = canvas.getContext("2d")
* const img = await loadImage(url)
* canvas.height = img.height
* canvas.width = img.width
* ctx.drawImage(ctx, img, 0, 0)
* return canvas
* }
*
* const res = await Forma.extensions.storage.getTextObject({
* key: "some-png-key",
* })
* if (!res) {
* return
* }
* const canvas = createCanvasFromDataUrl(res.data)
*
*/
getTextObject(request: {
/** The key of the object. */
key: string;
/**
* The authcontext of the data you want to read.
* Only the current project Id or the project's hub ID are valid values.
*/
authcontext?: string;
}): Promise<StorageObjectAsText | undefined>;
/**
* Fetch the data for the specified key.
*
* Use this function when you're **not** fetching text data, such as geometry
* or analysis results.
*
* If you wish to get an object on the current project's hub, the user needs
* view access to the hub See {@link EmbeddedViewSdk.getCanViewHub | getCanViewHub}
*
* @returns The data as an ArrayBuffer, including metadata if present.
*
* @example
* const res = await Forma.extensions.storage.getBinaryObject({
* key: "my-float32-array",
* })
* if (!res) {
* return
* }
* const terrainSlope: Float32Array = new Float32Array(res.data)
* const metadata = JSON.parse(res.metadata ?? "{}")
*
*/
getBinaryObject(request: {
/** The key of the object. */
key: string;
/**
* The authcontext you want to read the data under.
* Only the current project or the project's hub are valid authcontext
*/
authcontext?: string;
}): Promise<StorageObject | undefined>;
/**
* List all storage objects for the extension in the current authcontext.
*
* @returns List of filtered objects with relevant information.
*
* @example
* const availableObjects = await Forma.extensions.storage.listObjects().results
*/
listObjects(request?: {
/** Limit the response to only objects that starts with the key. */
prefix?: string | undefined;
/**
* The authcontext you want to read the data under.
* Only the current project or the project's hub are valid authcontext
*/
authcontext?: string;
}): Promise<{
results: StorageListObject[];
}>;
/**
* Delete object corresponding to the specified key.
*
* Requires edit access. See {@link EmbeddedViewSdk.getCanEdit | getCanEdit} for more info.
* If you wish to delete an object to the hub of the current project, the user needs
* edit access to the hub See {@link EmbeddedViewSdk.getCanEditHub | getCanEditHub}
*
* @example
* // Store a JSON object and delete it afterwards
* const myObject = {
* someData: "someValue"
* }
* await Forma.extensions.storage.setObject({key: "some-key", data: JSON.stringify(myObject)})
* await Forma.extensions.storage.deleteObject({key: "some-key"}})
*/
deleteObject(request: {
/** The key of the object. */
key: string;
/**
* The authcontext you want to read the data under.
* Only the current project or the project's hub are valid authcontext
*/
authcontext?: string;
}): Promise<void>;
}