Skip to main content

TypeScript API Reference

Complete API documentation for the DDEX Builder TypeScript/JavaScript bindings.

Installation

npm install ddex-builder

Imports

import { 
DdexBuilder,
StreamingDdexBuilder,
Release,
Resource,
ValidationResult,
BuilderStats,
PresetInfo,
batchBuild,
validateStructure
} from 'ddex-builder';

Classes

DdexBuilder

Main builder class for creating deterministic DDEX XML messages.

class DdexBuilder {
constructor();
addRelease(release: Release): void;
addResource(resource: Resource): void;
build(data?: any): Promise<string>;
validate(): Promise<ValidationResult>;
getStats(): BuilderStats;
reset(): void;
getAvailablePresets(): Array<string>;
getPresetInfo(presetName: string): PresetInfo;
applyPreset(presetName: string): void;
getPresetValidationRules(presetName: string): Array<ValidationRule>;
}

Constructor

const builder = new DdexBuilder();

Creates a new DDEX builder instance with default configuration.

addRelease()

addRelease(release: Release): void

Adds a release to the message being built.

Parameters:

  • release: Release - Release data structure

Example:

const builder = new DdexBuilder();

const release: Release = {
releaseId: 'REL001',
releaseType: 'Album',
title: 'My Album',
artist: 'Artist Name',
label: 'Record Label',
catalogNumber: 'CAT001',
upc: '123456789012',
releaseDate: '2024-01-15',
genre: 'Pop',
parentalWarning: false,
trackIds: ['TRK001', 'TRK002', 'TRK003'],
metadata: {
'custom_field': 'custom_value'
}
};

builder.addRelease(release);

addResource()

addResource(resource: Resource): void

Adds a resource (sound recording, video, etc.) to the message.

Parameters:

  • resource: Resource - Resource data structure

Example:

const resource: Resource = {
resourceId: 'TRK001',
resourceType: 'SoundRecording',
title: 'Track Title',
artist: 'Artist Name',
isrc: 'USRC17607839',
duration: 'PT3M45S',
trackNumber: 1,
volumeNumber: 1,
metadata: {
'composer': 'Composer Name',
'producer': 'Producer Name'
}
};

builder.addResource(resource);

build()

build(data?: any): Promise<string>

Builds the DDEX XML message from added releases and resources.

Parameters:

  • data?: any - Optional additional message data or BuildRequest object

Returns: Promise<string> - Generated DDEX XML

Example:

const builder = new DdexBuilder();
builder.applyPreset('youtube_album');

// Add releases and resources...
builder.addRelease(release);
builder.addResource(resource);

// Build the XML
const xml = await builder.build({
messageId: 'MSG_2024_001',
sender: 'MyLabel',
recipient: 'Spotify',
version: '4.3'
});

console.log('Generated XML:', xml);

validate()

validate(): Promise<ValidationResult>

Validates the current state of the builder without generating XML.

Returns: Promise<ValidationResult> - Validation results

Example:

const builder = new DdexBuilder();
builder.addRelease(release);

const validation = await builder.validate();

if (validation.isValid) {
console.log('✓ Validation passed');
} else {
console.log('✗ Validation failed:');
validation.errors.forEach(error => {
console.log(` - ${error}`);
});
}

if (validation.warnings.length > 0) {
console.log('Warnings:');
validation.warnings.forEach(warning => {
console.log(` ! ${warning}`);
});
}

getStats()

getStats(): BuilderStats

Returns statistics about the builder's current state and performance.

Returns: BuilderStats - Builder statistics

Example:

const builder = new DdexBuilder();
// Add data and build...

const stats = builder.getStats();
console.log(`Releases: ${stats.releasesCount}`);
console.log(`Resources: ${stats.resourcesCount}`);
console.log(`Build time: ${stats.totalBuildTimeMs}ms`);
console.log(`Output size: ${stats.lastBuildSizeBytes} bytes`);
console.log(`Validation errors: ${stats.validationErrors}`);

reset()

reset(): void

Clears all added releases, resources, and statistics.

