@musallam/lightroom-client
v2.2.0
Published
TypeScript client library for Adobe Lightroom API
Maintainers
Readme
@musallam/lightroom-client
TypeScript client library for the Adobe Lightroom API - programmatically apply Lightroom settings and image adjustments to photos.
Features
- 🚀 Full TypeScript support with auto-generated types from OpenAPI spec
- 📦 Complete API coverage for all Lightroom endpoints
- 🔄 Job polling utilities for async operations
- 🔐 Built-in authentication via IMS client
- 📝 Comprehensive documentation and examples
Installation
npm install @musallam/lightroom-clientQuick Start
import {
LightroomClient,
LIGHTROOM_AXIOS_INSTANCE,
TokenIMSClient,
pollLightroomJob,
} from '@musallam/lightroom-client';
// 1. Setup authentication
const imsClient = new TokenIMSClient({
clientId: 'YOUR_CLIENT_ID',
clientSecret: 'YOUR_CLIENT_SECRET',
scopes: ['openid', 'AdobeID', 'firefly_api', 'ff_apis'],
});
// 2. Configure axios instance
LIGHTROOM_AXIOS_INSTANCE.interceptors.request.use(async (config) => {
const token = await imsClient.getAccessToken();
config.headers.Authorization = `Bearer ${token}`;
config.headers['x-api-key'] = 'YOUR_CLIENT_ID';
return config;
});
// 3. Apply auto-tone to an image
const job = await LightroomClient.autoTone({
inputs: {
href: 'https://your-bucket.s3.amazonaws.com/image.jpg',
storage: 'external',
},
outputs: [
{
href: 'https://your-bucket.s3.amazonaws.com/output.jpg',
storage: 'external',
},
],
});
// 4. Poll for results
const result = await pollLightroomJob(job, {
onProgress: (status) => console.log(`Status: ${status.status}`),
});
console.log('Processed image:', result.outputs?.[0]?.href);API Coverage
The client provides full TypeScript support for:
Image Processing
presets()- Apply Lightroom presetxmp()- Apply XMP settingsautoStraighten()- Auto-straighten imageautoTone()- Auto-adjust image toneedit()- Apply manual image edits
Job Management
acrstatus()- Get job statuspollLightroomJob()- Poll until completion (utility)
Usage Examples
Apply Lightroom Preset
const job = await LightroomClient.presets({
inputs: {
source: {
href: 'https://your-bucket.s3.amazonaws.com/photo.jpg',
storage: 'external',
},
presets: [
{
href: 'https://your-bucket.s3.amazonaws.com/preset.xmp',
storage: 'external',
},
],
},
outputs: [
{
href: 'https://your-bucket.s3.amazonaws.com/result.jpg',
storage: 'external',
},
],
});
const result = await pollLightroomJob(job);
console.log('Processed:', result.outputs?.[0]?.href);Apply XMP Settings
const job = await LightroomClient.xmp({
inputs: {
source: {
href: 'https://your-bucket.s3.amazonaws.com/photo.jpg',
storage: 'external',
},
xmp: {
href: 'https://your-bucket.s3.amazonaws.com/settings.xmp',
storage: 'external',
},
},
outputs: [
{
href: 'https://your-bucket.s3.amazonaws.com/edited.jpg',
storage: 'external',
},
],
});Auto-Straighten Image
const job = await LightroomClient.autoStraighten({
inputs: {
href: 'https://your-bucket.s3.amazonaws.com/crooked.jpg',
storage: 'external',
},
outputs: [
{
href: 'https://your-bucket.s3.amazonaws.com/straightened.jpg',
storage: 'external',
},
],
});
const result = await pollLightroomJob(job, {
intervalMs: 2000,
maxAttempts: 60,
});Auto-Tone Adjustment
const job = await LightroomClient.autoTone({
inputs: {
href: 'https://your-bucket.s3.amazonaws.com/photo.jpg',
storage: 'external',
},
outputs: [
{
href: 'https://your-bucket.s3.amazonaws.com/auto-toned.jpg',
storage: 'external',
},
],
});Manual Image Edits
const job = await LightroomClient.edit({
inputs: {
source: {
href: 'https://your-bucket.s3.amazonaws.com/photo.jpg',
storage: 'external',
},
edits: {
href: 'https://your-bucket.s3.amazonaws.com/edits.json',
storage: 'external',
},
},
outputs: [
{
href: 'https://your-bucket.s3.amazonaws.com/edited.jpg',
storage: 'external',
},
],
});Job Polling
For async operations, use the polling utility:
import { pollLightroomJob, PollingTimeoutError } from '@musallam/lightroom-client';
try {
const result = await pollLightroomJob(jobResult, {
intervalMs: 2000, // Poll every 2 seconds
maxAttempts: 60, // Try up to 60 times
timeoutMs: 300000, // Or timeout after 5 minutes
onProgress: (status) => {
console.log(`Status: ${status.status}`);
if (status.status === 'running') {
console.log('Job is processing...');
}
},
});
console.log('Job completed:', result.outputs);
} catch (error) {
if (error instanceof PollingTimeoutError) {
console.error('Job timed out');
} else {
console.error('Job failed:', error);
}
}Error Handling
import axios from 'axios';
try {
const job = await LightroomClient.autoTone(request);
} catch (error) {
if (axios.isAxiosError(error)) {
const status = error.response?.status;
const data = error.response?.data;
switch (status) {
case 400:
console.error('Bad Request:', data.details?.reason);
break;
case 402:
console.error('Trial Limit Exceeded');
break;
case 403:
console.error('Forbidden:', data.details?.reason);
break;
case 404:
console.error('Resource Not Found');
break;
case 409:
console.error('File Overwrite Error');
break;
case 410:
console.error('Asset Link Invalid or Expired');
break;
default:
console.error('Error:', data);
}
}
}Advanced Configuration
Custom Axios Instance
import { LIGHTROOM_AXIOS_INSTANCE } from '@musallam/lightroom-client';
// Add custom headers
LIGHTROOM_AXIOS_INSTANCE.defaults.headers.common['X-Custom-Header'] = 'value';
// Add request interceptor
LIGHTROOM_AXIOS_INSTANCE.interceptors.request.use((config) => {
console.log(`Making request to ${config.url}`);
return config;
});
// Add response interceptor
LIGHTROOM_AXIOS_INSTANCE.interceptors.response.use(
(response) => response,
(error) => {
console.error('Request failed:', error.message);
return Promise.reject(error);
}
);Timeout Configuration
LIGHTROOM_AXIOS_INSTANCE.defaults.timeout = 30000; // 30 secondsIMS Organization ID (for Adobe I/O Events)
LIGHTROOM_AXIOS_INSTANCE.interceptors.request.use(async (config) => {
const token = await imsClient.getAccessToken();
config.headers.Authorization = `Bearer ${token}`;
config.headers['x-api-key'] = 'YOUR_CLIENT_ID';
config.headers['x-gw-ims-org-id'] = 'YOUR_ORG_ID'; // Optional, for events
return config;
});TypeScript Support
All types are automatically generated from the OpenAPI spec:
import type {
PostPresetsSchema,
PostXmpSchema,
PostAutoStraightenSchema,
PostAutoToneSchema,
PostImageEditSchema,
GetStatusSchema,
ApiResponseSuccessSchema,
} from '@musallam/lightroom-client';
const request: PostAutoToneSchema = {
inputs: {
href: 'https://example.com/image.jpg',
storage: 'external',
},
outputs: [
{
href: 'https://example.com/output.jpg',
storage: 'external',
},
],
};
const job = await LightroomClient.autoTone(request);Storage Options
The Lightroom API supports various storage options:
external- Pre-signed URLs to external storage (AWS S3, Azure, etc.)adobe- Adobe's cloud storage (requires different authentication)
Example with external storage:
const job = await LightroomClient.autoTone({
inputs: {
href: 'https://my-bucket.s3.amazonaws.com/input.jpg',
storage: 'external',
},
outputs: [
{
href: 'https://my-bucket.s3.amazonaws.com/output.jpg',
storage: 'external',
},
],
});Complete Example
import {
LightroomClient,
LIGHTROOM_AXIOS_INSTANCE,
TokenIMSClient,
pollLightroomJob,
} from '@musallam/lightroom-client';
async function processImage() {
// Setup authentication
const imsClient = new TokenIMSClient({
clientId: process.env.ADOBE_CLIENT_ID!,
clientSecret: process.env.ADOBE_CLIENT_SECRET!,
scopes: ['openid', 'AdobeID', 'firefly_api', 'ff_apis'],
});
LIGHTROOM_AXIOS_INSTANCE.interceptors.request.use(async (config) => {
const token = await imsClient.getAccessToken();
config.headers.Authorization = `Bearer ${token}`;
config.headers['x-api-key'] = process.env.ADOBE_CLIENT_ID!;
return config;
});
try {
// Apply auto-tone
console.log('Applying auto-tone...');
const job = await LightroomClient.autoTone({
inputs: {
href: 'https://my-bucket.s3.amazonaws.com/photo.jpg',
storage: 'external',
},
outputs: [
{
href: 'https://my-bucket.s3.amazonaws.com/auto-toned.jpg',
storage: 'external',
},
],
});
// Poll for completion
const result = await pollLightroomJob(job, {
intervalMs: 2000,
onProgress: (status) => {
console.log(`Job status: ${status.status}`);
},
});
console.log('✓ Processing complete!');
console.log('Output:', result.outputs?.[0]?.href);
} catch (error) {
console.error('Error processing image:', error);
}
}
processImage();License
MIT
Related Packages
- @musallam/firefly-client - Adobe Firefly Services API
- @musallam/photoshop-client - Adobe Photoshop API
- @musallam/storage-and-collaboration-client - Adobe Cloud Storage API
- @musallam/ims-client - Adobe Identity Management Services
