import * as qenv from '@push.rocks/qenv'; import * as crypto from 'crypto'; import { SmartRegistry } from '../../ts/classes.smartregistry.js'; import type { IRegistryConfig } from '../../ts/core/interfaces.core.js'; const testQenv = new qenv.Qenv('./', './.nogit'); /** * Create a test SmartRegistry instance with OCI, NPM, Maven, and Composer enabled */ export async function createTestRegistry(): Promise { // Read S3 config from env.json const s3AccessKey = await testQenv.getEnvVarOnDemand('S3_ACCESSKEY'); const s3SecretKey = await testQenv.getEnvVarOnDemand('S3_SECRETKEY'); const s3Endpoint = await testQenv.getEnvVarOnDemand('S3_ENDPOINT'); const s3Port = await testQenv.getEnvVarOnDemand('S3_PORT'); const config: IRegistryConfig = { storage: { accessKey: s3AccessKey || 'minioadmin', accessSecret: s3SecretKey || 'minioadmin', endpoint: s3Endpoint || 'localhost', port: parseInt(s3Port || '9000', 10), useSsl: false, region: 'us-east-1', bucketName: 'test-registry', }, auth: { jwtSecret: 'test-secret-key', tokenStore: 'memory', npmTokens: { enabled: true, }, ociTokens: { enabled: true, realm: 'https://auth.example.com/token', service: 'test-registry', }, }, oci: { enabled: true, basePath: '/oci', }, npm: { enabled: true, basePath: '/npm', }, maven: { enabled: true, basePath: '/maven', }, composer: { enabled: true, basePath: '/composer', }, cargo: { enabled: true, basePath: '/cargo', }, }; const registry = new SmartRegistry(config); await registry.init(); return registry; } /** * Helper to create test authentication tokens */ export async function createTestTokens(registry: SmartRegistry) { const authManager = registry.getAuthManager(); // Authenticate and create tokens const userId = await authManager.authenticate({ username: 'testuser', password: 'testpass', }); if (!userId) { throw new Error('Failed to authenticate test user'); } // Create NPM token const npmToken = await authManager.createNpmToken(userId, false); // Create OCI token with full access const ociToken = await authManager.createOciToken( userId, ['oci:repository:*:*'], 3600 ); // Create Maven token with full access const mavenToken = await authManager.createMavenToken(userId, false); // Create Composer token with full access const composerToken = await authManager.createComposerToken(userId, false); // Create Cargo token with full access const cargoToken = await authManager.createCargoToken(userId, false); return { npmToken, ociToken, mavenToken, composerToken, cargoToken, userId }; } /** * Helper to calculate SHA-256 digest in OCI format */ export function calculateDigest(data: Buffer): string { const hash = crypto.createHash('sha256').update(data).digest('hex'); return `sha256:${hash}`; } /** * Helper to create a minimal valid OCI manifest */ export function createTestManifest(configDigest: string, layerDigest: string) { return { schemaVersion: 2, mediaType: 'application/vnd.oci.image.manifest.v1+json', config: { mediaType: 'application/vnd.oci.image.config.v1+json', size: 123, digest: configDigest, }, layers: [ { mediaType: 'application/vnd.oci.image.layer.v1.tar+gzip', size: 456, digest: layerDigest, }, ], }; } /** * Helper to create a minimal valid NPM packument */ export function createTestPackument(packageName: string, version: string, tarballData: Buffer) { const shasum = crypto.createHash('sha1').update(tarballData).digest('hex'); const integrity = `sha512-${crypto.createHash('sha512').update(tarballData).digest('base64')}`; return { name: packageName, versions: { [version]: { name: packageName, version: version, description: 'Test package', main: 'index.js', scripts: {}, dist: { shasum: shasum, integrity: integrity, tarball: `http://localhost:5000/npm/${packageName}/-/${packageName}-${version}.tgz`, }, }, }, 'dist-tags': { latest: version, }, _attachments: { [`${packageName}-${version}.tgz`]: { content_type: 'application/octet-stream', data: tarballData.toString('base64'), length: tarballData.length, }, }, }; } /** * Helper to create a minimal valid Maven POM file */ export function createTestPom( groupId: string, artifactId: string, version: string, packaging: string = 'jar' ): string { return ` 4.0.0 ${groupId} ${artifactId} ${version} ${packaging} ${artifactId} Test Maven artifact `; } /** * Helper to create a test JAR file (minimal ZIP with manifest) */ export function createTestJar(): Buffer { // Create a simple JAR structure (just a manifest) // In practice, this is a ZIP file with at least META-INF/MANIFEST.MF const manifestContent = `Manifest-Version: 1.0 Created-By: SmartRegistry Test `; // For testing, we'll just create a buffer with dummy content // Real JAR would be a proper ZIP archive return Buffer.from(manifestContent, 'utf-8'); } /** * Helper to calculate Maven checksums */ export function calculateMavenChecksums(data: Buffer) { return { md5: crypto.createHash('md5').update(data).digest('hex'), sha1: crypto.createHash('sha1').update(data).digest('hex'), sha256: crypto.createHash('sha256').update(data).digest('hex'), sha512: crypto.createHash('sha512').update(data).digest('hex'), }; } /** * Helper to create a Composer package ZIP */ export async function createComposerZip( vendorPackage: string, version: string, options?: { description?: string; license?: string[]; authors?: Array<{ name: string; email?: string }>; } ): Promise { const AdmZip = (await import('adm-zip')).default; const zip = new AdmZip(); const composerJson = { name: vendorPackage, version: version, type: 'library', description: options?.description || 'Test Composer package', license: options?.license || ['MIT'], authors: options?.authors || [{ name: 'Test Author', email: 'test@example.com' }], require: { php: '>=7.4', }, autoload: { 'psr-4': { 'Vendor\\TestPackage\\': 'src/', }, }, }; // Add composer.json zip.addFile('composer.json', Buffer.from(JSON.stringify(composerJson, null, 2), 'utf-8')); // Add a test PHP file const [vendor, pkg] = vendorPackage.split('/'); const namespace = `${vendor.charAt(0).toUpperCase() + vendor.slice(1)}\\${pkg.charAt(0).toUpperCase() + pkg.slice(1).replace(/-/g, '')}`; const testPhpContent = `