UNPKG

forma-embedded-view-sdk

Version:

The Forma Embedded View SDK is a JavaScript library for creating custom extensions in Autodesk Forma (previously Spacemaker).

633 lines (632 loc) 21.2 kB
import type { Child, EmbeddedJsonRepresentation, LinkedRepresentation, Metadata, Properties, Urn } from "forma-elements"; import type { IframeMessenger } from "./iframe-messenger.js"; type PartialNullish<T> = { [P in keyof T]?: T[P] | null; }; export declare namespace CreateElementHierarchy { /** * Column-major 4x4 matrix. Translation values use metres as unit. */ type Transform = [ number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number ]; /** * Relationship to another element that will be a child of an element. */ type Child = { /** * Either an ID to another element in the request or a full URN to an external element. * * External elements must be in the integrate element system and for the same authcontext. */ id: string; /** * Transform to apply to the child element. */ transform?: Transform | undefined; /** * Unique id under parent. Used to build up paths. Prefer short values for space efficiency. * * Either all children must have keys specified or none of them. * * @min 1 * @max 40 */ key?: string | undefined; }; /** * Geometry of the element. */ namespace Geometry { /** * Geometry in binary glTF (GLB) format. * * Currently we only keep basic geometry details from the GLB, so * the stored GLB might not look exactly as the one you wrote. */ type Glb = { type: "File"; format: "glb"; /** * Reference to a file uploaded with {@link IntegrateApi.uploadFile}. */ s3Id: string; /** * ID of the node in the GLB file to use as geometry. * * This is useful if the same GLB file is used for multiple elements, * where each element should use a specific part of the GLB. */ nodeId?: string | undefined; /** * Enabling this flag makes the default rendering material double sided. * Double sided materials makes surfaces visible on from both sides * as opposed to the default behaviour of only being visible from the front. * Set this property if your geometry is a surface that should be visible from every * angle or if you have an open-ended volume. * * Note that enabling this comes at a cost to rendering performance. */ doubleSided?: boolean | undefined; }; /** * Geometry in a mesh (verts and faces) format. The unit is meter. * * The `verts` list consists of a flattened list of * x, y and z coordinates of a vertex. The `faces` list * consists of zero-indexed references to a vertex in the `verts` * list and is a flattened list of three vertices forming a triangle. * For example if there are two vertices, meaning 6 items in * the `verts` list, vertex 0 and 1 can be referenced from `faces`. * * @example Example geometry value representing a cube * ```json * { * "type": "Inline", * "format": "Mesh", * "verts": [ * // x, y, z * 0, 0, 0, // vertex 0 * 0, 1, 0, // vertex 1 * 1, 1, 0, // vertex 2 * 1, 0, 0, // vertex 3 * 0, 0, 1, // vertex 4 * 0, 1, 1, // vertex 5 * 1, 1, 1, // vertex 6 * 1, 0, 1 // vertex 7 * ], * "faces": [ * 0, 1, 3, // half bottom * 2, 1, 3, // other half bottom * 0, 3, 7, // half side 1 * 4, 3, 7, // other half side 1 * // and so on... * ] * } * ``` */ type Mesh = { type: "Inline"; format: "Mesh"; doubleSided?: boolean | undefined; /** * Verts item count must be multiple of 3. */ verts: number[]; /** * Only triangle faces supported. * Item count must be multiple of 3. */ faces: number[]; }; /** * Geometry in GeoJSON format (inline). * * Only `Polygon` and `LineString` can be specified as geometry types. */ type GeoJsonInline = { type: "Inline"; format: "GeoJSON"; geoJson: { type: "FeatureCollection"; features: unknown[]; }; nodeId?: string | undefined; }; /** * Geometry in GeoJSON format (uploaded file). * * Only `Polygon` and `LineString` can be specified as geometry types. */ type GeoJsonFile = { type: "File"; format: "GeoJSON"; /** * Reference to a file uploaded with {@link IntegrateApi.uploadFile}. * * The file must contain a valid GeoJSON FeatureCollection. */ s3Id: string; /** * ID of the GeoJSON feature the element with this geometry should use. */ nodeId: string; }; } /** * Metadata of the element to be created. */ type Metadata = { /** * Pointer to the previous version of this element. * Must be the full URN to the previous version. */ predecessor?: string | undefined; /** * Information related to the licensing governing the use and transfer of this element. */ licensing?: { /** * Whether or not data can be transferred out of Forma, for example * by downloading a data file or sending a project to Revit. */ exportable: boolean | undefined; /** * Attribution requirements that must be followed. * Empty if there are no requirements. */ attributions: { /** * We support two types of attribution actions, depending on what happens to the data: * - display: A watermark (clickable text) to be shown whenever data is displayed. * - transfer: Text to be shown to users (or put in LICENCE files or similar) whenever data is imported or exported. */ action: "display" | "transfer"; content: string; url: string; }[]; /** * Link to the original license for the data. */ licenseUrl: string; /** * Link to the providers description on how the license should be interpreted. * For auditing purposes. */ providerDescriptionUrl: string; } | undefined; }; /** * Properties of the element to be created. * * @see https://aps.autodesk.com/en/docs/forma/v1/http-specification/integrate-api/ */ type Properties = { /** * Specifies the type of element. * * @example * building * * @example * vegetation */ category?: string | undefined; /** * Value displayed to the user in the list of elements. */ name?: string | undefined; /** * Reference to the original model so if you receive this * element at a later time. You can use this reference to get information * about the model that is not stored in the element. */ internalRepresentationReference?: string | undefined; /** * The root element can be georeferenced by specifying this `geoReference` * property. * * The coordinates in the geometry will be relative to this ref point. */ geoReference?: { /** * Coordinate system identifier. * * This must be the same coordinate system as used for the * project where the element is stored. * * See {@link auto.Forma | Forma}.{@link index.EmbeddedViewSdk.project | project}. */ srid: number; /** * Reference point within the given coordinate system. */ refPoint: [number, number]; } | undefined; /** * Specify who created the element, so you can know that the * element was created by you and that it makes sense to look for * the `internalRepresentationReference` property. */ elementProvider?: string | undefined; geometry?: Geometry.Glb | Geometry.Mesh | Geometry.GeoJsonInline | Geometry.GeoJsonFile | undefined; [key: string]: unknown; }; /** * Element to create. */ type Element = { id: string; properties?: Properties | undefined; /** * Specify representations for the element. * * Representations can be given by specifying either a LinkedRepresentation, * with a blobId from the upload response of {@link IntegrateApi.uploadFile}, * or for JSON data, an EmbeddedJsonRepresentation. * * There is a limit of approximately 100 KiB of JSON data to use * EmbeddedJsonRepresentation, so if you risk exceeding this consider using * LinkedRepresentation instead by serializing the JSON to a string. * * @see https://aps.autodesk.com/en/docs/forma/v1/working-with-forma/element-system/forma-element-specification/#representations */ representations?: Record<string, LinkedRepresentation | EmbeddedJsonRepresentation> | undefined; /** * List of children elements. */ children?: Child[] | undefined; }; } /** * Hierarchy of elements to create. * * There must be at least one element that is the root element. * * The values used for IDs of elements are local to the request * to reference between elements, and can be any string. * * @see https://aps.autodesk.com/en/docs/forma/v1/http-specification/integrate-api/ */ export type CreateElementHierarchy = { /** * ID of the root element. * * @example * root */ rootElement: string; /** * Map of elements to create. * * The key must be the same value as the ID of the element. */ elements: Record<string, CreateElementHierarchy.Element>; }; export interface CreateElementV2 { /** * Desired URN (optional) for the new element. * * You can use {@link IntegrateApi.createUrn} to generate an URN. */ urn?: Urn | undefined; metadata?: Pick<Metadata, "licensing" | "predecessor"> | undefined; properties?: Properties | undefined; /** * Specify representations for the element. * * Representations can be given by specifying either a LinkedRepresentation, * with a blobId from the upload response of {@link IntegrateApi.uploadFile}, * or for JSON data, an EmbeddedJsonRepresentation. * * There is a limit of approximately 100 KiB of JSON data to use * EmbeddedJsonRepresentation, so if you risk exceeding this consider using * LinkedRepresentation instead by serializing the JSON to a string. * * @see https://aps.autodesk.com/en/docs/forma/v1/working-with-forma/element-system/forma-element-specification/#representations */ representations?: Record<string, LinkedRepresentation | EmbeddedJsonRepresentation> | undefined; children?: (Pick<Child, "urn" | "transform"> & { /** * Unique id under parent. Used to build up paths. Prefer short values for space efficiency. * * Either all children must have keys specified or none of them. * * @min 1 * @max 40 */ key?: string | undefined; })[] | undefined; } export interface UpdateElementV2 { /** * The existing element to update. */ urn: Urn; /** * Desired URN (optional) for the new element. * * You can use {@link IntegrateApi.createUrn} to generate an URN. */ nextUrn?: Urn | undefined; metadata?: PartialNullish<Pick<Metadata, "licensing" | "predecessor">> | undefined; properties?: PartialNullish<Properties> | undefined; /** * Specify representations for the element. * * Representations can be given by specifying either a LinkedRepresentation, * with a blobId from the upload response of {@link IntegrateApi.uploadFile}, * or for JSON data, an EmbeddedJsonRepresentation. * * There is a limit of approximately 100 KiB of JSON data to use * EmbeddedJsonRepresentation, so if you risk exceeding this consider using * LinkedRepresentation instead by serializing the JSON to a string. * * @see https://aps.autodesk.com/en/docs/forma/v1/working-with-forma/element-system/forma-element-specification/#representations */ representations?: Record<string, LinkedRepresentation | EmbeddedJsonRepresentation | null> | undefined; children?: (Pick<Child, "urn" | "transform"> & { /** * Unique id under parent. Used to build up paths. Prefer short values for space efficiency. * * Either all children must have keys specified or none of them. * * @min 1 * @max 40 */ key?: string | undefined; })[] | undefined; } /** * See {@link IntegrateApi.batchIngestElementsV2}. */ export declare namespace BatchIngestElementsV2 { /** * Create a new element. * * See description of {@link IntegrateApi.createElementV2} for more information. */ interface CreateElement extends CreateElementV2 { operation: "create"; } /** * Create a new element based on the existing element. * * See description of {@link IntegrateApi.updateElementV2} for more information. */ interface UpdateElement extends UpdateElementV2 { operation: "update"; } /** * Result for a successful operation. */ interface ResultOk { status: "ok"; urn: Urn; } /** * Result for a failed operation. */ interface ResultFailed { status: "failed"; error: { title: string; detail: string; errors?: { field: string | null; path: (string | number)[] | null; title: string; detail: string; }[] | undefined; }; } } /** * Create and upload elements to the integrate element system. * * @remarks * Available via {@link auto.Forma | Forma}.{@link index.EmbeddedViewSdk.integrateElements | integrateElements}. */ export declare class IntegrateApi { #private; /** @hidden */ constructor(iframeMessenger: IframeMessenger); /** * Create a hierarchy of elements in the integrate element system. * * More information about the integrate element system can be seen * at https://aps.autodesk.com/en/docs/forma/v1/http-specification/integrate-api/ * * Requires edit access. See {@link EmbeddedViewSdk.getCanEdit | getCanEdit} for more info. * * @deprecated Prefer using {@link IntegrateApi.createElementV2} or {@link IntegrateApi.batchIngestElementsV2} instead. * * @returns ID, URN, and revision of the root element created. * * @example * const upload = await Forma.integrateElements.uploadFile({ * data: "glb data here...", * }) * * const { urn } = await Forma.integrateElements.createElementHierarchy({ * data: { * rootElement: "root", * elements: { * root: { * id: "root", * properties: { * geometry: { * type: "File", * format: "glb", * s3Id: upload.fileId, * }, * }, * }, * }, * }, * }) * * console.log(`Created element: ${urn}`) */ createElementHierarchy(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; /** * Element hierarchy to add, consisting of a * root element and its children. */ data: CreateElementHierarchy; }): Promise<{ id: string; urn: string; revision: string; }>; /** * Create a new element. * * Requires edit access. See {@link EmbeddedViewSdk.getCanEdit | getCanEdit} for more info. * * @example * const upload = await Forma.integrateElements.uploadFile({ * data: "glb data here...", * }) * * const { urn } = await Forma.integrateElements.createElementV2({ * representations: { * volumeMesh: { * blobId: upload.blobId, * }, * }, * }) * * @returns URN of the created element. */ createElementV2(request: CreateElementV2): Promise<{ urn: Urn; }>; /** * Create a new element based on the existing element. The element must * belong to integrate system. * * The update will be merged onto the existing element. The merge happens * for each individual property and representation, but not deeper. * If you want to remove a field you must set it to \`null\`. * * Requires edit access. See {@link EmbeddedViewSdk.getCanEdit | getCanEdit} for more info. * * @example * const { urn } = await Forma.integrateElements.updateElementV2({ * urn: existingUrn, * properties: { * foo: "bar", * }, * }) * * @returns URN of the created element. */ updateElementV2(request: UpdateElementV2): Promise<{ urn: Urn; }>; /** * Create and/or update multiple elements in a batch. * * As part of the same batch elements can reference each other to form * a hierarchy in a single request. You need to specify the element URN * that should be used to store the new element for this. * * The response can be partial including failed items. * * Requires edit access. See {@link EmbeddedViewSdk.getCanEdit | getCanEdit} for more info. * * @example * const upload = await Forma.integrateElements.uploadFile({ * data: "glb data here...", * }) * * const { items } = await Forma.integrateElements.batchIngestElementsV2({ * items: [ * { * operation: "create", * representations: { * volumeMesh: { * blobId: upload.blobId, * }, * }, * }, * { * operation: "update", * urn: existingUrn, * properties: { * foo: "bar", * }, * }, * ], * }) * // Handle failures. */ batchIngestElementsV2(request: { /** * A list of operations to create or update elements. A maximum of 1000 items can be specified. */ items: (BatchIngestElementsV2.CreateElement | BatchIngestElementsV2.UpdateElement)[]; }): Promise<{ /** * Each item in the response corresponds to the item with the same index * in the request. */ items: (BatchIngestElementsV2.ResultOk | BatchIngestElementsV2.ResultFailed)[]; }>; /** * Upload a file to the integrate file storage. Files stored here are can only * be retrieved in relation to an element. An example of this is uploading a * geometric file - e.g. GLB or GeoJSON files. * * Requires edit access. See {@link EmbeddedViewSdk.getCanEdit | getCanEdit} for more info. * * @returns Unique identifier for the uploaded file. */ uploadFile(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; /** * File data to upload. */ data: string | ArrayBuffer; }): Promise<{ fileId: string; blobId: string; }>; /** * Create a new URN to be used for an element in Integrate API. * * @example * const urn = createUrn("pro_japoqu38nx") */ createUrn(authcontext: string): Urn; } export {};