atpi
v1.0.7
Published
Resolve AT Protocol URLs to JSON data
Maintainers
Readme
atpi
Resolve AT Protocol URLs to JSON data with ease. This package provides both a CLI tool and a programmatic API for resolving at:// URLs.
Features
- Local Resolution: Connect directly to PDS servers (default)
- Remote Resolution: Use the atpi.at service
- Automatic Fallback: Falls back to remote if local fails
- Smart Caching: Caches DID and handle resolutions
- Multiple Modes: Choose between local, remote, or auto mode
- Tab Completion: Smart shell completion for AT Protocol URLs
Installation
Global Install (for CLI usage)
npm install -g atpi
# Optional: Enable tab completion
atpi --install-completionLocal Install (for programmatic usage)
npm install atpiQuick Start
After installation, you can immediately use atpi:
# Resolve an AT Protocol URL
atpi at://did:plc:7gm5ejhut7kia2kzglqfew5b/app.bsky.feed.post/3lszcx7zf622q
# With tab completion enabled, press TAB to see available collections
atpi at://did:plc:7gm5ejhut7kia2kzglqfew5b/<TAB>CLI Usage
Once installed globally, you can use the atpi command directly from your terminal:
# Basic usage (pretty printed by default)
atpi at://did:plc:7gm5ejhut7kia2kzglqfew5b/app.bsky.feed.post/3lszcx7zf622q
# Compact JSON output
atpi at://did:plc:7gm5ejhut7kia2kzglqfew5b/app.bsky.feed.post/3lszcx7zf622q --compact
# Save to file
atpi at://did:plc:7gm5ejhut7kia2kzglqfew5b/app.bsky.feed.post/3lszcx7zf622q > post.json
# Process with jq
atpi at://did:plc:7gm5ejhut7kia2kzglqfew5b/app.bsky.feed.post/3lszcx7zf622q | jq '.value.text'
# Multiple URLs
atpi at://did:plc:7gm5ejhut7kia2kzglqfew5b at://did:plc:7gm5ejhut7kia2kzglqfew5b/app.bsky.actor.profile/self
# Local resolution (default - connects directly to PDS)
atpi at://did:plc:7gm5ejhut7kia2kzglqfew5b/app.bsky.feed.post/3lszcx7zf622q --local
# Remote resolution (uses atpi.at service)
atpi at://did:plc:7gm5ejhut7kia2kzglqfew5b/app.bsky.feed.post/3lszcx7zf622q --remote
# Custom timeout (in milliseconds)
atpi at://did:plc:7gm5ejhut7kia2kzglqfew5b/app.bsky.feed.post/3lszcx7zf622q --timeout 10000Programmatic Usage
JavaScript
const atpi = require('atpi');
// Using async/await
async function getPost() {
try {
const data = await atpi.resolve('at://did:plc:7gm5ejhut7kia2kzglqfew5b/app.bsky.feed.post/3lszcx7zf622q');
console.log(data);
} catch (error) {
console.error('Failed to resolve:', error.message);
}
}
// Using promises
atpi.resolve('at://did:plc:7gm5ejhut7kia2kzglqfew5b/app.bsky.feed.post/3lszcx7zf622q')
.then(data => console.log(data))
.catch(error => console.error(error));TypeScript
import atpi, { ATProtocolData, ATProtocolError } from 'atpi';
async function getPost(): Promise<void> {
try {
const data: ATProtocolData = await atpi.resolve('at://did:plc:7gm5ejhut7kia2kzglqfew5b/app.bsky.feed.post/3lszcx7zf622q');
console.log(data);
} catch (error) {
if (error instanceof ATProtocolError) {
console.error(`AT Protocol Error: ${error.message}`);
if (error.statusCode) {
console.error(`Status Code: ${error.statusCode}`);
}
}
}
}Advanced Options
// Resolution modes
const options = {
mode: 'local', // 'local' | 'remote' | 'auto' (default: 'local')
timeout: 60000, // Request timeout in ms (default: 30000)
fallbackToRemote: true, // Fall back to remote if local fails (default: true)
baseUrl: 'https://custom.resolver/' // Custom remote resolver URL
};
const data = await atpi.resolve('at://...', options);
// Force remote resolution
const remoteData = await atpi.resolve('at://...', { mode: 'remote' });
// Use local with no fallback
const localData = await atpi.resolve('at://...', {
mode: 'local',
fallbackToRemote: false
});API Reference
atpi.resolve(url, options?)
Resolves an AT Protocol URL to JSON data.
- url (string): The AT Protocol URL to resolve (must start with
at://) - options (object, optional):
- mode (string): Resolution mode - 'local', 'remote', or 'auto' (default: 'local')
- timeout (number): Request timeout in milliseconds (default: 30000)
- fallbackToRemote (boolean): Fall back to remote if local fails (default: true)
- baseUrl (string): Custom remote resolver base URL (default: 'https://atpi.')
- Returns: Promise - The resolved JSON data
- Throws: ATProtocolError - If the URL is invalid or resolution fails
Error Handling
The package exports an ATProtocolError class for specific error handling:
import { ATProtocolError } from 'atpi';
try {
const data = await atpi.resolve('at://...');
} catch (error) {
if (error instanceof ATProtocolError) {
console.error('AT Protocol specific error:', error.message);
console.error('Status code:', error.statusCode);
} else {
console.error('Unexpected error:', error);
}
}How It Works
Local Resolution (Default)
The package connects directly to AT Protocol Personal Data Servers (PDS) to resolve URLs:
- Parse AT URI: Extract identifier (DID/handle), collection, and record key
- Resolve Handle: If needed, resolve handle to DID using known PDS endpoints
- Resolve DID: Get the PDS endpoint URL from the DID document
- Fetch Data: Request data directly from the PDS using XRPC endpoints
- Cache Results: Cache DID and handle resolutions for better performance
Remote Resolution
When using remote mode, the package transforms AT Protocol URLs to HTTP URLs by prepending a resolver service URL (by default https://atpi.). For example:
at://did:plc:7gm5ejhut7kia2kzglqfew5b/app.bsky.feed.post/3lszcx7zf622qbecomeshttps://atpi.at://did:plc:7gm5ejhut7kia2kzglqfew5b/app.bsky.feed.post/3lszcx7zf622q
Resolution Modes
- Local: Direct PDS connection (faster, no external dependencies)
- Remote: Via atpi.at service (simpler, works behind restrictive firewalls)
- Auto: Try local first, fall back to remote if needed
Tab Completion
The package includes smart tab completion that fetches real collections from AT Protocol!
Easy Installation
After installing atpi globally, run:
atpi --install-completionThis will automatically set up tab completion for zsh.
How It Works
- Smart completions: Fetches actual collections from AT Protocol for any DID
- Local caching: Collections are cached for 24 hours for fast performance
- Partial matching: Type partial collection names and tab to complete
- Offline support: Uses cached data when internet is unavailable
Examples
# Complete a DID's collections (fetches real collections!)
atpi at://did:plc:7gm5ejhut7kia2kzglqfew5b/<TAB>
# Shows: app.bsky.actor.profile app.bsky.feed.post app.bsky.graph.follow ...
# Partial collection name completion
atpi at://did:plc:7gm5ejhut7kia2kzglqfew5b/app.bsky.graph.<TAB>
# Shows: app.bsky.graph.block app.bsky.graph.follow app.bsky.graph.list ...
# Command options
atpi --<TAB>
# Shows: --help --compact --install-completionManual Installation
If automatic installation doesn't work, you can manually add completion:
For zsh:
# Add the completion directory to fpath
echo "fpath=($(npm root -g)/atpi/completions \$fpath)" >> ~/.zshrc
echo "autoload -Uz compinit && compinit" >> ~/.zshrc
source ~/.zshrcLicense
MIT
