summaryrefslogtreecommitdiffstats
path: root/routers/api/packages/composer/api.go
blob: a3bcf80417c772308ec0f7739a32bd2502dd0a6b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package composer

import (
	"fmt"
	"net/url"
	"time"

	packages_model "code.gitea.io/gitea/models/packages"
	composer_module "code.gitea.io/gitea/modules/packages/composer"
)

// ServiceIndexResponse contains registry endpoints
type ServiceIndexResponse struct {
	SearchTemplate   string `json:"search"`
	MetadataTemplate string `json:"metadata-url"`
	PackageList      string `json:"list"`
}

func createServiceIndexResponse(registryURL string) *ServiceIndexResponse {
	return &ServiceIndexResponse{
		SearchTemplate:   registryURL + "/search.json?q=%query%&type=%type%",
		MetadataTemplate: registryURL + "/p2/%package%.json",
		PackageList:      registryURL + "/list.json",
	}
}

// SearchResultResponse contains search results
type SearchResultResponse struct {
	Total    int64           `json:"total"`
	Results  []*SearchResult `json:"results"`
	NextLink string          `json:"next,omitempty"`
}

// SearchResult contains a search result
type SearchResult struct {
	Name        string `json:"name"`
	Description string `json:"description"`
	Downloads   int64  `json:"downloads"`
}

func createSearchResultResponse(total int64, pds []*packages_model.PackageDescriptor, nextLink string) *SearchResultResponse {
	results := make([]*SearchResult, 0, len(pds))

	for _, pd := range pds {
		results = append(results, &SearchResult{
			Name:        pd.Package.Name,
			Description: pd.Metadata.(*composer_module.Metadata).Description,
			Downloads:   pd.Version.DownloadCount,
		})
	}

	return &SearchResultResponse{
		Total:    total,
		Results:  results,
		NextLink: nextLink,
	}
}

// PackageMetadataResponse contains packages metadata
type PackageMetadataResponse struct {
	Minified string                               `json:"minified"`
	Packages map[string][]*PackageVersionMetadata `json:"packages"`
}

// PackageVersionMetadata contains package metadata
type PackageVersionMetadata struct {
	*composer_module.Metadata
	Name    string    `json:"name"`
	Version string    `json:"version"`
	Type    string    `json:"type"`
	Created time.Time `json:"time"`
	Dist    Dist      `json:"dist"`
}

// Dist contains package download information
type Dist struct {
	Type     string `json:"type"`
	URL      string `json:"url"`
	Checksum string `json:"shasum"`
}

func createPackageMetadataResponse(registryURL string, pds []*packages_model.PackageDescriptor) *PackageMetadataResponse {
	versions := make([]*PackageVersionMetadata, 0, len(pds))

	for _, pd := range pds {
		packageType := ""
		for _, pvp := range pd.VersionProperties {
			if pvp.Name == composer_module.TypeProperty {
				packageType = pvp.Value
				break
			}
		}

		versions = append(versions, &PackageVersionMetadata{
			Name:     pd.Package.Name,
			Version:  pd.Version.Version,
			Type:     packageType,
			Created:  pd.Version.CreatedUnix.AsLocalTime(),
			Metadata: pd.Metadata.(*composer_module.Metadata),
			Dist: Dist{
				Type:     "zip",
				URL:      fmt.Sprintf("%s/files/%s/%s/%s", registryURL, url.PathEscape(pd.Package.LowerName), url.PathEscape(pd.Version.LowerVersion), url.PathEscape(pd.Files[0].File.LowerName)),
				Checksum: pd.Files[0].Blob.HashSHA1,
			},
		})
	}

	return &PackageMetadataResponse{
		Minified: "composer/2.0",
		Packages: map[string][]*PackageVersionMetadata{
			pds[0].Package.Name: versions,
		},
	}
}