Skip to content

🛠️ 创建 / 编辑 / 列表模型

pkg/domain 中用于包管理(创建、编辑、更新)与包列表/流行包查询的结构体。这些类型同时充当 API 请求体与响应体,对应 Packagist 的 https://packagist.org/api/... 写接口与 https://packagist.org/packages/list.json 读接口。

类型总览

类型角色是否需要凭据
PackageCreateRequest / PackageCreateResponse创建包✅ 需要
PackageEditRequest / PackageEditResponse编辑包✅ 需要
PackageUpdateRequest / PackageUpdateResponse更新包✅ 需要
PackageListResponse包名列表❌ 公开
PackageListWithDataResponse / PackageData带附加数据的包列表❌ 公开
PopularPackagesResponse / PopularPackage流行包列表❌ 公开

写操作需要 API 凭据

创建/编辑/更新包属于写操作,必须通过 client.WithAPICredentials(username, apiToken) 提供凭据,否则会被 Packagist 拒绝。


✏️ 创建包

PackageCreateRequest

go
type PackageCreateRequest struct {
    Repository string `json:"repository"`
}
字段类型说明
Repositorystring要提交的包的仓库 URL(如 https://github.com/symfony/console

PackageCreateResponse

go
type PackageCreateResponse struct {
    Status string `json:"status"`
}
字段类型说明
Statusstring操作状态(如 success

📝 编辑包

PackageEditRequest

go
type PackageEditRequest struct {
    Repository string `json:"repository"`
}
字段类型说明
Repositorystring新的仓库 URL,用于替换该包原有的仓库地址

PackageEditResponse

go
type PackageEditResponse struct {
    Status string `json:"status"`
}
字段类型说明
Statusstring操作状态

创建 vs 编辑

  • 创建CreatePackage):向 Packagist 注册一个新包,只需传仓库 URL。
  • 编辑EditPackage):修改已有包的仓库地址,需同时指定包名(在方法参数中)和新仓库 URL。
  • 更新UpdatePackage):触发 Packagist 重新抓取某包的元数据,通常不改变仓库地址。

🔄 更新包

PackageUpdateRequest

go
type PackageUpdateRequest struct {
    Repository string `json:"repository"`
}
字段类型说明
Repositorystring要触发更新的包名或仓库标识

PackageUpdateResponse

go
type PackageUpdateResponse struct {
    Status string   `json:"status"`
    Jobs   []string `json:"jobs,omitempty"`
}
字段类型说明
Statusstring操作状态
Jobs[]string触发的后台作业 ID 列表(可用来轮询更新进度)

📋 包名列表

PackageListResponse

对应 https://packagist.org/packages/list.json,返回 Packagist 中所有包名。

go
type PackageListResponse struct {
    PackageNames []string `json:"packageNames"`
}
字段类型说明
PackageNames[]string包名列表

📋 带附加数据的包列表

PackageListWithDataResponse

对应 https://packagist.org/packages/list.json?fields[]=repository&fields[]=type,返回包名到附加数据的映射。

go
type PackageListWithDataResponse struct {
    Packages map[string]PackageData `json:"package"`
}
字段类型说明
Packagesmap[string]PackageData包信息映射,键为包名,值为附加数据

PackageData

go
type PackageData struct {
    Type       string      `json:"type,omitempty"`
    Repository string      `json:"repository,omitempty"`
    Abandoned  interface{} `json:"abandoned,omitempty"`
}
字段类型说明
Typestring包类型(如 library
Repositorystring仓库 URL
Abandonedinterface{}是否废弃:可为 boolfalse/true)或 string(推荐替代包名)

Abandoned 是联合类型

Abandoned 在 JSON 中既可能是布尔值也可能是字符串:

  • false / true:表示未废弃 / 已废弃(无替代包)
  • "vendor/replacement":已废弃,并推荐迁移到该替代包

因此 Go 端用 interface{} 接收。使用时需做类型断言:

go
switch v := data.Abandoned.(type) {
case bool:
    if v { fmt.Println("已废弃,无替代包") }
case string:
    fmt.Printf("已废弃,替代包: %s\n", v)
}

⭐ 流行包

PopularPackagesResponse

对应 https://packagist.org/explore/popular.json,返回流行包列表。

go
type PopularPackagesResponse struct {
    Packages []PopularPackage `json:"packages"`
    Total    int              `json:"total"`
    Next     string           `json:"next,omitempty"`
}
字段类型说明
Packages[]PopularPackage流行包信息列表
Totalint总流行包数
Nextstring下一页 URL,没有则为空

PopularPackage

go
type PopularPackage struct {
    Name        string `json:"name"`
    Description string `json:"description"`
    URL         string `json:"url"`
    Downloads   int    `json:"downloads"`
    Favers      int    `json:"favers"`
}
字段类型说明
Namestring包名
Descriptionstring包描述
URLstring包页面 URL
Downloadsint下载次数
Faversint收藏次数

与 SearchResult 的区别

PopularPackage 的字段几乎与 domain.SearchResult 一致,但语义不同:前者来自「流行包」榜单(按收藏/下载排序),后者来自关键词搜索。两者独立定义以便各自演进。


🚀 示例

创建包(需凭据)

go
package main

import (
    "context"
    "fmt"
    "log"
    "time"

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

func main() {
    c := client.NewComposerClient(30*time.Second,
        client.WithAPICredentials("your-username", "your-api-token"),
    )

    resp, err := c.CreatePackage(context.Background(), &domain.PackageCreateRequest{
        Repository: "https://github.com/your-org/your-package",
    })
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("创建结果: %s\n", resp.Status)
}

列出带附加数据的包

go
list, _ := c.ListPackagesWithData([]string{"repository", "type"})
for name, data := range list.Packages {
    fmt.Printf("%s  type=%s  repo=%s\n", name, data.Type, data.Repository)
}

获取流行包

go
popular, _ := c.ListPopularPackages(20)
for _, p := range popular.Packages {
    fmt.Printf("%-30s%-6d 下载:%d\n", p.Name, p.Favers, p.Downloads)
}

📚 相关文档

基于 MIT 许可证发布