Files
Will Browne 758d9884bc Plugins: Plugins loader pipeline (#71438)
* discovery

* flesh out

* add docs

* remove unused func

* bootstrap stage

* fix docs

* update docs

* undo unnecessary changes

* add end tag

* update doc

* fix linter

* fix

* tidy

* update docs

* add class to filter func

* apply PR feedback

* fix test
2023-07-27 15:29:13 +02:00

76 lines
2.4 KiB
Go

package assetpath
import (
"fmt"
"net/url"
"path"
"path/filepath"
"strings"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins/config"
"github.com/grafana/grafana/pkg/plugins/pluginscdn"
)
// Service provides methods for constructing asset paths for plugins.
// It supports core plugins, external plugins stored on the local filesystem, and external plugins stored
// on the plugins CDN, and it will switch to the correct implementation depending on the plugin and the config.
type Service struct {
cdn *pluginscdn.Service
}
func ProvideService(cdn *pluginscdn.Service) *Service {
return &Service{cdn: cdn}
}
func DefaultService(cfg *config.Cfg) *Service {
return &Service{cdn: pluginscdn.ProvideService(cfg)}
}
// Base returns the base path for the specified plugin.
func (s *Service) Base(pluginJSON plugins.JSONData, class plugins.Class, pluginDir string) (string, error) {
if class == plugins.ClassCore {
return path.Join("public/app/plugins", string(pluginJSON.Type), filepath.Base(pluginDir)), nil
}
if s.cdn.PluginSupported(pluginJSON.ID) {
return s.cdn.SystemJSAssetPath(pluginJSON.ID, pluginJSON.Info.Version, "")
}
return path.Join("public/plugins", pluginJSON.ID), nil
}
// Module returns the module.js path for the specified plugin.
func (s *Service) Module(pluginJSON plugins.JSONData, class plugins.Class, pluginDir string) (string, error) {
if class == plugins.ClassCore {
return path.Join("app/plugins", string(pluginJSON.Type), filepath.Base(pluginDir), "module"), nil
}
if s.cdn.PluginSupported(pluginJSON.ID) {
return s.cdn.SystemJSAssetPath(pluginJSON.ID, pluginJSON.Info.Version, "module")
}
return path.Join("plugins", pluginJSON.ID, "module"), nil
}
// RelativeURL returns the relative URL for an arbitrary plugin asset.
// If pathStr is an empty string, defaultStr is returned.
func (s *Service) RelativeURL(p *plugins.Plugin, pathStr, defaultStr string) (string, error) {
if pathStr == "" {
return defaultStr, nil
}
if s.cdn.PluginSupported(p.ID) {
// CDN
return s.cdn.NewCDNURLConstructor(p.ID, p.Info.Version).StringPath(pathStr)
}
// Local
u, err := url.Parse(pathStr)
if err != nil {
return "", fmt.Errorf("url parse: %w", err)
}
if u.IsAbs() {
return pathStr, nil
}
// is set as default or has already been prefixed with base path
if pathStr == defaultStr || strings.HasPrefix(pathStr, p.BaseURL) {
return pathStr, nil
}
return path.Join(p.BaseURL, pathStr), nil
}