Example:

const builder = new DdexBuilder();
// Add data...
builder.addRelease(release);

// Clear everything
builder.reset();

// Builder is now empty and ready for new data

getAvailablePresets()

getAvailablePresets(): Array<string>

Returns list of available platform presets.

Returns: Array<string> - Array of preset names

Example:

const builder = new DdexBuilder();
const presets = builder.getAvailablePresets();
console.log('Available presets:', presets);
// Output: ['youtube_album', 'generic_audio_album', 'youtube_music', 'generic_audio_single', 'generic_audio_album']

getPresetInfo()

getPresetInfo(presetName: string): PresetInfo

Gets detailed information about a specific preset.

Parameters:

  • presetName: string - Name of the preset

Returns: PresetInfo - Preset information

Example:

const builder = new DdexBuilder();
const presetInfo = builder.getPresetInfo('youtube_album');

console.log(`Name: ${presetInfo.name}`);
console.log(`Description: ${presetInfo.description}`);
console.log(`Version: ${presetInfo.version}`);
console.log(`Profile: ${presetInfo.profile}`);
console.log(`Required fields: ${presetInfo.requiredFields.join(', ')}`);
console.log(`Disclaimer: ${presetInfo.disclaimer}`);

applyPreset()

applyPreset(presetName: string): void

Applies a platform-specific preset configuration.

Parameters:

  • presetName: string - Name of the preset to apply

Example:

const builder = new DdexBuilder();

// Apply Spotify preset
builder.applyPreset('youtube_album');

// The builder is now configured for Spotify requirements
// - Specific validation rules
// - Required fields
// - Format preferences

getPresetValidationRules()

getPresetValidationRules(presetName: string): Array<ValidationRule>

Gets the validation rules for a specific preset.

Parameters:

  • presetName: string - Name of the preset

Returns: Array<ValidationRule> - Array of validation rules

Example:

const builder = new DdexBuilder();
const rules = builder.getPresetValidationRules('youtube_album');

rules.forEach(rule => {
console.log(`Field: ${rule.fieldName}`);
console.log(`Rule: ${rule.ruleType}`);
console.log(`Message: ${rule.message}`);
if (rule.parameters) {
console.log(`Parameters:`, rule.parameters);
}
});

StreamingDdexBuilder

Streaming builder for memory-efficient generation of large DDEX catalogs.

class StreamingDdexBuilder {
constructor(config?: StreamingConfig);
setProgressCallback(callback: (...args: any[]) => any): void;
setEstimatedTotal(total: number): void;
startMessage(header: MessageHeader, version: string): void;
writeResource(resourceId: string, title: string, artist: string, isrc?: string, duration?: string, filePath?: string): string;
finishResourcesStartReleases(): void;
writeRelease(releaseId: string, title: string, artist: string, label: string, upc: string, releaseDate: string, genre: string, resourceReferences: Array<string>): string;
finishMessage(): StreamingStats;
getXml(): string;
reset(): void;
}

Constructor

const streamBuilder = new StreamingDdexBuilder(config?: StreamingConfig);

Creates a new streaming builder with optional configuration.

Parameters:

  • config?: StreamingConfig - Optional streaming configuration

Example:

const streamBuilder = new StreamingDdexBuilder({
maxBufferSize: 10 * 1024 * 1024, // 10MB buffer
deterministic: true,
validateDuringStream: true,
progressCallbackFrequency: 100 // Callback every 100 items
});

setProgressCallback()

setProgressCallback(callback: (...args: any[]) => any): void

Sets a callback function to receive progress updates during streaming.

Parameters:

  • callback: Function - Progress callback function

Example:

const streamBuilder = new StreamingDdexBuilder();

streamBuilder.setProgressCallback((progress: StreamingProgress) => {
const percent = progress.estimatedCompletionPercent || 0;
console.log(`Progress: ${percent.toFixed(1)}%`);
console.log(`Releases: ${progress.releasesWritten}`);
console.log(`Memory: ${(progress.currentMemoryUsage / 1024 / 1024).toFixed(1)}MB`);
});

