gitea

Development moved to Codeberg

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
  42. 42
  43. 43
  44. 44
  45. 45
  46. 46
  47. 47
  48. 48
  49. 49
  50. 50
  51. 51
  52. 52
  53. 53
  54. 54
  55. 55
  56. 56
  57. 57
  58. 58
  59. 59
  60. 60
  61. 61
  62. 62
  63. 63
  64. 64
  65. 65
  66. 66
  67. 67
  68. 68
  69. 69
  70. 70
  71. 71
  72. 72
  73. 73
  74. 74
  75. 75
  76. 76
  77. 77
  78. 78
  79. 79
  80. 80
  81. 81
  82. 82
  83. 83
  84. 84
  85. 85
  86. 86
  87. 87
  88. 88
  89. 89
  90. 90
  91. 91
  92. 92
  93. 93
  94. 94
  95. 95
  96. 96
  97. 97
  98. 98
  99. 99
  100. 100
  101. 101
  102. 102
  103. 103
  104. 104
  105. 105
  106. 106
  107. 107
  108. 108
  109. 109
  110. 110
  111. 111
  112. 112
  113. 113
  114. 114
  115. 115
  116. 116
  117. 117
  118. 118
// Copyright 2021 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

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.Properties {
			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:  time.Unix(int64(pd.Version.CreatedUnix), 0),
			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,
		},
	}
}