lumen-client
v1.0.0
Published
A fully typed TypeScript client for the Lumen Database API
Downloads
106
Maintainers
Readme
lumen-client
A fully typed TypeScript client for the Lumen Database API.
Features
- Full TypeScript support with branded types, discriminated unions, and comprehensive type guards
- Async iterators for automatic pagination handling
- Automatic retry with exponential backoff for rate limiting
- Zero dependencies - uses native
fetch
Installation
npm install lumen-clientQuick Start
import { LumenClient, NoticeId, isDMCANotice } from 'lumen-client';
const client = new LumenClient({
authToken: 'your-api-token',
userAgent: 'MyApp/1.0',
});
// Get a notice
const notice = await client.getNotice(NoticeId(12345));
// Type narrowing with type guards
if (isDMCANotice(notice)) {
console.log(notice.works);
}
// Or use switch for exhaustive handling
switch (notice.type) {
case 'DMCA':
console.log(notice.body);
break;
case 'Trademark':
console.log(notice.marks);
break;
// ... handle other types
}Usage
Searching Notices
const results = await client.searchNotices({
term: 'copyright',
term_require_all: true,
sender_name_facet: 'RIAA',
sort_by: 'date_received desc',
page: 1,
per_page: 25,
});
console.log(`Found ${results.meta.total_entries} notices`);
// Access facet aggregations
for (const facet of results.meta.facets.sender_name_facet?.terms ?? []) {
console.log(`${facet.term}: ${facet.count}`);
}Iterating Through All Results
// Automatically handles pagination
for await (const notice of client.searchNoticesIterator({ term: 'music' })) {
console.log(notice.title);
}Creating a Notice
const result = await client.createNotice({
type: 'DMCA',
title: 'Copyright Notice',
works_attributes: [{
kind: 'Image',
description: 'My photograph',
infringing_urls_attributes: [{ url: 'https://example.com/stolen.jpg' }],
}],
});
console.log('Created notice:', result.id);Searching Entities
const results = await client.searchEntities({
term: 'Google',
per_page: 50,
});
for (const entity of results.entities) {
console.log(`${entity.name} (${entity.kind})`);
}Working with Topics
// Get all topics
const { topics } = await client.getTopics();
// Get hierarchical topic tree
const tree = await client.getTopicsTree();API Reference
Client Methods
| Method | Description |
|--------|-------------|
| getNotice(id) | Get a single notice by ID |
| getNoticeOfType(id, type) | Get a notice with type assertion |
| getNoticeBySubmissionId(id) | Get a notice by submission ID |
| searchNotices(params) | Search notices with filters |
| searchNoticesIterator(params) | Async iterator for notice search |
| getAllNotices(params, limit) | Get all matching notices up to limit |
| getNotices(ids) | Get multiple notices by ID |
| createNotice(notice) | Create a new notice |
| createNoticeWithFiles(notice, files) | Create notice with file uploads |
| searchEntities(params) | Search entities |
| searchEntitiesIterator(params) | Async iterator for entity search |
| getTopics() | Get all topics |
| getTopicsTree() | Get hierarchical topic tree |
Configuration
const client = new LumenClient({
// Base URL (default: https://lumendatabase.org)
baseUrl: 'https://lumendatabase.org',
// API authentication token
authToken: 'your-token',
// User agent (required - default agents are blocked)
userAgent: 'MyApp/1.0',
// Request timeout in ms (default: 30000)
timeout: 30000,
// Custom headers
headers: { 'X-Custom': 'value' },
// Retry on rate limiting (default: true)
retryOnRateLimit: true,
// Max retries (default: 3)
maxRetries: 3,
// Base retry delay in ms (default: 1000)
retryDelay: 1000,
// Custom fetch implementation
fetch: customFetch,
});Notice Types
The client supports all Lumen notice types with full type discrimination:
DMCA- DMCA takedown requestsCounternotice- Responses to DMCA takedownsCourtOrder- Court-ordered removalsDataProtection- Data protection requestsDefamation- Defamation claimsGovernmentRequest- Government removal requestsLawEnforcementRequest- Law enforcement requestsOther- Other notice typesPrivateInformation- Private information removalTrademark- Trademark infringementCounterfeit- Counterfeit claimsPlaceholder- Placeholder notices
Type Guards
import {
isDMCANotice,
isTrademarkNotice,
isNoticeWithMarks,
isNoticeWithRequestType,
isLumenApiError,
} from 'lumen-client';
if (isDMCANotice(notice)) {
// notice is DMCANotice
}
if (isNoticeWithMarks(notice)) {
// notice is TrademarkNotice | CounterfeitNotice
console.log(notice.marks);
}Branded Types
The client uses branded types for type-safe IDs:
import { NoticeId, EntityId, TopicId } from 'lumen-client';
const noticeId = NoticeId(12345); // Type: NoticeId
const entityId = EntityId(67890); // Type: EntityIdError Handling
import { LumenApiError, isLumenApiError } from 'lumen-client';
try {
await client.getNotice(NoticeId(999999999));
} catch (error) {
if (isLumenApiError(error)) {
console.log(error.status); // HTTP status code
console.log(error.isNotFound); // true for 404
console.log(error.isRateLimited); // true for 429
console.log(error.isUnauthorized); // true for 401
// Access validation errors
if (error.isValidationError) {
console.log(error.getFieldErrors('title'));
}
}
}Requirements
- Node.js >= 18.0.0
- TypeScript >= 5.3.0 (for development)
License
MIT
