Files
smartregistry/readme.md

175 lines
5.2 KiB
Markdown
Raw Normal View History

# @push.rocks/smartregistry
2025-11-19 15:16:20 +00:00
A TypeScript library implementing the OCI Distribution Specification v1.1 for building container and artifact registries.
2025-11-19 15:16:20 +00:00
## Features
2025-11-19 15:16:20 +00:00
- **OCI Distribution Spec v1.1 Compliant**: Implements all required and optional endpoints
- **Cloud-Agnostic Storage**: Uses @push.rocks/smartbucket for S3-compatible object storage
- **Pluggable Authentication**: Async callbacks for login and authorization
- **Bearer Token Auth**: JWT-based authentication following Docker Registry Token Authentication spec
- **Programmatic API**: Use as a library in any Node.js/TypeScript application
- **Full CRUD Operations**: Push, pull, list, and delete manifests and blobs
- **Content Discovery**: Tag listing and referrers API for artifact relationships
- **Chunked Uploads**: Support for large blob uploads with resumable sessions
## Installation
```bash
npm install @push.rocks/smartregistry
# or
pnpm add @push.rocks/smartregistry
```
## Usage
### Basic Setup
```typescript
import { SmartRegistry, IRegistryConfig, TLoginCallback, TAuthCallback } from '@push.rocks/smartregistry';
// Implement login callback
const loginCallback: TLoginCallback = async (credentials) => {
// Validate credentials and return JWT token
// This should create a proper JWT with required claims
return generateJWT(credentials.username);
};
// Implement authorization callback
const authCallback: TAuthCallback = async (token, repository, action) => {
// Validate token and check permissions
const claims = verifyJWT(token);
return hasPermission(claims, repository, action);
};
// Configure registry
const config: IRegistryConfig = {
storage: {
accessKey: 'your-s3-access-key',
accessSecret: 'your-s3-secret',
endpoint: 's3.amazonaws.com',
port: 443,
useSsl: true,
region: 'us-east-1',
bucketName: 'my-registry',
},
serviceName: 'my-registry',
tokenRealm: 'https://auth.example.com/token',
loginCallback,
authCallback,
};
// Create and initialize registry
const registry = new SmartRegistry(config);
await registry.init();
```
### Integration with HTTP Server
```typescript
import express from 'express';
const app = express();
// OCI Distribution API endpoints
app.get('/v2/', (req, res) => {
res.status(200).json({});
});
app.get('/v2/:name(*)/manifests/:reference', async (req, res) => {
const { name, reference } = req.params;
const token = req.headers.authorization?.replace('Bearer ', '');
const result = await registry.getManifest(name, reference, token);
if ('errors' in result) {
return res.status(404).json(result);
}
res.setHeader('Content-Type', result.contentType);
res.setHeader('Docker-Content-Digest', result.digest);
res.send(result.data);
});
app.get('/v2/:name(*)/blobs/:digest', async (req, res) => {
const { name, digest } = req.params;
const token = req.headers.authorization?.replace('Bearer ', '');
const result = await registry.getBlob(name, digest, token);
if ('errors' in result) {
return res.status(404).json(result);
}
res.setHeader('Content-Type', 'application/octet-stream');
res.send(result.data);
});
// ... implement other endpoints
app.listen(5000);
```
### Authentication Flow
```typescript
// Client requests without token
const challenge = registry.getAuthChallenge('library/nginx', ['pull', 'push']);
// Returns: Bearer realm="https://auth.example.com/token",service="my-registry",scope="repository:library/nginx:pull,push"
// Client authenticates
const token = await registry.login({ username: 'user', password: 'pass' });
// Client uses token for subsequent requests
const manifest = await registry.getManifest('library/nginx', 'latest', token);
```
## API Reference
### Pull Operations (Required)
- `getManifest(repository, reference, token?)` - Download a manifest
- `headManifest(repository, reference, token?)` - Check manifest existence
- `getBlob(repository, digest, token?, range?)` - Download a blob
- `headBlob(repository, digest, token?)` - Check blob existence
### Push Operations
- `initiateUpload(repository, token, mountDigest?, fromRepository?)` - Start blob upload
- `uploadChunk(uploadId, data, contentRange, token)` - Upload blob chunk
- `completeUpload(uploadId, digest, token, finalData?)` - Finalize blob upload
- `putManifest(repository, reference, manifest, contentType, token)` - Upload manifest
### Content Discovery
- `listTags(repository, token?, pagination?)` - List all tags
- `getReferrers(repository, digest, token?, artifactType?)` - Get referencing artifacts
### Content Management
- `deleteManifest(repository, digest, token)` - Delete manifest
- `deleteBlob(repository, digest, token)` - Delete blob
- `deleteTag(repository, tag, token)` - Delete tag
### Authentication
- `login(credentials)` - Get authentication token
- `getAuthChallenge(repository, actions)` - Generate WWW-Authenticate header
## OCI Specification Compliance
This library implements:
- **Pull Category** (required): All manifest and blob retrieval operations
- **Push Category**: Complete blob upload workflow with chunked and monolithic modes
- **Content Discovery**: Tag listing and referrers API
- **Content Management**: Deletion operations for manifests, blobs, and tags
## License
MIT
## Contributing
See the main repository for contribution guidelines.