UNPKG

recoder-code

Version:

🚀 AI-powered development platform - Chat with 32+ models, build projects, automate workflows. Free models included!

314 lines (259 loc) • 7.38 kB
/** * Package Entity * Represents a plugin package in the NPM-compatible registry */ import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn, ManyToOne, OneToMany, Index } from 'typeorm'; import { User } from './User'; import { PackageVersion } from './PackageVersion'; import { Download } from './Download'; export enum PackageVisibility { PUBLIC = 'public', PRIVATE = 'private', ORGANIZATION = 'organization' } export enum PackageStatus { ACTIVE = 'active', DEPRECATED = 'deprecated', UNPUBLISHED = 'unpublished', SUSPENDED = 'suspended' } @Entity('packages') @Index(['status']) @Index(['visibility']) export class Package { @PrimaryGeneratedColumn('uuid') id!: string; @Column({ type: 'varchar', length: 255, unique: true }) name!: string; @Column({ type: 'text', nullable: true }) description?: string; @Column({ type: 'varchar', length: 255, nullable: true }) homepage?: string; @Column({ type: 'text', nullable: true }) readme?: string; @Column({ type: 'json', nullable: true }) keywords?: string[]; @Column({ type: 'varchar', length: 100, nullable: true }) license?: string; @Column({ type: 'json', nullable: true }) repository: { type: string; url: string; }; @Column({ type: 'json', nullable: true }) bugs: { url?: string; email?: string; }; @Column({ type: 'json', nullable: true }) author: { name: string; email?: string; url?: string; }; @Column({ type: 'json', nullable: true }) contributors: Array<{ name: string; email?: string; url?: string; }>; @Column({ type: 'json', nullable: true }) maintainers: Array<{ name: string; email?: string; }>; @Column({ type: 'enum', enum: PackageVisibility, default: PackageVisibility.PUBLIC }) visibility!: PackageVisibility; @Column({ type: 'enum', enum: PackageStatus, default: PackageStatus.ACTIVE }) status!: PackageStatus; @Column({ type: 'varchar', length: 255, nullable: true }) latest_version?: string; @Column({ type: 'int', default: 0 }) download_count!: number; @Column({ type: 'int', default: 0 }) version_count!: number; @Column({ type: 'float', default: 0 }) rating!: number; @Column({ type: 'int', default: 0 }) rating_count!: number; @Column({ type: 'json', nullable: true }) npm_metadata: { dist_tags?: Record<string, string>; time?: Record<string, string>; users?: Record<string, boolean>; }; @Column({ type: 'json', nullable: true }) security_scan: { last_scan: string; vulnerabilities: number; status: 'clean' | 'warning' | 'critical'; details?: any[]; }; @Column({ type: 'json', nullable: true }) quality_metrics: { code_quality: number; documentation: number; testing: number; popularity: number; maintenance: number; }; @Column({ type: 'json', nullable: true }) tags: string[]; @Column({ type: 'json', nullable: true }) categories: string[]; @Column({ type: 'boolean', default: false }) featured!: boolean; @Column({ type: 'boolean', default: false }) verified!: boolean; @Column({ type: 'varchar', length: 255, nullable: true }) organization?: string; @Column({ type: 'json', nullable: true }) stats: { weekly_downloads: number; monthly_downloads: number; yearly_downloads: number; dependents: number; dependencies: number; }; @CreateDateColumn() created_at!: Date; @UpdateDateColumn() updated_at!: Date; @Column({ type: 'timestamp', nullable: true }) last_published?: Date; @Column({ type: 'timestamp', nullable: true }) deprecated_at?: Date; @Column({ type: 'text', nullable: true }) deprecation_message?: string; // Relationships @ManyToOne(() => User, user => user.packages, { eager: false }) @Index() owner!: User; @Column({ type: 'uuid' }) owner_id!: string; @OneToMany(() => PackageVersion, version => version.package, { cascade: true }) versions!: PackageVersion[]; @OneToMany(() => Download, download => download.package) downloads!: Download[]; // Virtual properties get full_name(): string { return this.organization ? `@${this.organization}/${this.name}` : this.name; } get is_scoped(): boolean { return this.name.startsWith('@'); } get scope(): string | null { if (this.is_scoped) { const parts = this.name.split('/'); return parts[0].substring(1); // Remove @ symbol } return null; } get package_name(): string { if (this.is_scoped) { const parts = this.name.split('/'); return parts[1]; } return this.name; } // Methods updateStats(downloads: { weekly: number; monthly: number; yearly: number }) { this.stats = { ...this.stats, weekly_downloads: downloads.weekly, monthly_downloads: downloads.monthly, yearly_downloads: downloads.yearly, dependents: this.stats?.dependents || 0, dependencies: this.stats?.dependencies || 0 }; } addDownload() { this.download_count += 1; } updateQuality(metrics: Partial<Package['quality_metrics']>) { this.quality_metrics = { ...this.quality_metrics, ...metrics }; } deprecate(message?: string) { this.status = PackageStatus.DEPRECATED; this.deprecated_at = new Date(); this.deprecation_message = message; } undeprecate() { this.status = PackageStatus.ACTIVE; this.deprecated_at = undefined; this.deprecation_message = undefined; } suspend() { this.status = PackageStatus.SUSPENDED; } activate() { this.status = PackageStatus.ACTIVE; } unpublish() { this.status = PackageStatus.UNPUBLISHED; } updateRating(newRating: number) { const totalRating = this.rating * this.rating_count + newRating; this.rating_count += 1; this.rating = totalRating / this.rating_count; } toNpmFormat(): any { return { _id: this.name, name: this.name, description: this.description, 'dist-tags': this.npm_metadata?.dist_tags || { latest: this.latest_version }, maintainers: this.maintainers || [], time: this.npm_metadata?.time || {}, author: this.author, repository: this.repository, keywords: this.keywords || [], license: this.license, homepage: this.homepage, bugs: this.bugs, readme: this.readme, readmeFilename: 'README.md', users: this.npm_metadata?.users || {}, _attachments: {} }; } toApiFormat(): any { return { id: this.id, name: this.name, full_name: this.full_name, description: this.description, version: this.latest_version, author: this.author, homepage: this.homepage, repository: this.repository, keywords: this.keywords || [], license: this.license, visibility: this.visibility, status: this.status, downloads: this.download_count, rating: this.rating, rating_count: this.rating_count, featured: this.featured, verified: this.verified, tags: this.tags || [], categories: this.categories || [], stats: this.stats, quality_metrics: this.quality_metrics, created_at: this.created_at, updated_at: this.updated_at, last_published: this.last_published }; } }