Refactor code structure for improved readability and maintainability

This commit is contained in:
2025-11-27 23:47:33 +00:00
parent ab88ac896f
commit 9f5e7e2558
23 changed files with 13024 additions and 109 deletions

View File

@@ -154,18 +154,22 @@ export class StackGalleryRegistry {
return await this.handleApiRequest(request);
}
// Registry protocol endpoints
// NPM: /-/..., /@scope/package, /package
// Registry protocol endpoints (handled by smartregistry)
// NPM: /-/..., /@scope/package (but not /packages which is UI route)
// OCI: /v2/...
// Maven: /maven2/...
// PyPI: /simple/..., /pypi/...
// Cargo: /api/v1/crates/...
// Composer: /packages.json, /p/...
// RubyGems: /api/v1/gems/..., /gems/...
const registryPaths = ['/-/', '/v2/', '/maven2/', '/simple/', '/pypi/', '/api/v1/crates/', '/packages.json', '/p/', '/api/v1/gems/', '/gems/'];
const isRegistryPath = registryPaths.some(p => path.startsWith(p)) ||
(path.startsWith('/@') && !path.startsWith('/@stack'));
if (this.smartRegistry) {
if (this.smartRegistry && isRegistryPath) {
try {
return await this.smartRegistry.handleRequest(request);
const response = await this.smartRegistry.handleRequest(request);
if (response) return response;
} catch (error) {
console.error('[StackGalleryRegistry] Request error:', error);
return new Response(
@@ -178,7 +182,56 @@ export class StackGalleryRegistry {
}
}
return new Response('Not Found', { status: 404 });
// Serve static UI files
return await this.serveStaticFile(path);
}
/**
* Serve static files from UI dist
*/
private async serveStaticFile(path: string): Promise<Response> {
const uiDistPath = './ui/dist/registry-ui/browser';
// Map path to file
let filePath = path === '/' ? '/index.html' : path;
// Content type mapping
const contentTypes: Record<string, string> = {
'.html': 'text/html',
'.js': 'application/javascript',
'.css': 'text/css',
'.json': 'application/json',
'.png': 'image/png',
'.jpg': 'image/jpeg',
'.svg': 'image/svg+xml',
'.ico': 'image/x-icon',
'.woff': 'font/woff',
'.woff2': 'font/woff2',
'.ttf': 'font/ttf',
};
try {
const fullPath = `${uiDistPath}${filePath}`;
const file = await Deno.readFile(fullPath);
const ext = filePath.substring(filePath.lastIndexOf('.'));
const contentType = contentTypes[ext] || 'application/octet-stream';
return new Response(file, {
status: 200,
headers: { 'Content-Type': contentType },
});
} catch {
// For SPA routing, serve index.html for unknown paths
try {
const indexFile = await Deno.readFile(`${uiDistPath}/index.html`);
return new Response(indexFile, {
status: 200,
headers: { 'Content-Type': 'text/html' },
});
} catch {
return new Response('Not Found', { status: 404 });
}
}
}
/**
@@ -274,3 +327,47 @@ export function createRegistryFromEnv(): StackGalleryRegistry {
return new StackGalleryRegistry(config);
}
/**
* Create registry from .nogit/env.json file (for local development)
* Falls back to environment variables if file doesn't exist
*/
export async function createRegistryFromEnvFile(): Promise<StackGalleryRegistry> {
const envPath = '.nogit/env.json';
try {
const envText = await Deno.readTextFile(envPath);
const env = JSON.parse(envText);
console.log('[StackGalleryRegistry] Loading config from .nogit/env.json');
// Build S3 endpoint from host/port/ssl settings
const s3Protocol = env.S3_USESSL ? 'https' : 'http';
const s3Endpoint = `${s3Protocol}://${env.S3_HOST || 'localhost'}:${env.S3_PORT || '9000'}`;
const config: IRegistryConfig = {
mongoUrl: env.MONGODB_URL || `mongodb://${env.MONGODB_USER}:${env.MONGODB_PASS}@${env.MONGODB_HOST || 'localhost'}:${env.MONGODB_PORT || '27017'}/${env.MONGODB_NAME}?authSource=admin`,
mongoDb: env.MONGODB_NAME || 'stackgallery',
s3Endpoint: s3Endpoint,
s3AccessKey: env.S3_ACCESSKEY || env.S3_ACCESS_KEY || 'minioadmin',
s3SecretKey: env.S3_SECRETKEY || env.S3_SECRET_KEY || 'minioadmin',
s3Bucket: env.S3_BUCKET || 'registry',
s3Region: env.S3_REGION,
host: env.HOST || '0.0.0.0',
port: parseInt(env.PORT || '3000', 10),
storagePath: env.STORAGE_PATH || 'packages',
enableUpstreamCache: env.ENABLE_UPSTREAM_CACHE !== false,
upstreamCacheExpiry: parseInt(env.UPSTREAM_CACHE_EXPIRY || '24', 10),
jwtSecret: env.JWT_SECRET,
};
return new StackGalleryRegistry(config);
} catch (error) {
if (error instanceof Deno.errors.NotFound) {
console.log('[StackGalleryRegistry] No .nogit/env.json found, using environment variables');
} else {
console.warn('[StackGalleryRegistry] Error reading .nogit/env.json, falling back to env vars:', error);
}
return createRegistryFromEnv();
}
}