nulti registry support
This commit is contained in:
173
readme.md
173
readme.md
@@ -1,7 +1,174 @@
|
||||
# @push.rocks/smartregistry
|
||||
|
||||
a registry for npm modules and oci images
|
||||
A TypeScript library implementing the OCI Distribution Specification v1.1 for building container and artifact registries.
|
||||
|
||||
## How to create the docs
|
||||
## Features
|
||||
|
||||
To create docs run gitzone aidoc.
|
||||
- **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.
|
||||
|
||||
Reference in New Issue
Block a user