API: Attachments

Functions are executed in an environment that has strict memory limits. Exceeding these memory limits can happen quickly when dealing with file data; we recommend only interacting with attachments under 20MB.

An attachment is a file that acts like a property of an object. Attachments are uploaded as temporary files and attached to objects via Actions. Once attached to an object, an attachment is persisted and can be accessed similarly to other properties.

Attachments in Functions

Attachments can be passed directly into Functions as inputs from Actions or accessed as properties on objects. You can also create attachments in Functions.

Read attachment data

To read the raw data from an attachment, use the readAsync method on the Attachment. The signature for the readAsync method is as follows:

Copied!
1 readAsync(): Promise<Blob>;

Blob is a standard JavaScript type ↗, representing a file-like object of immutable, raw data.

You will likely need to use libraries or write your own custom code for handling complex file types. For example, PDFs must be parsed with an appropriate library. Learn more about adding NPM dependencies to Functions repositories.

Often, dependencies related to parsing file data will rely on the fs module, which is not available in the Functions environment. This restriction may cause fs module errors during compilation and execution. To work around this restriction, you can introduce a dependency on an in-memory file system (memfs, for example). Then, alias the dependency under the fs name.

For example, using the NPM dependencies memfs would look as follows in your package.json:

Copied!
1 "fs": "npm:memfs@^x.x.x"

The following example demonstrates reading data from attachments:

Copied!
1 2 3 4 5 6 7 8 9 10 @OntologyEditFunction() public async updateMaintenanceLog(aircaft: Aircraft, completedMaintenanceLog: Attachment): Promise<void> { const aircraftMaintenanceLogData: Blob = await aircraft.maintenanceLog.readAsync(); const completedMaintenanceLogData: Blob = await completedMaintenanceLog.readAsync(); // Compare the current aircraft logs and completed logs and create a new maintenance log const updatedMaintenanceLogData: Blob; aircraft.maintenanceLog = await Attachments.uploadFile("maintenance-log.txt", updatedMaintenanceLogData); }

Create attachments

Functions can also be used to create attachments and attach them to objects. For attachments created in Functions to be persisted, the Function must make an Ontology edit that links the attachment to an object.

Attachments that are not attached to an object can only be viewed by the uploader and are automatically deleted after a certain period of time.

To create an attachment, use uploadFile on the Attachments interface imported from @foundry/functions-api. The signature for the uploadFile method is as follows:

Copied!
1 uploadFile(filename: string, blob: Blob): Promise<Attachment>;

The following example shows the process for uploading a file and assigning the resulting attachment to an object.

Copied!
1 2 3 4 5 6 7 8 9 10 11 import { Attachments, Attachment, OntologyEditFunction } from "@foundry/functions-api" @OntologyEditFunction() public async setMaintenanceLog(aircraft: Aircraft): Promise<void> { const data: Blob; // Logic to create a Blob and assign it to the data variable const maintenanceLog = await Attachments.uploadFile("maintenance-log.txt", data); aircraft.maintenanceLog = maintenanceLog; }

You will likely need to rely on libraries or custom code to create the Blob object, which is passed as a parameter into the uploadFile method.