Create Bundle artifacts to group multiple artifacts together
Create Bundle artifacts to group multiple documents, forms, and checklists into a single distributable package. Bundles support conditional includes and can reference content inline, by file path, or by registry slug.
Examples
Creating a bundle
// Object pattern
const bundle = open. bundle ({
name: 'lease-package' ,
version: '1.0.0' ,
title: 'Residential Lease Package' ,
logic: { hasPets: 'data.pets.length > 0' },
contents: [
{ type: 'registry' , key: 'lease' , slug: 'residential-lease@1.0.0' },
{ type: 'path' , key: 'addendum' , path: './pet-addendum.json' , include: 'hasPets' },
{ type: 'inline' , key: 'disclosure' , artifact: disclosureDoc }
]
})
// Builder pattern
const bundle = open. bundle ()
. name ( 'lease-package' )
. version ( '1.0.0' )
. title ( 'Residential Lease Package' )
. expr ( 'hasPets' , 'data.pets.length > 0' )
. registry ( 'lease' , 'residential-lease@1.0.0' )
. path ( 'addendum' , './pet-addendum.json' , 'hasPets' )
. inline ( 'disclosure' , disclosureDoc)
. build ()
Loading from external data
// Parse and validate unknown input (throws on error)
const bundle = open.bundle. from (jsonData)
// Safe parsing (returns result object)
const result = open.bundle. safeFrom (jsonData)
if (result.success) {
const bundle = result.data
}
Assembling a bundle
Bundles can be assembled to resolve all contents and optionally render forms:
// Basic assembly
const assembled = await bundle. assemble ({
resolver,
includeDocumentBytes: true ,
})
// Assembly with form rendering
const assembled = await bundle. assemble ({
resolver,
formData: {
lease: leaseFormData,
addendum: petAddendumData,
},
renderForm : async ( form , data , resolver ) => ({
content: await renderFormToPDF (form, data, resolver),
filename: `${ form . name }.pdf` ,
mimeType: 'application/pdf' ,
}),
})
// Access assembled items
for ( const item of assembled.items) {
if (item.kind === 'form' && item.rendered) {
// item.rendered contains the PDF bytes
// item.filename is the suggested filename
}
}
API
Object Pattern
open. bundle (input: BundleInput): BundleInstance
Parameters
name : string
Unique identifier; must follow slug constraints
version ?: string
Artifact version (semantic versioning)
title ?: string
Human-friendly name presented to end users
description ?: string
Long-form description or context
code ?: string
Internal code or reference number
releaseDate ?: string
ISO date string indicating when the artifact was released
metadata ?: Metadata
Custom metadata map (keys must be alphanumeric with hyphens)
logic ?: LogicSection
Named expressions for conditional includes
contents : BundleContentItem[]
Ordered list of bundle content items
Returns
Returns a BundleInstance with the following properties and methods:
kind : 'bundle'
Artifact discriminator
version : string | undefined
Semantic version
title : string | undefined
Human-readable title
description : string | undefined
Description text
code : string | undefined
Internal code or reference number
releaseDate : string | undefined
ISO date string
metadata : Metadata | undefined
Custom metadata map
logic : LogicSection | undefined
Named logic expressions
contents : BundleContentItem[]
Bundle content items
validate : (options?: ValidateOptions) => StandardSchemaV1.Result
Validate the bundle definition
isValid : (options?: ValidateOptions) => boolean
Check if bundle is valid
toJSON : (options?: SerializationOptions) => object
Serialize to JSON (includes $schema by default)
toYAML : (options?: SerializationOptions) => string
Serialize to YAML
clone : () => BundleInstance
Deep clone the instance
assemble : (options: BundleAssemblyOptions) => Promise<AssembledBundle>
Resolve contents and render runtime instances
prepare : (contents?: RuntimeBundleContents) => DraftBundle
Create runtime bundle in draft phase
Builder Pattern
Chain methods to build a bundle incrementally:
All methods return BundleBuilder and are chainable.
open.bundle()
name : (value: string) => BundleBuilder Set bundle name (required)
version : (value: string) => BundleBuilder Set semantic version
title : (value: string) => BundleBuilder Set human-readable title
description : (value: string) => BundleBuilder Set description
code : (value: string) => BundleBuilder Set external reference code
releaseDate : (value: string) => BundleBuilder Set release date (ISO format)
metadata : (value: Metadata) => BundleBuilder Set custom metadata
logic : (logicDef: LogicSection) => BundleBuilder Set all logic expressions
expr : (name: string, expression: string) => BundleBuilder Add a named logic expression
registry : (key: string, slug: string, include?: CondExpr) => BundleBuilder Add registry reference
path : (key: string, path: string, include?: CondExpr) => BundleBuilder Add path reference
inline : (key: string, artifact: Artifact) => BundleBuilder Add inline artifact
contents : (items: BundleContentItem[]) => BundleBuilder Set all contents at once
removeContent : (predicate: (item, index) => boolean) => BundleBuilder Remove matching content
clearContents : () => BundleBuilder Remove all contents
build : () => BundleInstance Build and validate
Static Methods
Parse bundles from unknown data sources:
from : (input: unknown) => BundleInstance
Parse unknown input (throws on error)
safeFrom : (input: unknown) => Result<BundleInstance>
Parse unknown input (returns result object)
Bundle Content Types
Bundles can contain content from three sources:
Adding content
Use builder methods to add content:
// Registry reference - published artifacts
. registry ( 'lease' , 'residential-lease@1.0.0' )
// Path reference - local files
. path ( 'addendum' , './pet-addendum.yaml' , 'hasPets' )
// Inline - embedded artifacts
. inline ( 'disclosure' , open. document ({ ... }))
Content Item Types
InlineBundleItem
Embed an artifact directly in the bundle:
type : 'inline'
Discriminator for inline bundle item
key : string
Unique key for this item within the bundle
artifact : Document | Form | Checklist | Bundle
The embedded artifact
PathBundleItem
Reference an artifact by file path:
type : 'path'
Discriminator for path-based bundle item
key : string
Unique key for this item within the bundle
path : string
File path to the artifact definition
include ?: CondExpr
Conditional expression for including this item
RegistryBundleItem
Reference a published artifact by slug:
type : 'registry'
Discriminator for registry-based bundle item
key : string
Unique key for this item within the bundle
slug : string
Registry slug identifying the artifact
include ?: CondExpr
Conditional expression for including this item
Conditional Includes
Path and registry items support conditional inclusion using logic expressions:
const bundle = open. bundle ()
. name ( 'lease-package' )
// Define logic expressions
. expr ( 'hasPets' , 'data.pets.length > 0' )
. expr ( 'hasVehicles' , 'data.vehicles.length > 0' )
// Always include
. registry ( 'lease' , 'residential-lease@1.0.0' )
// Include only if hasPets evaluates to true
. path ( 'pet-addendum' , './pet-addendum.yaml' , 'hasPets' )
// Include only if hasVehicles evaluates to true
. path ( 'parking-addendum' , './parking.yaml' , 'hasVehicles' )
. build ()
Assembly Options
The assemble() method accepts the following options:
resolver : Resolver | ArtifactResolver
Resolver for loading files and artifacts
formData ?: Record<string, Data>
Data to use when rendering forms, keyed by content key
renderForm ?: (form, data, resolver) => Promise<RenderResult>
Function to render a form with its data
includeDocumentBytes ?: boolean
Whether to include document layer bytes (default: true)
assembleNestedBundles ?: boolean
Whether to recursively assemble nested bundles (default: true)
Lifecycle Types
Bundles follow a three-phase lifecycle similar to forms (since bundles can contain forms that require signatures):
Type Phase Description DraftBundleDraft Mutable contents, configure signers SignableBundleSignable Frozen data, capture signatures ExecutedBundleExecuted Fully frozen, ready for archival
// Prepare bundle with runtime contents (DraftBundle)
const draft = bundle. prepare ({
lease: filledLeaseForm,
disclosure: preparedDocument,
checklist: filledChecklist,
})
// Prepare for signing (SignableBundle)
const signable = draft. prepareForSigning ()
// Capture signatures across forms
const signed = signable. captureSignature ( 'lease' , 'tenant' , 'tenant-0' , 'john' , 'sig-1' )
// Finalize (ExecutedBundle)
const executed = signed. finalize ()
// executed.executedAt === ISO timestamp
DraftBundle
Created by bundle.prepare(). Contains runtime instances of all artifacts.
phase : 'draft'
Phase discriminator
bundle : Bundle
The underlying bundle definition
executedAt : undefined
Execution timestamp (always undefined for draft)
getContentKeys : () => string[]
Get all content keys
getContent : (key: string) => RuntimeInstance | undefined
Get runtime instance by key
hasContent : (key: string) => boolean
Check if content exists
getAllContents : () => RuntimeBundleContents
Get all contents
setContent : (key: string, instance: RuntimeInstance) => DraftBundle
Set content instance
removeContent : (key: string) => DraftBundle
Remove content by key
updateContents : (contents: RuntimeBundleContents) => DraftBundle
Update multiple contents
prepareForSigning : () => SignableBundle
Transition to signable phase
render : (options: RuntimeBundleRenderOptions) => Promise<RuntimeBundleRendered>
Render all contents
toJSON : () => RuntimeBundleJSON
Serialize to JSON
clone : () => DraftBundle
Create exact copy
SignableBundle
Created by draft.prepareForSigning(). Contains signable instances.
phase : 'signable'
Phase discriminator
bundle : Bundle
The underlying bundle definition
executedAt : undefined
Execution timestamp (always undefined for signable)
getContentKeys : () => string[]
Get all content keys
getContent : (key: string) => RuntimeInstance | undefined
Get runtime instance by key
hasContent : (key: string) => boolean
Check if content exists
getAllContents : () => RuntimeBundleContents
Get all contents
updateContent : (key: string, instance: RuntimeInstance) => SignableBundle
Update content (for signature capture)
finalize : () => ExecutedBundle
Transition to executed phase
render : (options: RuntimeBundleRenderOptions) => Promise<RuntimeBundleRendered>
Render all contents
toJSON : () => RuntimeBundleJSON
Serialize to JSON
clone : () => SignableBundle
Create exact copy
ExecutedBundle
Created by signable.finalize(). Fully frozen.
phase : 'executed'
Phase discriminator
bundle : Bundle
The underlying bundle definition
executedAt : string
ISO timestamp of execution
getContentKeys : () => string[]
Get all content keys
getContent : (key: string) => RuntimeInstance | undefined
Get runtime instance by key
hasContent : (key: string) => boolean
Check if content exists
getAllContents : () => RuntimeBundleContents
Get all contents
render : (options: RuntimeBundleRenderOptions) => Promise<RuntimeBundleRendered>
Render all contents
toJSON : () => RuntimeBundleJSON
Serialize to JSON
clone : () => ExecutedBundle
Create exact copy
Related