150 lines
3.8 KiB
TypeScript
150 lines
3.8 KiB
TypeScript
import * as qenv from '@push.rocks/qenv';
|
|
import { SmartRegistry, IRegistryConfig } from '../ts/index.js';
|
|
|
|
const testQenv = new qenv.Qenv('./', './.nogit');
|
|
|
|
/**
|
|
* Create a test SmartRegistry instance with both OCI and NPM enabled
|
|
*/
|
|
export async function createTestRegistry(): Promise<SmartRegistry> {
|
|
// Read S3 config from env.json
|
|
const s3AccessKey = await testQenv.getEnvVarOnDemand('S3_ACCESS_KEY');
|
|
const s3SecretKey = await testQenv.getEnvVarOnDemand('S3_SECRET_KEY');
|
|
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',
|
|
},
|
|
};
|
|
|
|
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
|
|
);
|
|
|
|
return { npmToken, ociToken, userId };
|
|
}
|
|
|
|
/**
|
|
* Helper to calculate SHA-256 digest in OCI format
|
|
*/
|
|
export function calculateDigest(data: Buffer): string {
|
|
const crypto = require('crypto');
|
|
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 crypto = require('crypto');
|
|
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,
|
|
},
|
|
},
|
|
};
|
|
}
|