Skip to content

📦 Package Info Models

Core structures in pkg/domain describing Composer package details. They correspond to Packagist's https://repo.packagist.org/p2/<vendor>/<package>.json API response, deserialized by ComposerClient.GetPackage.

Type Overview

TypeRoleKey Field Count
ComposerPackageInfoPackage complete info (top-level wrapper)5
PackageInfoPackage business info body15
PackageDownloadsDownload stats sub-structure3
MaintainerMaintainer2
VersionSingle version metadata18+

🗂️ ComposerPackageInfo

Package complete info, containing primary key, lowercase package name, business info, md5 fingerprint, and three timestamps. This is the direct return type of GetPackage.

go
type ComposerPackageInfo struct {
    PackageName          string     `json:"package_name"          bson:"package_name"`
    PackageNameLowercase string     `json:"package_name_lowercase" bson:"package_name_lowercase"`
    Package              PackageInfo `json:"package"             bson:"package"`
    PackageInfoMd5       string     `json:"package_info_md5"     bson:"package_info_md5"`
    CreateTime           *time.Time `json:"create_time"          bson:"create_time"`
    UpdateTime           *time.Time `json:"update_time"          bson:"update_time"`
    ChangeTime           *time.Time `json:"change_time"          bson:"change_time"`
}
FieldTypeDescription
PackageNamestringPackage name, as unique primary key (e.g., symfony/console)
PackageNameLowercasestringLowercase package name, for case-insensitive queries
PackagePackageInfoPackage detailed business info, see next section
PackageInfoMd5stringPackage info md5 fingerprint, used to detect content changes
CreateTime*time.TimePackage record creation time (pointer type, can be nil)
UpdateTime*time.TimePackage record update time
ChangeTime*time.TimeTime when package info content actually changed

Difference between three timestamps

  • CreateTime: Record first入库 time
  • UpdateTime: Time when any field was refreshed
  • ChangeTime: Time when content actually changed (md5 differs), commonly used for incremental sync

📑 PackageInfo

Package business info body, nested in ComposerPackageInfo.Package.

