dependency.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. package bundle_entities
  2. import (
  3. "fmt"
  4. "regexp"
  5. "strings"
  6. "github.com/go-playground/validator/v10"
  7. "github.com/langgenius/dify-plugin-daemon/pkg/entities/manifest_entities"
  8. "github.com/langgenius/dify-plugin-daemon/pkg/validators"
  9. "gopkg.in/yaml.v3"
  10. )
  11. type DependencyType string
  12. const (
  13. DEPENDENCY_TYPE_GITHUB DependencyType = "github"
  14. DEPENDENCY_TYPE_MARKETPLACE DependencyType = "marketplace"
  15. DEPENDENCY_TYPE_PACKAGE DependencyType = "package"
  16. )
  17. type Dependency struct {
  18. Type DependencyType `json:"type" yaml:"type" validate:"required,oneof=github marketplace package"`
  19. Value any `json:"value" yaml:"value" validate:"required"`
  20. }
  21. func (d *Dependency) UnmarshalYAML(node *yaml.Node) error {
  22. // try convert Value to GithubDependency, MarketplaceDependency, PackageDependency
  23. type alias struct {
  24. Type DependencyType `json:"type" yaml:"type" validate:"required,oneof=github marketplace package"`
  25. Value yaml.Node `json:"value" yaml:"value" validate:"required"`
  26. }
  27. var a alias
  28. if err := node.Decode(&a); err != nil {
  29. return err
  30. }
  31. d.Type = a.Type
  32. // try convert Value to GithubDependency, MarketplaceDependency, PackageDependency
  33. switch d.Type {
  34. case DEPENDENCY_TYPE_GITHUB:
  35. var value GithubDependency
  36. if err := a.Value.Decode(&value); err != nil {
  37. return err
  38. }
  39. d.Value = value
  40. case DEPENDENCY_TYPE_MARKETPLACE:
  41. var value MarketplaceDependency
  42. if err := a.Value.Decode(&value); err != nil {
  43. return err
  44. }
  45. d.Value = value
  46. case DEPENDENCY_TYPE_PACKAGE:
  47. var value PackageDependency
  48. if err := a.Value.Decode(&value); err != nil {
  49. return err
  50. }
  51. d.Value = value
  52. }
  53. return nil
  54. }
  55. type GithubRepoPattern string
  56. func (p GithubRepoPattern) Split() []string {
  57. split := strings.Split(string(p), ":")
  58. // split again by "/"
  59. splits := []string{}
  60. for _, s := range split {
  61. splits = append(splits, strings.Split(s, "/")...)
  62. }
  63. return splits
  64. }
  65. func (p GithubRepoPattern) Repo() string {
  66. split := p.Split()
  67. if len(split) < 3 {
  68. return ""
  69. }
  70. organization, repo := split[0], split[1]
  71. return fmt.Sprintf("https://github.com/%s/%s", organization, repo)
  72. }
  73. func (p GithubRepoPattern) GithubRepo() string {
  74. split := p.Split()
  75. if len(split) < 3 {
  76. return ""
  77. }
  78. return fmt.Sprintf("%s/%s", split[0], split[1])
  79. }
  80. func (p GithubRepoPattern) Release() string {
  81. split := p.Split()
  82. if len(split) < 3 {
  83. return ""
  84. }
  85. return split[2]
  86. }
  87. func (p GithubRepoPattern) Asset() string {
  88. split := p.Split()
  89. if len(split) < 4 {
  90. return ""
  91. }
  92. return split[3]
  93. }
  94. func NewGithubRepoPattern(pattern string) (GithubRepoPattern, error) {
  95. if !GITHUB_DEPENDENCY_PATTERN_REGEX_COMPILED.MatchString(pattern) {
  96. return "", fmt.Errorf("invalid github repo pattern")
  97. }
  98. return GithubRepoPattern(pattern), nil
  99. }
  100. type MarketplacePattern string
  101. func NewMarketplacePattern(pattern string) (MarketplacePattern, error) {
  102. if !MARKETPLACE_PATTERN_REGEX_COMPILED.MatchString(pattern) {
  103. return "", fmt.Errorf("invalid marketplace pattern")
  104. }
  105. return MarketplacePattern(pattern), nil
  106. }
  107. func (p MarketplacePattern) Split() []string {
  108. split := strings.Split(string(p), ":")
  109. // split again by "/"
  110. splits := []string{}
  111. for _, s := range split {
  112. splits = append(splits, strings.Split(s, "/")...)
  113. }
  114. return splits
  115. }
  116. func (p MarketplacePattern) Organization() string {
  117. split := p.Split()
  118. if len(split) < 1 {
  119. return ""
  120. }
  121. return split[0]
  122. }
  123. func (p MarketplacePattern) Plugin() string {
  124. split := p.Split()
  125. if len(split) < 2 {
  126. return ""
  127. }
  128. return split[1]
  129. }
  130. func (p MarketplacePattern) Version() string {
  131. split := p.Split()
  132. if len(split) < 3 {
  133. return ""
  134. }
  135. return split[2]
  136. }
  137. var (
  138. GITHUB_VERSION_PATTERN = fmt.Sprintf(
  139. `([~^]?%s|%s(\.%s){2}|%s-%s)`,
  140. manifest_entities.VERSION_PATTERN,
  141. manifest_entities.VERSION_X_PATTERN,
  142. manifest_entities.VERSION_X_PATTERN,
  143. manifest_entities.VERSION_PATTERN,
  144. manifest_entities.VERSION_PATTERN,
  145. )
  146. GITHUB_DEPENDENCY_PATTERN = fmt.Sprintf(`^[a-z0-9_-]{1,64}/[a-z0-9_-]{1,128}:%s/[^/]+$`, GITHUB_VERSION_PATTERN)
  147. MARKETPLACE_VERSION_PATTERN = fmt.Sprintf(
  148. `([~^]?%s|%s(\.%s){2}|%s-%s)`,
  149. manifest_entities.VERSION_PATTERN,
  150. manifest_entities.VERSION_X_PATTERN,
  151. manifest_entities.VERSION_X_PATTERN,
  152. manifest_entities.VERSION_PATTERN,
  153. manifest_entities.VERSION_PATTERN,
  154. )
  155. MARKETPLACE_DEPENDENCY_PATTERN = fmt.Sprintf(`^[a-z0-9_-]{1,64}/[a-z0-9_-]{1,128}:%s$`, MARKETPLACE_VERSION_PATTERN)
  156. )
  157. var (
  158. GITHUB_DEPENDENCY_PATTERN_REGEX_COMPILED = regexp.MustCompile(GITHUB_DEPENDENCY_PATTERN)
  159. MARKETPLACE_PATTERN_REGEX_COMPILED = regexp.MustCompile(MARKETPLACE_DEPENDENCY_PATTERN)
  160. )
  161. func validateGithubDependencyPattern(fl validator.FieldLevel) bool {
  162. return GITHUB_DEPENDENCY_PATTERN_REGEX_COMPILED.MatchString(fl.Field().String())
  163. }
  164. func validateMarketplacePattern(fl validator.FieldLevel) bool {
  165. return MARKETPLACE_PATTERN_REGEX_COMPILED.MatchString(fl.Field().String())
  166. }
  167. func init() {
  168. validators.GlobalEntitiesValidator.RegisterValidation("github_dependency_pattern", validateGithubDependencyPattern)
  169. validators.GlobalEntitiesValidator.RegisterValidation("marketplace_pattern", validateMarketplacePattern)
  170. }
  171. type GithubDependency struct {
  172. // RepoPattern is the pattern of the repo, as for its content, at least one of the following patterns:
  173. // 1. owner/repo/1.0.0/aaa.difypkg
  174. // 2. owner/repo/1.0.0/*.difypkg
  175. // 3. owner/repo/1.x.x/aaa.difypkg
  176. // 4. owner/repo/^1.0.0/aaa.difypkg
  177. // 5. owner/repo/~1.0.0/aaa.difypkg
  178. // 6. owner/repo/1.0.0-2.0.0/aaa.difypkg
  179. // 7. owner/repo/1.0.0-beta/aaa.difypkg
  180. RepoPattern GithubRepoPattern `json:"repo_pattern" yaml:"repo_pattern" validate:"required,github_dependency_pattern"`
  181. }
  182. type MarketplaceDependency struct {
  183. // MarketplacePattern is the pattern of the marketplace, as for its content, at least one of the following patterns:
  184. // 1. org/plugin/1.0.0
  185. // 2. org/plugin/1.x.x
  186. // 3. org/plugin/^1.0.0
  187. // 4. org/plugin/~1.0.0
  188. // 5. org/plugin/1.0.0-2.0.0
  189. // 6. org/plugin/1.0.0-beta
  190. MarketplacePattern MarketplacePattern `json:"marketplace_pattern" yaml:"marketplace_pattern" validate:"required,marketplace_pattern"`
  191. }
  192. type PackageDependency struct {
  193. // refers to the path of difypkg file in assets
  194. Path string `json:"path" yaml:"path" validate:"required"`
  195. }