Get the current list of files in the manifest.
Returns metadata about all files that have been added to the builder. Does not include the actual file content, only the storage paths, content types, and ciphertext lengths.
Array of file metadata objects (copies, safe to modify)
Get the manifest ID for the SHL instance used by this builder.
Useful for storing the SHL and its manifest in a database with a unique identifier.
The manifest ID is the 43-character base64url-encoded entropy segment that uniquely identifies this SHL's manifest URL. This ID is extracted from the manifest URL path and can be used as a database key or identifier.
For example, if the manifest URL is: 'https://shl.example.org/manifests/abc123def456.../manifest.json' The manifest ID would be: 'abc123def456...'
The 43-character manifest ID string
Get the SHL instance used by this builder.
Returns the immutable SHL that contains the encryption key and manifest URL for this builder's files.
The SHL instance provided in the constructor
Create a manifest builder for the given SHL.
The builder requires functions for file storage operations. These functions abstract the storage backend (S3, filesystem, database, etc.) and allow the builder to work with any storage system.
Optional
fetch?: (url: string, options?: RequestInit) => Promise<Response>Optional fetch implementation for the default loadFile.
Only used if loadFile
is not provided. Defaults to global fetch.
Function to generate URLs for stored files.
Receives a storage path from uploadFile
and returns an HTTPS URL.
Per SHL spec, URLs SHALL be short-lived and intended for single use.
Called each time a manifest is built for location-based files.
Optional
loadFile?: (path: string) => Promise<string>Optional function to load file content from storage.
Receives a storage path and returns the JWE content as a string.
If not provided, defaults to fetching via getFileURL()
with the provided fetch implementation.
Called when building manifests for embedded files.
Optional
maxParallelism?: numberOptional maximum number of concurrent file operations. Defaults to 5. Used for parallelizing file loading and URL generation in buildManifest.
Optional
removeFile?: (path: string) => Promise<void>Optional function to remove files from storage. Receives a storage path and removes the file. Required for file removal operations.
The immutable SHL instance this builder manages. Contains the encryption key and manifest URL for this SHL.
Optional
updateFile?: (Optional function to update files in storage. Receives a storage path, new content, and optional content type. Required for file update operations.
Function to upload encrypted files to storage.
Receives the JWE content as a string and optional content type.
Must return a storage path/key that can be used with getFileURL
and loadFile
.
Called once per file when added to the builder.
// With S3-like storage
const builder = new SHLManifestBuilder({
shl: myShl,
uploadFile: async (content, contentType) => {
const key = `shl-files/${crypto.randomUUID()}.jwe`;
await s3.putObject({ Key: key, Body: content, ContentType: 'application/jose' });
return key;
},
getFileURL: async (path) => {
return s3.getSignedUrl('getObject', { Key: path, Expires: 3600 });
},
loadFile: async (path) => {
const result = await s3.getObject({ Key: path });
return result.Body.toString();
},
removeFile: async (path) => {
await s3.deleteObject({ Key: path });
},
updateFile: async (path, content, contentType) => {
await s3.putObject({ Key: path, Body: content, ContentType: 'application/jose' });
},
maxParallelism: 10
});
Add a FHIR JSON resource file to the manifest.
Encrypts the FHIR resource as a JWE file and uploads it to storage. The resource is serialized as JSON and can be any valid FHIR R4 resource.
Configuration for adding the FHIR resource. The object should contain:
content
: FHIR R4 resource object to add (must have valid resourceType
field)enableCompression
: Optional. Whether to compress the file content before encryption (defaults to true)Promise resolving to object with encrypted file metadata and storage path
SHLEncryptionError When encryption fails due to invalid key, content, or crypto operations
// Add a FHIR Bundle
const result = await builder.addFHIRResource({
content: {
resourceType: 'Bundle',
type: 'collection',
entry: [
{ resource: { resourceType: 'Patient', id: '123', ... } },
// ... more resources
]
}
});
console.log('Added FHIR resource:', result.storagePath, 'Size:', result.ciphertextLength);
Add a SMART Health Card file to the manifest.
Encrypts the SMART Health Card as a JWE file and uploads it to storage.
The SHC is wrapped in a verifiableCredential
array as per SMART Health Cards specification.
Configuration for adding the health card. The object should contain:
shc
: SMART Health Card to add (JWS string or SHC object)enableCompression
: Optional. Whether to compress the file content before encryption (defaults to false, as SHCs are typically already compressed)Promise resolving to object with encrypted file metadata and storage path
SHLEncryptionError When encryption fails due to invalid key, content, or crypto operations
// Add from SHC object
const result = await builder.addHealthCard({ shc: mySHC });
console.log('Added file:', result.storagePath, 'Size:', result.ciphertextLength);
// Add from JWS string
await builder.addHealthCard({ shc: 'eyJhbGciOiJFUzI1NiIsImtpZCI6IjNLZmRnLVh3UC03Z...' });
// Add with compression (not recommended for SHCs)
await builder.addHealthCard({
shc: mySHC,
enableCompression: true
});
Build the manifest as JSON.
Generates a fresh manifest response with up-to-date file descriptors.
Files are either embedded directly in the manifest or referenced by
location URLs based on the size threshold. Location URLs are generated
fresh each time to ensure security and proper access control.
embeddedLengthMax
may vary per request.
Optional
embeddedLengthMax?: numberMaximum size in bytes for embedded files. Files with ciphertext length ≤ this value will be embedded directly in the manifest. Files larger than this will be referenced by location URLs. Defaults to 16384 (16 KiB). Typical range: 4096-32768.
Optional
list?: ListOptional FHIR List resource to include in the manifest root. Provides metadata about the collection of files.
Optional
status?: "finalized" | "can-change" | "no-longer-valid"Optional value indicating whether files may change in the future. When provided, will be included in the manifest root.
Promise resolving to SHL manifest object conforming to v1 specification (SHLManifestV1)
SHLExpiredError When the SHL has expired (exp field < current time)
SHLManifestError When a stored file cannot be loaded or content is missing
SHLNetworkError When storage network requests fail
// Use default settings
const manifest = await builder.buildManifest();
// Custom settings with can-change status and FHIR List
const manifest = await builder.buildManifest({
embeddedLengthMax: 4096,
status: "can-change",
list: {
resourceType: 'List',
status: 'current',
mode: 'working',
title: 'Patient Summary'
}
});
Find a file in the manifest by storage path.
Returns the file metadata for the specified storage path, or null if not found. Useful for checking if a file exists before attempting updates or for getting file information.
Storage path to search for
File metadata object or null if not found
Static
fromReconstruct a builder from database attributes returned by toDBAttrs method.
Creates a new SHLManifestBuilder instance from previously stored database attributes. The provided functions are used for subsequent file operations.
Database attributes from a previous toDBAttrs()
call
Optional
fetch?: (url: string, options?: RequestInit) => Promise<Response>Optional fetch implementation for default loadFile (same signature as constructor)
Function to generate file URLs (same signature as constructor)
Optional
loadFile?: (path: string) => Promise<string>Optional function to load file content (same signature as constructor)
Optional
maxParallelism?: numberOptional maximum number of concurrent file operations (same signature as constructor)
Optional
removeFile?: (path: string) => Promise<void>Optional function to remove files (same signature as constructor)
SHL payload stored separately in database
Optional
updateFile?: (Optional function to update files (same signature as constructor)
Function to upload encrypted files (same signature as constructor)
New SHLManifestBuilder
instance with restored state
// Load from database (when serving the manifest)
const savedAttrs = await database.getManifestBuilder(shlId);
const shlPayload = await database.getSHL(shlId);
// Reconstruct builder (pass the same functions passed to the constructor)
const builder = SHLManifestBuilder.fromDBAttrs({
shl: shlPayload,
attrs: savedAttrs,
uploadFile: async (content) => await storage.upload(content),
getFileURL: async (path) => await storage.getSignedURL(path),
loadFile: async (path) => await storage.download(path),
removeFile: async (path) => await storage.delete(path),
updateFile: async (path, content) => await storage.update(path, content)
});
// Builder is ready to serve the manifest
const manifest = await builder.buildManifest();
Remove a file from the manifest and storage.
Removes the file metadata from the builder's internal state and calls the
removeFile
function to delete the actual file from storage.
The file is identified by its storage path.
Storage path of the file to remove (as returned by uploadFile)
Promise that resolves when the file is removed from both manifest and storage
SHLManifestError When removeFile function is not provided or file not found
SHLNetworkError When storage removal fails
Return database attributes for DB persistence. Use the fromDBAttrs method to reconstruct the builder later.
Returns an object containing only the files metadata. This is NOT the same as an SHLManifestV1 - it's the builder's internal state that can be stored in a database and used to reconstruct the builder later. The SHL payload should be stored separately in the database.
The database attributes include:
Does NOT include:
Database attributes suitable for storage (SHLManifestBuilderDBAttrs)
// Store for persistence (when creating the SHL)
await database.storeSHL(shlId, shl.payload);
const builderAttrs = builder.toDBAttrs();
await database.storeManifestBuilder(shlId, builderAttrs);
// Later, reconstruct the builder (when serving the manifest)
const shlPayload = await database.getSHL(shlId);
const savedAttrs = await database.getManifestBuilder(shlId);
const reconstructedBuilder = SHLManifestBuilder.fromDBAttrs({
attrs: savedAttrs,
shl: shlPayload,
uploadFile: myUploadFunction,
getFileURL: myGetURLFunction
});
Update a FHIR resource file in the manifest and storage.
Replaces an existing FHIR resource file with new content. The file is identified by its storage path. The updated content is encrypted and stored using the same storage path, and the manifest metadata is updated accordingly.
Storage path of the file to update (as returned by uploadFile)
New FHIR resource content to store
Optional
enableCompression: booleanWhether to compress the file content before encryption (defaults to true)
Optional
lastUpdated: DateOptional custom timestamp for the update. If not provided, the current time will be used.
Promise that resolves when the file is updated in both manifest and storage
SHLManifestError When updateFile function is not provided, file not found, or file is not a FHIR resource
SHLNetworkError When storage update fails
SHLEncryptionError When encryption fails due to invalid key, content, or crypto operations
Update a SMART Health Card file in the manifest and storage.
Replaces an existing SMART Health Card file with new content. The file is identified by its storage path. The updated content is encrypted and stored using the same storage path, and the manifest metadata is updated accordingly.
Storage path of the file to update (as returned by uploadFile)
New SMART Health Card to store (JWS string or SHC object)
Optional
enableCompression: booleanWhether to compress the file content before encryption (defaults to false for SHCs)
Optional
lastUpdated: DateOptional custom timestamp for the update. If not provided, the current time will be used.
Promise that resolves when the file is updated in both manifest and storage
SHLManifestError When updateFile function is not provided, file not found, or file is not a SMART Health Card
SHLNetworkError When storage update fails
SHLEncryptionError When encryption fails due to invalid key, content, or crypto operations
Class that builds the manifest and files for a SMART Health Link.
This class handles file encryption, upload, and manifest building for SHL content. It encrypts files using JWE with A256GCM, manages file storage through provided upload/retrieval functions, and generates manifests with embedded or location-based file descriptors based on size thresholds.
Per the SHL specification, servers SHALL generate manifests with short-lived URLs on each request. This ensures URLs remain secure and can be rotated frequently. For this to work, the
SHLManifestBuilder
must be reconstructed on each request. Use thetoDBAttrs
to persist the builder state after the SHL is created, and thefromDBAttrs
to reconstruct the builder when handling each manifest request.The builder supports:
Example