go
type PackageInfo struct {
    Name             string              `json:"name"             bson:"name"`
    Description      string              `json:"description"      bson:"description"`
    Time             time.Time           `json:"time"             bson:"time"`
    Maintainers      []*Maintainer       `json:"maintainers"      bson:"maintainers"`
    Versions         map[string]*Version `json:"versions"         bson:"versions"`
    Type             string              `json:"type"             bson:"type"`
    Repository       string              `json:"repository"       bson:"repository"`
    GithubStars      int                 `json:"github_stars"     bson:"github_stars"`
    GithubWatchers   int                 `json:"github_watchers"  bson:"github_watchers"`
    GithubForks      int                 `json:"github_forks"     bson:"github_forks"`
    GithubOpenIssues int                 `json:"github_open_issues" bson:"github_open_issues"`
    Language         string              `json:"language"         bson:"language"`
    Dependents       int                 `json:"dependents"       bson:"dependents"`
    Suggesters       int                 `json:"suggesters"       bson:"suggesters"
    Downloads        PackageDownloads    `json:"downloads"        bson:"downloads"`
    Favers           int                 `json:"favers"           bson:"favers"`
}
FieldTypeDescription
NamestringPackage name
DescriptionstringPackage description
Timetime.TimePackage creation time
Maintainers[]*MaintainerMaintainer list
Versionsmap[string]*VersionAll versions, key is version number (e.g., v6.0.0)
TypestringPackage type (e.g., library, composer-plugin)
RepositorystringCorresponding source code repository URL
GithubStarsintGitHub star count
GithubWatchersintGitHub watcher count
GithubForksintGitHub fork count
GithubOpenIssuesintGitHub open issue count
LanguagestringRepository primary language
DependentsintHow many other packages depend on this
SuggestersintSuggester count
DownloadsPackageDownloadsDownload stats, see next section
FaversintFavorite count

📉 PackageDownloads

Download stats, nested in PackageInfo.Downloads and PackageStatsResponse.Downloads.

go
type PackageDownloads struct {
    Total   int `json:"total"   bson:"total"`
    Monthly int `json:"monthly" bson:"monthly"`
    Daily   int `json:"daily"   bson:"daily"`
}
FieldTypeDescription
TotalintHistorical total download count
MonthlyintCurrent month download count
DailyintToday's download count

👤 Maintainer

Package maintainer, element type of PackageInfo.Maintainers.

go
type Maintainer struct {
    Name      string `json:"name"       bson:"name"`
    AvatarURL string `json:"avatar_url" bson:"avatar_url"`
}
FieldTypeDescription
NamestringMaintainer name
AvatarURLstringMaintainer avatar URL

🏷️ Version

Complete metadata for a single version. Value type of PackageInfo.Versions is *Version.

go
type Version struct {
    Name              string        `json:"name"`
    Description       string        `json:"description"`
    Keywords          []string      `json:"keywords"`
    Homepage          string        `json:"homepage"`
    Version           string        `json:"version"`
    VersionNormalized string        `json:"version_normalized"`
    License           []string      `json:"license" bson:"license"`
    Authors           []struct {
        Name     string `json:"name"     bson:"name"`
        Email    string `json:"email"    bson:"email"`
        Homepage string `json:"homepage" bson:"homepage"`
    } `json:"authors" bson:"authors"`
    Source struct {
        URL       string `json:"url"       bson:"url"`
        Type      string `json:"type"      bson:"type"`
        Reference string `json:"reference" bson:"reference"`
    } `json:"source" bson:"source"`
    Dist struct {
        URL       string `json:"url"       bson:"url"`
        Type      string `json:"type"      bson:"type"`
        Shasum    string `json:"shasum"    bson:"shasum"`
        Reference string `json:"reference" bson:"reference"`
    } `json:"dist" bson:"dist"`
    Type    string `json:"type" bson:"type"`
    Support struct {
        Source string `json:"source" bson:"source"`
    } `json:"support" bson:"support"`
    Funding []struct {
        URL  string `json:"url"  bson:"url"`
        Type string `json:"type" bson:"type"`
    } `json:"funding" bson:"funding"`
    Time    time.Time        `json:"time"    bson:"time"`
    Require map[string]string `json:"require" bson:"require"`
    Autoload interface{}    `json:"autoload" bson:"autoload"`
    Extra    interface{}    `json:"extra"    bson:"extra"`
    Suggest  interface{}    `json:"suggest"  bson:"suggest"`
    Provide  interface{}    `json:"provide"  bson:"provide"`
}
FieldTypeDescription
NamestringVersion name
DescriptionstringVersion description
Keywords[]stringKeywords
HomepagestringVersion homepage
VersionstringVersion number (e.g., 6.0.0)
VersionNormalizedstringNormalized version number
License[]stringLicense used by this version
Authors[]structAuthor list (contains name/email/homepage)
SourcestructSource info (url/type/reference)
DiststructDistribution archive info (url/type/shasum/reference)
TypestringPackage type
SupportstructSupport info (contains source link)
Funding[]structFunding info (url/type)
Timetime.TimeVersion release time
Requiremap[string]stringOther packages and version constraints this version depends on
Autoloadinterface{}PSR-4 etc. autoloading config
Extrainterface{}Extra config
Suggestinterface{}Suggested packages to install
Provideinterface{}Virtual package capabilities this version provides

Authors/Source/Dist are anonymous structs

Authors, Source, Dist, Support, Funding are all inline anonymous structs, cannot be referenced by type externally. To reuse their fields, use chain access like version.Authors[i].Name.

🚀 Example: Iterate Package Versions and Dependencies

go
package main

import (
    "fmt"
    "log"
    "time"

    "github.com/scagogogo/composer-skills/pkg/client"
)

func main() {
    c := client.NewComposerClient(30 * time.Second)
    info, err := c.GetPackage("monolog/monolog")
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("Maintainers: %d people\n", len(info.Package.Maintainers))
    for ver, v := range info.Package.Versions {
        fmt.Printf("Version %s, license=%v, dependency count=%d\n", ver, v.License, len(v.Require))
        for dep, constraint := range v.Require {
            fmt.Printf("  - %s: %s\n", dep, constraint)
        }
    }
}

Released under the MIT License