setEstimatedTotal()

setEstimatedTotal(total: number): void

Sets the estimated total number of items for accurate progress reporting.

Parameters:

  • total: number - Estimated total number of releases

Example:

const streamBuilder = new StreamingDdexBuilder();
streamBuilder.setEstimatedTotal(10000); // Expecting 10,000 releases

startMessage()

startMessage(header: MessageHeader, version: string): void

Starts a new DDEX message with the specified header and version.

Parameters:

  • header: MessageHeader - Message header information
  • version: string - DDEX version ('3.8.2', '4.2', or '4.3')

Example:

const streamBuilder = new StreamingDdexBuilder();

const header: MessageHeader = {
messageId: 'MSG_CATALOG_2024_001',
messageSenderName: 'MyRecordLabel',
messageRecipientName: 'Spotify',
messageCreatedDateTime: new Date().toISOString()
};

streamBuilder.startMessage(header, '4.3');

writeResource()

writeResource(resourceId: string, title: string, artist: string, isrc?: string, duration?: string, filePath?: string): string

Writes a resource (sound recording) to the streaming output.

Parameters:

  • resourceId: string - Unique resource identifier
  • title: string - Resource title
  • artist: string - Artist name
  • isrc?: string - Optional ISRC code
  • duration?: string - Optional duration (ISO 8601 format)
  • filePath?: string - Optional file path reference

Returns: string - Generated resource reference ID

Example:

const streamBuilder = new StreamingDdexBuilder();
streamBuilder.startMessage(header, '4.3');

const resourceRef = streamBuilder.writeResource(
'RES_001',
'Track Title',
'Artist Name',
'USRC17607839',
'PT3M45S',
'/audio/track001.wav'
);

console.log(`Resource reference: ${resourceRef}`);

finishResourcesStartReleases()

finishResourcesStartReleases(): void

Finishes the resources section and starts the releases section.

Example:

const streamBuilder = new StreamingDdexBuilder();
streamBuilder.startMessage(header, '4.3');

// Write all resources...
streamBuilder.writeResource(...);
streamBuilder.writeResource(...);

// Transition to releases
streamBuilder.finishResourcesStartReleases();

// Now write releases...

writeRelease()

writeRelease(releaseId: string, title: string, artist: string, label: string, upc: string, releaseDate: string, genre: string, resourceReferences: Array<string>): string

Writes a release to the streaming output.

Parameters:

  • releaseId: string - Unique release identifier
  • title: string - Release title
  • artist: string - Primary artist
  • label: string - Record label name
  • upc: string - Universal Product Code
  • releaseDate: string - Release date (ISO 8601)
  • genre: string - Musical genre
  • resourceReferences: Array<string> - Array of resource reference IDs

Returns: string - Generated release reference ID

Example:

const releaseRef = streamBuilder.writeRelease(
'REL_001',
'Album Title',
'Artist Name',
'Record Label',
'123456789012',
'2024-01-15',
'Pop',
[resourceRef1, resourceRef2, resourceRef3]
);

console.log(`Release reference: ${releaseRef}`);

finishMessage()

finishMessage(): StreamingStats

Finishes the message and returns statistics.

Returns: StreamingStats - Final streaming statistics

Example:

const streamBuilder = new StreamingDdexBuilder();
// Build the message...

const stats = streamBuilder.finishMessage();
console.log(`Final stats:`);
console.log(` Releases written: ${stats.releasesWritten}`);
console.log(` Resources written: ${stats.resourcesWritten}`);
console.log(` Deals written: ${stats.dealsWritten}`);
console.log(` Total bytes: ${stats.bytesWritten}`);
console.log(` Peak memory: ${stats.peakMemoryUsage} bytes`);

if (stats.warnings.length > 0) {
console.log(`Warnings:`);
stats.warnings.forEach(warning => console.log(` - ${warning}`));
}

getXml()

getXml(): string

Returns the generated XML content.

Returns: string - Complete DDEX XML

Example:

