feat(core,storage,oci,registry-config): add streaming response support and configurable registry URLs across protocols
This commit is contained in:
@@ -2,6 +2,7 @@ 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 { toReadableStream } from './core/helpers.stream.js';
|
||||
import { OciRegistry } from './oci/classes.ociregistry.js';
|
||||
import { NpmRegistry } from './npm/classes.npmregistry.js';
|
||||
import { MavenRegistry } from './maven/classes.mavenregistry.js';
|
||||
@@ -95,7 +96,7 @@ export class SmartRegistry {
|
||||
// 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 registryUrl = this.config.npm.registryUrl ?? `http://localhost:5000${npmBasePath}`;
|
||||
const npmRegistry = new NpmRegistry(
|
||||
this.storage,
|
||||
this.authManager,
|
||||
@@ -110,7 +111,7 @@ export class SmartRegistry {
|
||||
// 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 registryUrl = this.config.maven.registryUrl ?? `http://localhost:5000${mavenBasePath}`;
|
||||
const mavenRegistry = new MavenRegistry(
|
||||
this.storage,
|
||||
this.authManager,
|
||||
@@ -125,7 +126,7 @@ export class SmartRegistry {
|
||||
// Initialize Cargo registry if enabled
|
||||
if (this.config.cargo?.enabled) {
|
||||
const cargoBasePath = this.config.cargo.basePath ?? '/cargo';
|
||||
const registryUrl = `http://localhost:5000${cargoBasePath}`; // TODO: Make configurable
|
||||
const registryUrl = this.config.cargo.registryUrl ?? `http://localhost:5000${cargoBasePath}`;
|
||||
const cargoRegistry = new CargoRegistry(
|
||||
this.storage,
|
||||
this.authManager,
|
||||
@@ -140,7 +141,7 @@ export class SmartRegistry {
|
||||
// Initialize Composer registry if enabled
|
||||
if (this.config.composer?.enabled) {
|
||||
const composerBasePath = this.config.composer.basePath ?? '/composer';
|
||||
const registryUrl = `http://localhost:5000${composerBasePath}`; // TODO: Make configurable
|
||||
const registryUrl = this.config.composer.registryUrl ?? `http://localhost:5000${composerBasePath}`;
|
||||
const composerRegistry = new ComposerRegistry(
|
||||
this.storage,
|
||||
this.authManager,
|
||||
@@ -155,7 +156,7 @@ export class SmartRegistry {
|
||||
// Initialize PyPI registry if enabled
|
||||
if (this.config.pypi?.enabled) {
|
||||
const pypiBasePath = this.config.pypi.basePath ?? '/pypi';
|
||||
const registryUrl = `http://localhost:5000`; // TODO: Make configurable
|
||||
const registryUrl = this.config.pypi.registryUrl ?? `http://localhost:5000`;
|
||||
const pypiRegistry = new PypiRegistry(
|
||||
this.storage,
|
||||
this.authManager,
|
||||
@@ -170,7 +171,7 @@ export class SmartRegistry {
|
||||
// Initialize RubyGems registry if enabled
|
||||
if (this.config.rubygems?.enabled) {
|
||||
const rubygemsBasePath = this.config.rubygems.basePath ?? '/rubygems';
|
||||
const registryUrl = `http://localhost:5000${rubygemsBasePath}`; // TODO: Make configurable
|
||||
const registryUrl = this.config.rubygems.registryUrl ?? `http://localhost:5000${rubygemsBasePath}`;
|
||||
const rubygemsRegistry = new RubyGemsRegistry(
|
||||
this.storage,
|
||||
this.authManager,
|
||||
@@ -191,75 +192,88 @@ export class SmartRegistry {
|
||||
*/
|
||||
public async handleRequest(context: IRequestContext): Promise<IResponse> {
|
||||
const path = context.path;
|
||||
let response: IResponse | undefined;
|
||||
|
||||
// Route to OCI registry
|
||||
if (this.config.oci?.enabled && path.startsWith(this.config.oci.basePath)) {
|
||||
if (!response && this.config.oci?.enabled && path.startsWith(this.config.oci.basePath)) {
|
||||
const ociRegistry = this.registries.get('oci');
|
||||
if (ociRegistry) {
|
||||
return ociRegistry.handleRequest(context);
|
||||
response = await ociRegistry.handleRequest(context);
|
||||
}
|
||||
}
|
||||
|
||||
// Route to NPM registry
|
||||
if (this.config.npm?.enabled && path.startsWith(this.config.npm.basePath)) {
|
||||
if (!response && this.config.npm?.enabled && path.startsWith(this.config.npm.basePath)) {
|
||||
const npmRegistry = this.registries.get('npm');
|
||||
if (npmRegistry) {
|
||||
return npmRegistry.handleRequest(context);
|
||||
response = await npmRegistry.handleRequest(context);
|
||||
}
|
||||
}
|
||||
|
||||
// Route to Maven registry
|
||||
if (this.config.maven?.enabled && path.startsWith(this.config.maven.basePath)) {
|
||||
if (!response && this.config.maven?.enabled && path.startsWith(this.config.maven.basePath)) {
|
||||
const mavenRegistry = this.registries.get('maven');
|
||||
if (mavenRegistry) {
|
||||
return mavenRegistry.handleRequest(context);
|
||||
response = await mavenRegistry.handleRequest(context);
|
||||
}
|
||||
}
|
||||
|
||||
// Route to Cargo registry
|
||||
if (this.config.cargo?.enabled && path.startsWith(this.config.cargo.basePath)) {
|
||||
if (!response && this.config.cargo?.enabled && path.startsWith(this.config.cargo.basePath)) {
|
||||
const cargoRegistry = this.registries.get('cargo');
|
||||
if (cargoRegistry) {
|
||||
return cargoRegistry.handleRequest(context);
|
||||
response = await cargoRegistry.handleRequest(context);
|
||||
}
|
||||
}
|
||||
|
||||
// Route to Composer registry
|
||||
if (this.config.composer?.enabled && path.startsWith(this.config.composer.basePath)) {
|
||||
if (!response && this.config.composer?.enabled && path.startsWith(this.config.composer.basePath)) {
|
||||
const composerRegistry = this.registries.get('composer');
|
||||
if (composerRegistry) {
|
||||
return composerRegistry.handleRequest(context);
|
||||
response = await composerRegistry.handleRequest(context);
|
||||
}
|
||||
}
|
||||
|
||||
// Route to PyPI registry (also handles /simple prefix)
|
||||
if (this.config.pypi?.enabled) {
|
||||
if (!response && this.config.pypi?.enabled) {
|
||||
const pypiBasePath = this.config.pypi.basePath ?? '/pypi';
|
||||
if (path.startsWith(pypiBasePath) || path.startsWith('/simple')) {
|
||||
const pypiRegistry = this.registries.get('pypi');
|
||||
if (pypiRegistry) {
|
||||
return pypiRegistry.handleRequest(context);
|
||||
response = await pypiRegistry.handleRequest(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Route to RubyGems registry
|
||||
if (this.config.rubygems?.enabled && path.startsWith(this.config.rubygems.basePath)) {
|
||||
if (!response && this.config.rubygems?.enabled && path.startsWith(this.config.rubygems.basePath)) {
|
||||
const rubygemsRegistry = this.registries.get('rubygems');
|
||||
if (rubygemsRegistry) {
|
||||
return rubygemsRegistry.handleRequest(context);
|
||||
response = await rubygemsRegistry.handleRequest(context);
|
||||
}
|
||||
}
|
||||
|
||||
// No matching registry
|
||||
return {
|
||||
status: 404,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: {
|
||||
error: 'NOT_FOUND',
|
||||
message: 'No registry handler for this path',
|
||||
},
|
||||
};
|
||||
if (!response) {
|
||||
response = {
|
||||
status: 404,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: {
|
||||
error: 'NOT_FOUND',
|
||||
message: 'No registry handler for this path',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// Normalize body to ReadableStream<Uint8Array> at the API boundary
|
||||
if (response.body != null && !(response.body instanceof ReadableStream)) {
|
||||
if (!Buffer.isBuffer(response.body) && typeof response.body === 'object' && !(response.body instanceof Uint8Array)) {
|
||||
response.headers['Content-Type'] ??= 'application/json';
|
||||
}
|
||||
response.body = toReadableStream(response.body);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user