2025-11-19 15:32:00 +00:00
|
|
|
import { RegistryStorage } from './core/classes.registrystorage.js';
|
|
|
|
|
import { AuthManager } from './core/classes.authmanager.js';
|
|
|
|
|
import { BaseRegistry } from './core/classes.baseregistry.js';
|
|
|
|
|
import type { IRegistryConfig, IRequestContext, IResponse } from './core/interfaces.core.js';
|
|
|
|
|
import { OciRegistry } from './oci/classes.ociregistry.js';
|
|
|
|
|
import { NpmRegistry } from './npm/classes.npmregistry.js';
|
2025-11-21 08:58:29 +00:00
|
|
|
import { MavenRegistry } from './maven/classes.mavenregistry.js';
|
2025-11-19 15:16:20 +00:00
|
|
|
|
|
|
|
|
/**
|
2025-11-19 15:32:00 +00:00
|
|
|
* Main registry orchestrator
|
2025-11-21 08:58:29 +00:00
|
|
|
* Routes requests to appropriate protocol handlers (OCI, NPM, or Maven)
|
2025-11-19 15:16:20 +00:00
|
|
|
*/
|
|
|
|
|
export class SmartRegistry {
|
|
|
|
|
private storage: RegistryStorage;
|
2025-11-19 15:32:00 +00:00
|
|
|
private authManager: AuthManager;
|
|
|
|
|
private registries: Map<string, BaseRegistry> = new Map();
|
2025-11-19 15:16:20 +00:00
|
|
|
private config: IRegistryConfig;
|
|
|
|
|
private initialized: boolean = false;
|
|
|
|
|
|
|
|
|
|
constructor(config: IRegistryConfig) {
|
|
|
|
|
this.config = config;
|
|
|
|
|
this.storage = new RegistryStorage(config.storage);
|
2025-11-19 15:32:00 +00:00
|
|
|
this.authManager = new AuthManager(config.auth);
|
2025-11-19 15:16:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2025-11-19 15:32:00 +00:00
|
|
|
* Initialize the registry system
|
2025-11-19 15:16:20 +00:00
|
|
|
*/
|
|
|
|
|
public async init(): Promise<void> {
|
|
|
|
|
if (this.initialized) return;
|
|
|
|
|
|
2025-11-19 15:32:00 +00:00
|
|
|
// Initialize storage
|
|
|
|
|
await this.storage.init();
|
2025-11-19 15:16:20 +00:00
|
|
|
|
2025-11-19 15:32:00 +00:00
|
|
|
// Initialize auth manager
|
|
|
|
|
await this.authManager.init();
|
2025-11-19 15:16:20 +00:00
|
|
|
|
2025-11-19 15:32:00 +00:00
|
|
|
// Initialize OCI registry if enabled
|
|
|
|
|
if (this.config.oci?.enabled) {
|
|
|
|
|
const ociBasePath = this.config.oci.basePath || '/oci';
|
|
|
|
|
const ociRegistry = new OciRegistry(this.storage, this.authManager, ociBasePath);
|
|
|
|
|
await ociRegistry.init();
|
|
|
|
|
this.registries.set('oci', ociRegistry);
|
2025-11-19 15:16:20 +00:00
|
|
|
}
|
|
|
|
|
|
2025-11-19 15:32:00 +00:00
|
|
|
// Initialize NPM registry if enabled
|
|
|
|
|
if (this.config.npm?.enabled) {
|
|
|
|
|
const npmBasePath = this.config.npm.basePath || '/npm';
|
|
|
|
|
const registryUrl = `http://localhost:5000${npmBasePath}`; // TODO: Make configurable
|
|
|
|
|
const npmRegistry = new NpmRegistry(this.storage, this.authManager, npmBasePath, registryUrl);
|
|
|
|
|
await npmRegistry.init();
|
|
|
|
|
this.registries.set('npm', npmRegistry);
|
2025-11-19 15:16:20 +00:00
|
|
|
}
|
|
|
|
|
|
2025-11-21 08:58:29 +00:00
|
|
|
// Initialize Maven registry if enabled
|
|
|
|
|
if (this.config.maven?.enabled) {
|
|
|
|
|
const mavenBasePath = this.config.maven.basePath || '/maven';
|
|
|
|
|
const registryUrl = `http://localhost:5000${mavenBasePath}`; // TODO: Make configurable
|
|
|
|
|
const mavenRegistry = new MavenRegistry(this.storage, this.authManager, mavenBasePath, registryUrl);
|
|
|
|
|
await mavenRegistry.init();
|
|
|
|
|
this.registries.set('maven', mavenRegistry);
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-19 15:32:00 +00:00
|
|
|
this.initialized = true;
|
2025-11-19 15:16:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2025-11-19 15:32:00 +00:00
|
|
|
* Handle an incoming HTTP request
|
|
|
|
|
* Routes to the appropriate protocol handler based on path
|
2025-11-19 15:16:20 +00:00
|
|
|
*/
|
2025-11-19 15:32:00 +00:00
|
|
|
public async handleRequest(context: IRequestContext): Promise<IResponse> {
|
|
|
|
|
const path = context.path;
|
2025-11-19 15:16:20 +00:00
|
|
|
|
2025-11-19 15:32:00 +00:00
|
|
|
// Route to OCI registry
|
|
|
|
|
if (this.config.oci?.enabled && path.startsWith(this.config.oci.basePath)) {
|
|
|
|
|
const ociRegistry = this.registries.get('oci');
|
|
|
|
|
if (ociRegistry) {
|
|
|
|
|
return ociRegistry.handleRequest(context);
|
2025-11-19 15:16:20 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-19 15:32:00 +00:00
|
|
|
// Route to NPM registry
|
|
|
|
|
if (this.config.npm?.enabled && path.startsWith(this.config.npm.basePath)) {
|
|
|
|
|
const npmRegistry = this.registries.get('npm');
|
|
|
|
|
if (npmRegistry) {
|
|
|
|
|
return npmRegistry.handleRequest(context);
|
2025-11-19 15:16:20 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-21 08:58:29 +00:00
|
|
|
// Route to Maven registry
|
|
|
|
|
if (this.config.maven?.enabled && path.startsWith(this.config.maven.basePath)) {
|
|
|
|
|
const mavenRegistry = this.registries.get('maven');
|
|
|
|
|
if (mavenRegistry) {
|
|
|
|
|
return mavenRegistry.handleRequest(context);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-19 15:32:00 +00:00
|
|
|
// No matching registry
|
2025-11-19 15:16:20 +00:00
|
|
|
return {
|
2025-11-19 15:32:00 +00:00
|
|
|
status: 404,
|
|
|
|
|
headers: { 'Content-Type': 'application/json' },
|
|
|
|
|
body: {
|
|
|
|
|
error: 'NOT_FOUND',
|
|
|
|
|
message: 'No registry handler for this path',
|
|
|
|
|
},
|
2025-11-19 15:16:20 +00:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2025-11-19 15:32:00 +00:00
|
|
|
* Get the storage instance (for testing/advanced use)
|
2025-11-19 15:16:20 +00:00
|
|
|
*/
|
2025-11-19 15:32:00 +00:00
|
|
|
public getStorage(): RegistryStorage {
|
|
|
|
|
return this.storage;
|
2025-11-19 15:16:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2025-11-19 15:32:00 +00:00
|
|
|
* Get the auth manager instance (for testing/advanced use)
|
2025-11-19 15:16:20 +00:00
|
|
|
*/
|
2025-11-19 15:32:00 +00:00
|
|
|
public getAuthManager(): AuthManager {
|
|
|
|
|
return this.authManager;
|
2025-11-19 15:16:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2025-11-19 15:32:00 +00:00
|
|
|
* Get a specific registry handler
|
2025-11-19 15:16:20 +00:00
|
|
|
*/
|
2025-11-21 08:58:29 +00:00
|
|
|
public getRegistry(protocol: 'oci' | 'npm' | 'maven'): BaseRegistry | undefined {
|
2025-11-19 15:32:00 +00:00
|
|
|
return this.registries.get(protocol);
|
2025-11-19 15:16:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2025-11-19 15:32:00 +00:00
|
|
|
* Check if the registry is initialized
|
2025-11-19 15:16:20 +00:00
|
|
|
*/
|
2025-11-19 15:32:00 +00:00
|
|
|
public isInitialized(): boolean {
|
|
|
|
|
return this.initialized;
|
2025-11-19 15:16:20 +00:00
|
|
|
}
|
2025-11-20 19:46:34 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Clean up resources (timers, connections, etc.)
|
|
|
|
|
*/
|
|
|
|
|
public destroy(): void {
|
|
|
|
|
for (const registry of this.registries.values()) {
|
|
|
|
|
if (typeof (registry as any).destroy === 'function') {
|
|
|
|
|
(registry as any).destroy();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-11-19 15:16:20 +00:00
|
|
|
}
|