const streamBuilder = new StreamingDdexBuilder();
// Build the message...
streamBuilder.finishMessage();

const xml = streamBuilder.getXml();
console.log(`Generated ${xml.length} characters of XML`);

// Save to file
import { writeFileSync } from 'fs';
writeFileSync('catalog.xml', xml, 'utf-8');

reset()

reset(): void

Resets the streaming builder for a new message.

Example:

const streamBuilder = new StreamingDdexBuilder();
// Build first message...
streamBuilder.finishMessage();

// Reset for next message
streamBuilder.reset();
streamBuilder.startMessage(newHeader, '4.3');

Global Functions

batchBuild()

function batchBuild(requests: Array<string>): Promise<Array<string>>

Builds multiple DDEX messages in a single operation for improved performance.

Parameters:

  • requests: Array<string> - Array of JSON-serialized build requests

Returns: Promise<Array<string>> - Array of generated XML strings

Example:

import { batchBuild } from 'ddex-builder';

const requests = [
JSON.stringify({ releases: [release1], version: '4.3' }),
JSON.stringify({ releases: [release2], version: '4.3' }),
JSON.stringify({ releases: [release3], version: '4.3' })
];

const xmlResults = await batchBuild(requests);
xmlResults.forEach((xml, index) => {
console.log(`Request ${index + 1}: ${xml.length} characters`);
});

validateStructure()

function validateStructure(xml: string): Promise<ValidationResult>

Validates the structure of existing DDEX XML without building.

Parameters:

  • xml: string - DDEX XML content to validate

Returns: Promise<ValidationResult> - Validation results

Example:

import { validateStructure } from 'ddex-builder';
import { readFileSync } from 'fs';

const xml = readFileSync('existing_ddex.xml', 'utf-8');
const validation = await validateStructure(xml);

if (validation.isValid) {
console.log('✓ XML structure is valid');
} else {
console.log('✗ XML structure has errors:');
validation.errors.forEach(error => console.log(` - ${error}`));
}

Error Handling

The builder throws specific errors for different failure conditions:

import { DdexBuilder } from 'ddex-builder';

const builder = new DdexBuilder();

try {
builder.addRelease(invalidRelease);
const xml = await builder.build();
} catch (error) {
if (error.message.includes('Validation failed')) {
console.error('Validation error:', error.message);
// Check validation results
const validation = await builder.validate();
validation.errors.forEach(err => console.error(` - ${err}`));
} else if (error.message.includes('Missing required field')) {
console.error('Required field missing:', error.message);
} else if (error.message.includes('Invalid preset')) {
console.error('Preset error:', error.message);
} else {
console.error('Unexpected error:', error.message);
}
}

Common Error Types

  • Validation Errors: Data doesn't meet DDEX requirements
  • Preset Errors: Invalid or unknown preset names
  • Reference Errors: Invalid resource references in releases
  • Format Errors: Invalid date formats, durations, or identifiers
  • Memory Errors: Insufficient memory for large catalogs
  • Configuration Errors: Invalid streaming configuration

Performance Tips

Memory Management

// Use streaming for large catalogs
const streamBuilder = new StreamingDdexBuilder({
maxBufferSize: 50 * 1024 * 1024, // 50MB
validateDuringStream: false // Validate at end for speed
});

// Process in chunks
for (const chunk of releaseChunks) {
chunk.forEach(release => {
streamBuilder.writeRelease(...);
});

// Optional: Force garbage collection
if (global.gc) global.gc();
}

Batch Processing

// Build multiple messages efficiently
const buildRequests = releases.map(release => ({
releases: [release],
preset: 'youtube_album',
version: '4.3'
}));

const xmlResults = await batchBuild(
buildRequests.map(req => JSON.stringify(req))
);

Validation Optimization

// Skip validation during building for speed
const builder = new DdexBuilder();
builder.applyPreset('youtube_album');

// Add all data...
releases.forEach(release => builder.addRelease(release));

// Validate once at the end
const validation = await builder.validate();
if (validation.isValid) {
const xml = await builder.build();
}