@onlineapps/content-resolver
v1.1.15
Published
Automatic conversion between text content and storage references with Content Descriptor pattern
Maintainers
Readme
@onlineapps/content-resolver
Automatic conversion between text content and storage references with Content Descriptor Pattern.
Overview
ContentResolver provides unified API for working with:
- Inline strings - Small text content (< 16KB)
- File references - Large content stored in MinIO
- Binary files - PDFs, images, etc.
All content is represented as Content Descriptors with consistent metadata (filename, content_type, size, fingerprint).
Threshold
Default threshold: 16 KB (16384 bytes)
Content larger than threshold is automatically stored in MinIO and returned as a Descriptor.
Usage
Basic Usage
const ContentResolver = require('@onlineapps/content-resolver');
const resolver = new ContentResolver({
threshold: 16 * 1024, // 16KB (default)
storage: {
endPoint: 'api_shared_storage',
port: 9000,
accessKey: 'minioadmin',
secretKey: 'minioadmin'
}
});
// Resolve reference to content
const content = await resolver.resolve('minio://workflow/path/to/file.txt');
// → Returns actual file content
// Store large content - returns Content Descriptor
const descriptor = await resolver.store(largeText, { workflow_id: 'wf-123' }, 'document.html');
// → {
// _descriptor: true,
// type: 'file',
// storage_ref: 'minio://workflow/...',
// filename: 'document.html',
// content_type: 'text/html',
// size: 50000,
// fingerprint: 'sha256...'
// }In Business Service Handler
const ContentResolver = require('@onlineapps/content-resolver');
exports.processDocument = async (input, context = {}) => {
const resolver = new ContentResolver();
// Input can be either text or reference - resolve transparently
const resolvedInput = await resolver.resolveInput(input, ['content', 'markdown']);
// Now resolvedInput.content and resolvedInput.markdown are always text
const result = processContent(resolvedInput.content);
// Store large output as reference
const output = await resolver.storeOutput({ result }, context, ['result']);
return output;
};API
new ContentResolver(options)
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| threshold | number | 16384 | Size threshold in bytes |
| storage | Object | env-based | Storage connector config |
| logger | Object | console | Logger instance |
Methods
resolve(value): Promise<string>
If value is a reference (minio://...), downloads and returns content.
Otherwise returns value unchanged.
store(content, context, filename?, content_type?): Promise<Object>
Stores content and returns Content Descriptor. If size > threshold, stores in MinIO.
Returns Descriptor with type: 'inline' or type: 'file'.
getAsBuffer(value): Promise<Buffer>
Unified API to get content as Buffer. Accepts:
- Plain string → converts to Buffer
- Storage reference (
minio://...) → downloads and returns Buffer - Content Descriptor → extracts content as Buffer
getAsString(value): Promise<string>
Unified API to get content as string. Works with string, reference, or Descriptor.
getMetadata(value): Object
Get metadata (filename, content_type, size, fingerprint) from any value type.
createDescriptor(content, options): Promise<Object>
Create Content Descriptor from raw content. Automatically decides inline vs file storage.
normalizeToDescriptor(value, options): Promise<Object>
Normalize any value (string, reference, Buffer) to Content Descriptor.
createDescriptorFromFile(tempPath, options): Promise<Object>
Create Content Descriptor from a temp file. Used by ApiMapper for file outputs.
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| filename | string | basename | Output filename |
| content_type | string | auto-detect | MIME type |
| context | Object | {} | { workflow_id, step_id } |
| deleteAfterUpload | boolean | true | Delete temp file after upload |
// Handler returns temp file path
const handlerOutput = { temp_path: '/tmp/output.pdf', filename: 'report.pdf', content_type: 'application/pdf' };
// ApiMapper calls createDescriptorFromFile
const descriptor = await resolver.createDescriptorFromFile(handlerOutput.temp_path, {
filename: handlerOutput.filename,
content_type: handlerOutput.content_type,
context: { workflow_id: 'wf-123', step_id: 'pdf_gen' },
deleteAfterUpload: true // Cleanup temp file
});
// → Content Descriptor with _descriptor: true, type: 'file', storage_ref, etc.resolveInput(input, fields?): Promise<Object>
Resolves all reference fields in input object (legacy method).
storeOutput(output, context, fields?): Promise<Object>
Stores large content fields as Descriptors (returns Descriptors, not plain strings).
Content Descriptor Pattern
Descriptor Structure
// Inline content (small)
{
_descriptor: true,
type: 'inline',
content: 'actual text content',
encoding: 'utf-8',
filename: 'document.txt',
content_type: 'text/plain',
size: 1234,
fingerprint: 'sha256...'
}
// File content (large or binary)
{
_descriptor: true,
type: 'file',
storage_ref: 'minio://workflow/path/to/file',
filename: 'invoice.pdf',
content_type: 'application/pdf',
size: 56607,
fingerprint: 'sha256...'
}Descriptor Identification:
_descriptor: true- Explicit identifier that value is a Content Descriptortype: "inline"|"file"- Distinguishes inline text from file reference
Usage Example
const resolver = new ContentResolver();
// Work with attachments - unified API
async function processAttachment(attachment) {
// Get content as Buffer (works with string, reference, or Descriptor)
const buffer = await resolver.getAsBuffer(attachment.value);
// Get metadata
const meta = resolver.getMetadata(attachment.value);
console.log(`Processing ${meta.filename} (${meta.size} bytes)`);
// Process buffer...
return processed;
}Utilities
const {
isReference,
parseReference,
isDescriptor,
getContentType,
DEFAULT_THRESHOLD
} = require('@onlineapps/content-resolver');
isReference('minio://bucket/path'); // true
isReference('plain text'); // false
isDescriptor({ type: 'file', storage_ref: '...' }); // true
isDescriptor('plain string'); // false
parseReference('minio://workflow/content/file.txt');
// → { bucket: 'workflow', path: 'content/file.txt' }
getContentType('invoice.pdf'); // 'application/pdf'
getContentType('document.html'); // 'text/html'Reference Formats
Supported formats:
minio://bucket/path/to/fileinternal://storage/path/to/file(uses default bucket)
