mirror of
https://github.com/navidrome/navidrome.git
synced 2026-05-03 06:51:16 +00:00
refactor: rename List method to Keys for clarity in configuration management
Signed-off-by: Deluan <deluan@navidrome.org>
This commit is contained in:
parent
15a1d4152a
commit
3dba572ce7
@ -683,7 +683,7 @@ Access plugin configuration values programmatically. Unlike `pdk.GetConfig()` wh
|
|||||||
|-----------------|------------|-----------------------------|
|
|-----------------|------------|-----------------------------|
|
||||||
| `config_get` | `key` | `value, exists` |
|
| `config_get` | `key` | `value, exists` |
|
||||||
| `config_getint` | `key` | `value, exists` |
|
| `config_getint` | `key` | `value, exists` |
|
||||||
| `config_list` | `prefix` | Array of matching key names |
|
| `config_keys` | `prefix` | Array of matching key names |
|
||||||
|
|
||||||
**Usage (with generated SDK):**
|
**Usage (with generated SDK):**
|
||||||
|
|
||||||
@ -700,13 +700,13 @@ if exists {
|
|||||||
count, exists := host.ConfigGetInt("max_retries")
|
count, exists := host.ConfigGetInt("max_retries")
|
||||||
|
|
||||||
// List all keys with a prefix (useful for user-specific config)
|
// List all keys with a prefix (useful for user-specific config)
|
||||||
keys := host.ConfigList("user:")
|
keys := host.ConfigKeys("user:")
|
||||||
for _, key := range keys {
|
for _, key := range keys {
|
||||||
// key might be "user:john", "user:jane", etc.
|
// key might be "user:john", "user:jane", etc.
|
||||||
}
|
}
|
||||||
|
|
||||||
// List all configuration keys
|
// List all configuration keys
|
||||||
allKeys := host.ConfigList("")
|
allKeys := host.ConfigKeys("")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@ -33,12 +33,12 @@ type ConfigService interface {
|
|||||||
//nd:hostfunc
|
//nd:hostfunc
|
||||||
GetInt(ctx context.Context, key string) (value int64, exists bool)
|
GetInt(ctx context.Context, key string) (value int64, exists bool)
|
||||||
|
|
||||||
// List returns configuration keys matching the given prefix.
|
// Keys returns configuration keys matching the given prefix.
|
||||||
//
|
//
|
||||||
// Parameters:
|
// Parameters:
|
||||||
// - prefix: Key prefix to filter by. If empty, returns all keys.
|
// - prefix: Key prefix to filter by. If empty, returns all keys.
|
||||||
//
|
//
|
||||||
// Returns a sorted slice of matching configuration keys.
|
// Returns a sorted slice of matching configuration keys.
|
||||||
//nd:hostfunc
|
//nd:hostfunc
|
||||||
List(ctx context.Context, prefix string) (keys []string)
|
Keys(ctx context.Context, prefix string) (keys []string)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,13 +31,13 @@ type ConfigGetIntResponse struct {
|
|||||||
Exists bool `json:"exists,omitempty"`
|
Exists bool `json:"exists,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConfigListRequest is the request type for Config.List.
|
// ConfigKeysRequest is the request type for Config.Keys.
|
||||||
type ConfigListRequest struct {
|
type ConfigKeysRequest struct {
|
||||||
Prefix string `json:"prefix"`
|
Prefix string `json:"prefix"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConfigListResponse is the response type for Config.List.
|
// ConfigKeysResponse is the response type for Config.Keys.
|
||||||
type ConfigListResponse struct {
|
type ConfigKeysResponse struct {
|
||||||
Keys []string `json:"keys,omitempty"`
|
Keys []string `json:"keys,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ func RegisterConfigHostFunctions(service ConfigService) []extism.HostFunction {
|
|||||||
return []extism.HostFunction{
|
return []extism.HostFunction{
|
||||||
newConfigGetHostFunction(service),
|
newConfigGetHostFunction(service),
|
||||||
newConfigGetIntHostFunction(service),
|
newConfigGetIntHostFunction(service),
|
||||||
newConfigListHostFunction(service),
|
newConfigKeysHostFunction(service),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,9 +113,9 @@ func newConfigGetIntHostFunction(service ConfigService) extism.HostFunction {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newConfigListHostFunction(service ConfigService) extism.HostFunction {
|
func newConfigKeysHostFunction(service ConfigService) extism.HostFunction {
|
||||||
return extism.NewHostFunctionWithStack(
|
return extism.NewHostFunctionWithStack(
|
||||||
"config_list",
|
"config_keys",
|
||||||
func(ctx context.Context, p *extism.CurrentPlugin, stack []uint64) {
|
func(ctx context.Context, p *extism.CurrentPlugin, stack []uint64) {
|
||||||
// Read JSON request from plugin memory
|
// Read JSON request from plugin memory
|
||||||
reqBytes, err := p.ReadBytes(stack[0])
|
reqBytes, err := p.ReadBytes(stack[0])
|
||||||
@ -123,17 +123,17 @@ func newConfigListHostFunction(service ConfigService) extism.HostFunction {
|
|||||||
configWriteError(p, stack, err)
|
configWriteError(p, stack, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var req ConfigListRequest
|
var req ConfigKeysRequest
|
||||||
if err := json.Unmarshal(reqBytes, &req); err != nil {
|
if err := json.Unmarshal(reqBytes, &req); err != nil {
|
||||||
configWriteError(p, stack, err)
|
configWriteError(p, stack, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call the service method
|
// Call the service method
|
||||||
keys := service.List(ctx, req.Prefix)
|
keys := service.Keys(ctx, req.Prefix)
|
||||||
|
|
||||||
// Write JSON response to plugin memory
|
// Write JSON response to plugin memory
|
||||||
resp := ConfigListResponse{
|
resp := ConfigKeysResponse{
|
||||||
Keys: keys,
|
Keys: keys,
|
||||||
}
|
}
|
||||||
configWriteResponse(p, stack, resp)
|
configWriteResponse(p, stack, resp)
|
||||||
|
|||||||
@ -53,8 +53,8 @@ func (s *configServiceImpl) GetInt(ctx context.Context, key string) (int64, bool
|
|||||||
return intValue, true
|
return intValue, true
|
||||||
}
|
}
|
||||||
|
|
||||||
// List returns configuration keys matching the given prefix.
|
// Keys returns configuration keys matching the given prefix.
|
||||||
func (s *configServiceImpl) List(ctx context.Context, prefix string) []string {
|
func (s *configServiceImpl) Keys(ctx context.Context, prefix string) []string {
|
||||||
keys := make([]string, 0, len(s.config))
|
keys := make([]string, 0, len(s.config))
|
||||||
for k := range s.config {
|
for k := range s.config {
|
||||||
if prefix == "" || strings.HasPrefix(k, prefix) {
|
if prefix == "" || strings.HasPrefix(k, prefix) {
|
||||||
@ -62,7 +62,7 @@ func (s *configServiceImpl) List(ctx context.Context, prefix string) []string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
sort.Strings(keys)
|
sort.Strings(keys)
|
||||||
log.Trace(ctx, "Config.List", "plugin", s.pluginName, "prefix", prefix, "keyCount", len(keys))
|
log.Trace(ctx, "Config.Keys", "plugin", s.pluginName, "prefix", prefix, "keyCount", len(keys))
|
||||||
return keys
|
return keys
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -107,7 +107,7 @@ var _ = Describe("ConfigService", func() {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
Describe("List", func() {
|
Describe("Keys", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
service = newConfigService("test_plugin", map[string]string{
|
service = newConfigService("test_plugin", map[string]string{
|
||||||
"zebra": "z",
|
"zebra": "z",
|
||||||
@ -120,23 +120,23 @@ var _ = Describe("ConfigService", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
It("returns all keys in sorted order when prefix is empty", func() {
|
It("returns all keys in sorted order when prefix is empty", func() {
|
||||||
keys := service.List(ctx, "")
|
keys := service.Keys(ctx, "")
|
||||||
Expect(keys).To(Equal([]string{"apple", "banana", "user_alice", "user_bob", "user_charlie", "zebra"}))
|
Expect(keys).To(Equal([]string{"apple", "banana", "user_alice", "user_bob", "user_charlie", "zebra"}))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("returns only keys matching prefix", func() {
|
It("returns only keys matching prefix", func() {
|
||||||
keys := service.List(ctx, "user_")
|
keys := service.Keys(ctx, "user_")
|
||||||
Expect(keys).To(Equal([]string{"user_alice", "user_bob", "user_charlie"}))
|
Expect(keys).To(Equal([]string{"user_alice", "user_bob", "user_charlie"}))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("returns empty slice when no keys match prefix", func() {
|
It("returns empty slice when no keys match prefix", func() {
|
||||||
keys := service.List(ctx, "nonexistent_")
|
keys := service.Keys(ctx, "nonexistent_")
|
||||||
Expect(keys).To(BeEmpty())
|
Expect(keys).To(BeEmpty())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("returns empty slice for empty config", func() {
|
It("returns empty slice for empty config", func() {
|
||||||
service = newConfigService("test_plugin", nil)
|
service = newConfigService("test_plugin", nil)
|
||||||
keys := service.List(ctx, "")
|
keys := service.Keys(ctx, "")
|
||||||
Expect(keys).To(BeEmpty())
|
Expect(keys).To(BeEmpty())
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -23,10 +23,10 @@ func config_get(uint64) uint64
|
|||||||
//go:wasmimport extism:host/user config_getint
|
//go:wasmimport extism:host/user config_getint
|
||||||
func config_getint(uint64) uint64
|
func config_getint(uint64) uint64
|
||||||
|
|
||||||
// config_list is the host function provided by Navidrome.
|
// config_keys is the host function provided by Navidrome.
|
||||||
//
|
//
|
||||||
//go:wasmimport extism:host/user config_list
|
//go:wasmimport extism:host/user config_keys
|
||||||
func config_list(uint64) uint64
|
func config_keys(uint64) uint64
|
||||||
|
|
||||||
type configGetRequest struct {
|
type configGetRequest struct {
|
||||||
Key string `json:"key"`
|
Key string `json:"key"`
|
||||||
@ -46,11 +46,11 @@ type configGetIntResponse struct {
|
|||||||
Exists bool `json:"exists,omitempty"`
|
Exists bool `json:"exists,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type configListRequest struct {
|
type configKeysRequest struct {
|
||||||
Prefix string `json:"prefix"`
|
Prefix string `json:"prefix"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type configListResponse struct {
|
type configKeysResponse struct {
|
||||||
Keys []string `json:"keys,omitempty"`
|
Keys []string `json:"keys,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,16 +125,16 @@ func ConfigGetInt(key string) (int64, bool) {
|
|||||||
return response.Value, response.Exists
|
return response.Value, response.Exists
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConfigList calls the config_list host function.
|
// ConfigKeys calls the config_keys host function.
|
||||||
// List returns configuration keys matching the given prefix.
|
// List returns configuration keys matching the given prefix.
|
||||||
//
|
//
|
||||||
// Parameters:
|
// Parameters:
|
||||||
// - prefix: Key prefix to filter by. If empty, returns all keys.
|
// - prefix: Key prefix to filter by. If empty, returns all keys.
|
||||||
//
|
//
|
||||||
// Returns a sorted slice of matching configuration keys.
|
// Returns a sorted slice of matching configuration keys.
|
||||||
func ConfigList(prefix string) []string {
|
func ConfigKeys(prefix string) []string {
|
||||||
// Marshal request to JSON
|
// Marshal request to JSON
|
||||||
req := configListRequest{
|
req := configKeysRequest{
|
||||||
Prefix: prefix,
|
Prefix: prefix,
|
||||||
}
|
}
|
||||||
reqBytes, err := json.Marshal(req)
|
reqBytes, err := json.Marshal(req)
|
||||||
@ -145,14 +145,14 @@ func ConfigList(prefix string) []string {
|
|||||||
defer reqMem.Free()
|
defer reqMem.Free()
|
||||||
|
|
||||||
// Call the host function
|
// Call the host function
|
||||||
responsePtr := config_list(reqMem.Offset())
|
responsePtr := config_keys(reqMem.Offset())
|
||||||
|
|
||||||
// Read the response from memory
|
// Read the response from memory
|
||||||
responseMem := pdk.FindMemory(responsePtr)
|
responseMem := pdk.FindMemory(responsePtr)
|
||||||
responseBytes := responseMem.ReadBytes()
|
responseBytes := responseMem.ReadBytes()
|
||||||
|
|
||||||
// Parse the response
|
// Parse the response
|
||||||
var response configListResponse
|
var response configKeysResponse
|
||||||
if err := json.Unmarshal(responseBytes, &response); err != nil {
|
if err := json.Unmarshal(responseBytes, &response); err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -54,19 +54,19 @@ func ConfigGetInt(key string) (int64, bool) {
|
|||||||
return ConfigMock.GetInt(key)
|
return ConfigMock.GetInt(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
// List is the mock method for ConfigList.
|
// Keys is the mock method for ConfigKeys.
|
||||||
func (m *mockConfigService) List(prefix string) []string {
|
func (m *mockConfigService) Keys(prefix string) []string {
|
||||||
args := m.Called(prefix)
|
args := m.Called(prefix)
|
||||||
return args.Get(0).([]string)
|
return args.Get(0).([]string)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConfigList delegates to the mock instance.
|
// ConfigKeys delegates to the mock instance.
|
||||||
// List returns configuration keys matching the given prefix.
|
// List returns configuration keys matching the given prefix.
|
||||||
//
|
//
|
||||||
// Parameters:
|
// Parameters:
|
||||||
// - prefix: Key prefix to filter by. If empty, returns all keys.
|
// - prefix: Key prefix to filter by. If empty, returns all keys.
|
||||||
//
|
//
|
||||||
// Returns a sorted slice of matching configuration keys.
|
// Returns a sorted slice of matching configuration keys.
|
||||||
func ConfigList(prefix string) []string {
|
func ConfigKeys(prefix string) []string {
|
||||||
return ConfigMock.List(prefix)
|
return ConfigMock.Keys(prefix)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,8 +31,8 @@ def _config_getint(offset: int) -> int:
|
|||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
@extism.import_fn("extism:host/user", "config_list")
|
@extism.import_fn("extism:host/user", "config_keys")
|
||||||
def _config_list(offset: int) -> int:
|
def _config_keys(offset: int) -> int:
|
||||||
"""Raw host function - do not call directly."""
|
"""Raw host function - do not call directly."""
|
||||||
...
|
...
|
||||||
|
|
||||||
@ -116,7 +116,7 @@ value cannot be parsed as an integer, exists will be false.
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def config_list(prefix: str) -> Any:
|
def config_keys(prefix: str) -> Any:
|
||||||
"""List returns configuration keys matching the given prefix.
|
"""List returns configuration keys matching the given prefix.
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
@ -138,7 +138,7 @@ Returns a sorted slice of matching configuration keys.
|
|||||||
}
|
}
|
||||||
request_bytes = json.dumps(request).encode("utf-8")
|
request_bytes = json.dumps(request).encode("utf-8")
|
||||||
request_mem = extism.memory.alloc(request_bytes)
|
request_mem = extism.memory.alloc(request_bytes)
|
||||||
response_offset = _config_list(request_mem.offset)
|
response_offset = _config_keys(request_mem.offset)
|
||||||
response_mem = extism.memory.find(response_offset)
|
response_mem = extism.memory.find(response_offset)
|
||||||
response = json.loads(extism.memory.string(response_mem))
|
response = json.loads(extism.memory.string(response_mem))
|
||||||
|
|
||||||
|
|||||||
@ -38,13 +38,13 @@ struct ConfigGetIntResponse {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
struct ConfigListRequest {
|
struct ConfigKeysRequest {
|
||||||
prefix: String,
|
prefix: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
struct ConfigListResponse {
|
struct ConfigKeysResponse {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
keys: Vec<String>,
|
keys: Vec<String>,
|
||||||
}
|
}
|
||||||
@ -53,7 +53,7 @@ struct ConfigListResponse {
|
|||||||
extern "ExtismHost" {
|
extern "ExtismHost" {
|
||||||
fn config_get(input: Json<ConfigGetRequest>) -> Json<ConfigGetResponse>;
|
fn config_get(input: Json<ConfigGetRequest>) -> Json<ConfigGetResponse>;
|
||||||
fn config_getint(input: Json<ConfigGetIntRequest>) -> Json<ConfigGetIntResponse>;
|
fn config_getint(input: Json<ConfigGetIntRequest>) -> Json<ConfigGetIntResponse>;
|
||||||
fn config_list(input: Json<ConfigListRequest>) -> Json<ConfigListResponse>;
|
fn config_keys(input: Json<ConfigKeysRequest>) -> Json<ConfigKeysResponse>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get retrieves a configuration value as a string.
|
/// Get retrieves a configuration value as a string.
|
||||||
@ -122,9 +122,9 @@ pub fn get_int(key: &str) -> Result<(i64, bool), Error> {
|
|||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
/// Returns an error if the host function call fails.
|
/// Returns an error if the host function call fails.
|
||||||
pub fn list(prefix: &str) -> Result<Vec<String>, Error> {
|
pub fn keys(prefix: &str) -> Result<Vec<String>, Error> {
|
||||||
let response = unsafe {
|
let response = unsafe {
|
||||||
config_list(Json(ConfigListRequest {
|
config_keys(Json(ConfigKeysRequest {
|
||||||
prefix: prefix.to_owned(),
|
prefix: prefix.to_owned(),
|
||||||
}))?
|
}))?
|
||||||
};
|
};
|
||||||
|
|||||||
2
plugins/testdata/test-config/main.go
vendored
2
plugins/testdata/test-config/main.go
vendored
@ -46,7 +46,7 @@ func ndTestConfig() int32 {
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
case "list":
|
case "list":
|
||||||
keys := host.ConfigList(input.Prefix)
|
keys := host.ConfigKeys(input.Prefix)
|
||||||
pdk.OutputJSON(TestConfigOutput{Keys: keys})
|
pdk.OutputJSON(TestConfigOutput{Keys: keys})
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user