feat(plugins): generate Go client stubs for non-WASM platforms

Signed-off-by: Deluan <deluan@navidrome.org>
This commit is contained in:
Deluan 2025-12-29 16:49:17 -05:00
parent 3692a274b4
commit cd3ee136f4
16 changed files with 952 additions and 21 deletions

View File

@ -6,6 +6,7 @@ import (
"os"
"os/exec"
"path/filepath"
"strings"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
@ -239,13 +240,14 @@ type ServiceB interface {
goDir := filepath.Join(outputDir, "go")
goClientEntries, err := os.ReadDir(goDir)
Expect(err).ToNot(HaveOccurred())
Expect(goClientEntries).To(HaveLen(3), "Expected Go client file, doc.go, and go.mod")
Expect(goClientEntries).To(HaveLen(4), "Expected Go client file, stub file, doc.go, and go.mod")
// Find the client file (not doc.go or go.mod)
// Find the client file (not doc.go, go.mod, or stub)
var goClientName string
for _, entry := range goClientEntries {
if entry.Name() != "doc.go" && entry.Name() != "go.mod" {
goClientName = entry.Name()
name := entry.Name()
if name != "doc.go" && name != "go.mod" && !strings.HasSuffix(name, "_stub.go") {
goClientName = name
break
}
}
@ -368,13 +370,14 @@ type ServiceB interface {
goDir := filepath.Join(clientDir, "go")
entries, err := os.ReadDir(goDir)
Expect(err).ToNot(HaveOccurred())
Expect(entries).To(HaveLen(3), "Expected Go client file, doc.go, and go.mod")
Expect(entries).To(HaveLen(4), "Expected Go client file, stub file, doc.go, and go.mod")
// Find the client file (not doc.go or go.mod)
// Find the client file (not doc.go, go.mod, or stub)
var clientFileName string
for _, entry := range entries {
if entry.Name() != "doc.go" && entry.Name() != "go.mod" {
clientFileName = entry.Name()
name := entry.Name()
if name != "doc.go" && name != "go.mod" && !strings.HasSuffix(name, "_stub.go") {
clientFileName = name
break
}
}

View File

@ -94,6 +94,32 @@ func GenerateClientGo(svc Service) ([]byte, error) {
return buf.Bytes(), nil
}
// GenerateClientGoStub generates stub code for non-WASM platforms.
// These stubs provide type definitions and function signatures for IDE support,
// but panic at runtime since host functions are only available in WASM plugins.
func GenerateClientGoStub(svc Service) ([]byte, error) {
tmplContent, err := templatesFS.ReadFile("templates/client_go_stub.go.tmpl")
if err != nil {
return nil, fmt.Errorf("reading client stub template: %w", err)
}
tmpl, err := template.New("client_stub").Funcs(clientFuncMap(svc)).Parse(string(tmplContent))
if err != nil {
return nil, fmt.Errorf("parsing template: %w", err)
}
data := templateData{
Service: svc,
}
var buf bytes.Buffer
if err := tmpl.Execute(&buf, data); err != nil {
return nil, fmt.Errorf("executing template: %w", err)
}
return buf.Bytes(), nil
}
type templateData struct {
Package string
Service Service

View File

@ -557,9 +557,6 @@ var _ = Describe("Generator", func() {
// Check for package declaration
Expect(codeStr).To(ContainSubstring("package ndhost"))
// Check for build tag
Expect(codeStr).To(ContainSubstring("//go:build wasip1"))
// Check for package documentation
Expect(codeStr).To(ContainSubstring("Package ndhost provides Navidrome host function wrappers"))
@ -587,6 +584,54 @@ var _ = Describe("Generator", func() {
})
})
Describe("GenerateClientGoStub", func() {
It("should generate valid stub code with panic functions", func() {
svc := Service{
Name: "Cache",
Permission: "cache",
Interface: "CacheService",
Doc: "CacheService provides caching capabilities.",
Methods: []Method{
{
Name: "Get",
Doc: "Get retrieves a value from the cache.",
Params: []Param{
{Name: "key", Type: "string"},
},
Returns: []Param{
{Name: "value", Type: "string"},
{Name: "exists", Type: "bool"},
},
},
},
}
code, err := GenerateClientGoStub(svc)
Expect(err).NotTo(HaveOccurred())
// Verify it's valid Go code
_, err = format.Source(code)
Expect(err).NotTo(HaveOccurred())
codeStr := string(code)
// Check for build tag (non-WASM)
Expect(codeStr).To(ContainSubstring("//go:build !wasip1"))
// Check for package declaration
Expect(codeStr).To(ContainSubstring("package ndhost"))
// Check for stub comment
Expect(codeStr).To(ContainSubstring("stub implementations for non-WASM builds"))
// Check for panic in function body
Expect(codeStr).To(ContainSubstring(`panic("ndhost: CacheGet is only available in WASM plugins")`))
// Check that types are defined (needed for IDE support)
Expect(codeStr).To(ContainSubstring("type CacheGetResponse struct"))
})
})
Describe("Integration", func() {
It("should generate compilable code from parsed source", func() {
// This is an integration test that verifies the full pipeline

View File

@ -0,0 +1,56 @@
// Code generated by hostgen. DO NOT EDIT.
//
// This file contains stub implementations for non-WASM builds.
// These stubs allow IDE support and compilation on non-WASM platforms.
// They panic at runtime since host functions are only available in WASM plugins.
//
//go:build !wasip1
package ndhost
{{- /* Generate struct definitions (same as main file, needed for type references) */ -}}
{{- range .Service.Structs}}
// {{.Name}} represents the {{.Name}} data structure.
{{- if .Doc}}
{{formatDoc .Doc}}
{{- end}}
type {{.Name}} struct {
{{- range .Fields}}
{{.Name}} {{.Type}} `json:"{{.JSONTag}}"`
{{- end}}
}
{{- end}}
{{- /* Generate request/response types (same as main file) */ -}}
{{range .Service.Methods}}
{{- if .HasParams}}
// {{requestType .}} is the request type for {{$.Service.Name}}.{{.Name}}.
type {{requestType .}} struct {
{{- range .Params}}
{{title .Name}} {{.Type}} `json:"{{.JSONName}}"`
{{- end}}
}
{{- end}}
// {{responseType .}} is the response type for {{$.Service.Name}}.{{.Name}}.
type {{responseType .}} struct {
{{- range .Returns}}
{{title .Name}} {{.Type}} `json:"{{.JSONName}},omitempty"`
{{- end}}
Error string `json:"error,omitempty"`
}
{{- end}}
{{- /* Generate stub wrapper functions that panic */ -}}
{{range .Service.Methods}}
// {{$.Service.Name}}{{.Name}} is a stub that panics on non-WASM platforms.
{{- if .Doc}}
{{formatDoc .Doc}}
{{- end}}
func {{$.Service.Name}}{{.Name}}({{range $i, $p := .Params}}{{if $i}}, {{end}}{{$p.Name}} {{$p.Type}}{{end}}) (*{{responseType .}}, error) {
panic("ndhost: {{$.Service.Name}}{{.Name}} is only available in WASM plugins")
}
{{- end}}

View File

@ -1,7 +1,5 @@
// Code generated by hostgen. DO NOT EDIT.
//go:build wasip1
/*
Package ndhost provides Navidrome host function wrappers for Go/TinyGo plugins.

View File

@ -242,6 +242,43 @@ func generateGoClientCode(svc internal.Service, outputDir string, dryRun, verbos
if dryRun {
fmt.Printf("=== %s ===\n%s\n", clientFile, formatted)
} else {
// Create go/ subdirectory if needed
if err := os.MkdirAll(clientDir, 0755); err != nil {
return fmt.Errorf("creating client directory: %w", err)
}
if err := os.WriteFile(clientFile, formatted, 0600); err != nil {
return fmt.Errorf("writing file: %w", err)
}
if verbose {
fmt.Printf("Generated Go client code: %s\n", clientFile)
}
}
// Also generate stub file for non-WASM platforms
return generateGoClientStubCode(svc, outputDir, dryRun, verbose)
}
// generateGoClientStubCode generates stub code for non-WASM platforms.
func generateGoClientStubCode(svc internal.Service, outputDir string, dryRun, verbose bool) error {
code, err := internal.GenerateClientGoStub(svc)
if err != nil {
return fmt.Errorf("generating stub code: %w", err)
}
formatted, err := format.Source(code)
if err != nil {
return fmt.Errorf("formatting stub code: %w\nRaw code:\n%s", err, code)
}
// Stub code goes in go/ subdirectory with _stub suffix
clientDir := filepath.Join(outputDir, "go")
stubFile := filepath.Join(clientDir, "nd_host_"+strings.ToLower(svc.Name)+"_stub.go")
if dryRun {
fmt.Printf("=== %s ===\n%s\n", stubFile, formatted)
return nil
}
@ -250,12 +287,12 @@ func generateGoClientCode(svc internal.Service, outputDir string, dryRun, verbos
return fmt.Errorf("creating client directory: %w", err)
}
if err := os.WriteFile(clientFile, formatted, 0600); err != nil {
return fmt.Errorf("writing file: %w", err)
if err := os.WriteFile(stubFile, formatted, 0600); err != nil {
return fmt.Errorf("writing stub file: %w", err)
}
if verbose {
fmt.Printf("Generated Go client code: %s\n", clientFile)
fmt.Printf("Generated Go client stub: %s\n", stubFile)
}
return nil
}

View File

@ -27,14 +27,14 @@ const (
reconnectScheduleID = "crypto-ticker-reconnect"
)
// Coinbase subscription message structure
// CoinbaseSubscription message structure
type CoinbaseSubscription struct {
Type string `json:"type"`
ProductIDs []string `json:"product_ids"`
Channels []string `json:"channels"`
}
// Coinbase ticker message structure
// CoinbaseTicker message structure
type CoinbaseTicker struct {
Type string `json:"type"`
Sequence int64 `json:"sequence"`

View File

@ -1,7 +1,5 @@
// Code generated by hostgen. DO NOT EDIT.
//go:build wasip1
/*
Package ndhost provides Navidrome host function wrappers for Go/TinyGo plugins.

View File

@ -1,5 +1,5 @@
module github.com/navidrome/navidrome/plugins/host/go
go 1.23
go 1.24
require github.com/extism/go-pdk v1.1.3

View File

@ -0,0 +1,105 @@
// Code generated by hostgen. DO NOT EDIT.
//
// This file contains stub implementations for non-WASM builds.
// These stubs allow IDE support and compilation on non-WASM platforms.
// They panic at runtime since host functions are only available in WASM plugins.
//
//go:build !wasip1
package ndhost
// ArtworkGetArtistUrlRequest is the request type for Artwork.GetArtistUrl.
type ArtworkGetArtistUrlRequest struct {
Id string `json:"id"`
Size int32 `json:"size"`
}
// ArtworkGetArtistUrlResponse is the response type for Artwork.GetArtistUrl.
type ArtworkGetArtistUrlResponse struct {
Url string `json:"url,omitempty"`
Error string `json:"error,omitempty"`
}
// ArtworkGetAlbumUrlRequest is the request type for Artwork.GetAlbumUrl.
type ArtworkGetAlbumUrlRequest struct {
Id string `json:"id"`
Size int32 `json:"size"`
}
// ArtworkGetAlbumUrlResponse is the response type for Artwork.GetAlbumUrl.
type ArtworkGetAlbumUrlResponse struct {
Url string `json:"url,omitempty"`
Error string `json:"error,omitempty"`
}
// ArtworkGetTrackUrlRequest is the request type for Artwork.GetTrackUrl.
type ArtworkGetTrackUrlRequest struct {
Id string `json:"id"`
Size int32 `json:"size"`
}
// ArtworkGetTrackUrlResponse is the response type for Artwork.GetTrackUrl.
type ArtworkGetTrackUrlResponse struct {
Url string `json:"url,omitempty"`
Error string `json:"error,omitempty"`
}
// ArtworkGetPlaylistUrlRequest is the request type for Artwork.GetPlaylistUrl.
type ArtworkGetPlaylistUrlRequest struct {
Id string `json:"id"`
Size int32 `json:"size"`
}
// ArtworkGetPlaylistUrlResponse is the response type for Artwork.GetPlaylistUrl.
type ArtworkGetPlaylistUrlResponse struct {
Url string `json:"url,omitempty"`
Error string `json:"error,omitempty"`
}
// ArtworkGetArtistUrl is a stub that panics on non-WASM platforms.
// GetArtistUrl generates a public URL for an artist's artwork.
//
// Parameters:
// - id: The artist's unique identifier
// - size: Desired image size in pixels (0 for original size)
//
// Returns the public URL for the artwork, or an error if generation fails.
func ArtworkGetArtistUrl(id string, size int32) (*ArtworkGetArtistUrlResponse, error) {
panic("ndhost: ArtworkGetArtistUrl is only available in WASM plugins")
}
// ArtworkGetAlbumUrl is a stub that panics on non-WASM platforms.
// GetAlbumUrl generates a public URL for an album's artwork.
//
// Parameters:
// - id: The album's unique identifier
// - size: Desired image size in pixels (0 for original size)
//
// Returns the public URL for the artwork, or an error if generation fails.
func ArtworkGetAlbumUrl(id string, size int32) (*ArtworkGetAlbumUrlResponse, error) {
panic("ndhost: ArtworkGetAlbumUrl is only available in WASM plugins")
}
// ArtworkGetTrackUrl is a stub that panics on non-WASM platforms.
// GetTrackUrl generates a public URL for a track's artwork.
//
// Parameters:
// - id: The track's (media file) unique identifier
// - size: Desired image size in pixels (0 for original size)
//
// Returns the public URL for the artwork, or an error if generation fails.
func ArtworkGetTrackUrl(id string, size int32) (*ArtworkGetTrackUrlResponse, error) {
panic("ndhost: ArtworkGetTrackUrl is only available in WASM plugins")
}
// ArtworkGetPlaylistUrl is a stub that panics on non-WASM platforms.
// GetPlaylistUrl generates a public URL for a playlist's artwork.
//
// Parameters:
// - id: The playlist's unique identifier
// - size: Desired image size in pixels (0 for original size)
//
// Returns the public URL for the artwork, or an error if generation fails.
func ArtworkGetPlaylistUrl(id string, size int32) (*ArtworkGetPlaylistUrlResponse, error) {
panic("ndhost: ArtworkGetPlaylistUrl is only available in WASM plugins")
}

View File

@ -0,0 +1,248 @@
// Code generated by hostgen. DO NOT EDIT.
//
// This file contains stub implementations for non-WASM builds.
// These stubs allow IDE support and compilation on non-WASM platforms.
// They panic at runtime since host functions are only available in WASM plugins.
//
//go:build !wasip1
package ndhost
// CacheSetStringRequest is the request type for Cache.SetString.
type CacheSetStringRequest struct {
Key string `json:"key"`
Value string `json:"value"`
TtlSeconds int64 `json:"ttlSeconds"`
}
// CacheSetStringResponse is the response type for Cache.SetString.
type CacheSetStringResponse struct {
Error string `json:"error,omitempty"`
}
// CacheGetStringRequest is the request type for Cache.GetString.
type CacheGetStringRequest struct {
Key string `json:"key"`
}
// CacheGetStringResponse is the response type for Cache.GetString.
type CacheGetStringResponse struct {
Value string `json:"value,omitempty"`
Exists bool `json:"exists,omitempty"`
Error string `json:"error,omitempty"`
}
// CacheSetIntRequest is the request type for Cache.SetInt.
type CacheSetIntRequest struct {
Key string `json:"key"`
Value int64 `json:"value"`
TtlSeconds int64 `json:"ttlSeconds"`
}
// CacheSetIntResponse is the response type for Cache.SetInt.
type CacheSetIntResponse struct {
Error string `json:"error,omitempty"`
}
// CacheGetIntRequest is the request type for Cache.GetInt.
type CacheGetIntRequest struct {
Key string `json:"key"`
}
// CacheGetIntResponse is the response type for Cache.GetInt.
type CacheGetIntResponse struct {
Value int64 `json:"value,omitempty"`
Exists bool `json:"exists,omitempty"`
Error string `json:"error,omitempty"`
}
// CacheSetFloatRequest is the request type for Cache.SetFloat.
type CacheSetFloatRequest struct {
Key string `json:"key"`
Value float64 `json:"value"`
TtlSeconds int64 `json:"ttlSeconds"`
}
// CacheSetFloatResponse is the response type for Cache.SetFloat.
type CacheSetFloatResponse struct {
Error string `json:"error,omitempty"`
}
// CacheGetFloatRequest is the request type for Cache.GetFloat.
type CacheGetFloatRequest struct {
Key string `json:"key"`
}
// CacheGetFloatResponse is the response type for Cache.GetFloat.
type CacheGetFloatResponse struct {
Value float64 `json:"value,omitempty"`
Exists bool `json:"exists,omitempty"`
Error string `json:"error,omitempty"`
}
// CacheSetBytesRequest is the request type for Cache.SetBytes.
type CacheSetBytesRequest struct {
Key string `json:"key"`
Value []byte `json:"value"`
TtlSeconds int64 `json:"ttlSeconds"`
}
// CacheSetBytesResponse is the response type for Cache.SetBytes.
type CacheSetBytesResponse struct {
Error string `json:"error,omitempty"`
}
// CacheGetBytesRequest is the request type for Cache.GetBytes.
type CacheGetBytesRequest struct {
Key string `json:"key"`
}
// CacheGetBytesResponse is the response type for Cache.GetBytes.
type CacheGetBytesResponse struct {
Value []byte `json:"value,omitempty"`
Exists bool `json:"exists,omitempty"`
Error string `json:"error,omitempty"`
}
// CacheHasRequest is the request type for Cache.Has.
type CacheHasRequest struct {
Key string `json:"key"`
}
// CacheHasResponse is the response type for Cache.Has.
type CacheHasResponse struct {
Exists bool `json:"exists,omitempty"`
Error string `json:"error,omitempty"`
}
// CacheRemoveRequest is the request type for Cache.Remove.
type CacheRemoveRequest struct {
Key string `json:"key"`
}
// CacheRemoveResponse is the response type for Cache.Remove.
type CacheRemoveResponse struct {
Error string `json:"error,omitempty"`
}
// CacheSetString is a stub that panics on non-WASM platforms.
// SetString stores a string value in the cache.
//
// Parameters:
// - key: The cache key (will be namespaced with plugin ID)
// - value: The string value to store
// - ttlSeconds: Time-to-live in seconds (0 uses default of 24 hours)
//
// Returns an error if the operation fails.
func CacheSetString(key string, value string, ttlSeconds int64) (*CacheSetStringResponse, error) {
panic("ndhost: CacheSetString is only available in WASM plugins")
}
// CacheGetString is a stub that panics on non-WASM platforms.
// GetString retrieves a string value from the cache.
//
// Parameters:
// - key: The cache key (will be namespaced with plugin ID)
//
// Returns the value and whether the key exists. If the key doesn't exist
// or the stored value is not a string, exists will be false.
func CacheGetString(key string) (*CacheGetStringResponse, error) {
panic("ndhost: CacheGetString is only available in WASM plugins")
}
// CacheSetInt is a stub that panics on non-WASM platforms.
// SetInt stores an integer value in the cache.
//
// Parameters:
// - key: The cache key (will be namespaced with plugin ID)
// - value: The integer value to store
// - ttlSeconds: Time-to-live in seconds (0 uses default of 24 hours)
//
// Returns an error if the operation fails.
func CacheSetInt(key string, value int64, ttlSeconds int64) (*CacheSetIntResponse, error) {
panic("ndhost: CacheSetInt is only available in WASM plugins")
}
// CacheGetInt is a stub that panics on non-WASM platforms.
// GetInt retrieves an integer value from the cache.
//
// Parameters:
// - key: The cache key (will be namespaced with plugin ID)
//
// Returns the value and whether the key exists. If the key doesn't exist
// or the stored value is not an integer, exists will be false.
func CacheGetInt(key string) (*CacheGetIntResponse, error) {
panic("ndhost: CacheGetInt is only available in WASM plugins")
}
// CacheSetFloat is a stub that panics on non-WASM platforms.
// SetFloat stores a float value in the cache.
//
// Parameters:
// - key: The cache key (will be namespaced with plugin ID)
// - value: The float value to store
// - ttlSeconds: Time-to-live in seconds (0 uses default of 24 hours)
//
// Returns an error if the operation fails.
func CacheSetFloat(key string, value float64, ttlSeconds int64) (*CacheSetFloatResponse, error) {
panic("ndhost: CacheSetFloat is only available in WASM plugins")
}
// CacheGetFloat is a stub that panics on non-WASM platforms.
// GetFloat retrieves a float value from the cache.
//
// Parameters:
// - key: The cache key (will be namespaced with plugin ID)
//
// Returns the value and whether the key exists. If the key doesn't exist
// or the stored value is not a float, exists will be false.
func CacheGetFloat(key string) (*CacheGetFloatResponse, error) {
panic("ndhost: CacheGetFloat is only available in WASM plugins")
}
// CacheSetBytes is a stub that panics on non-WASM platforms.
// SetBytes stores a byte slice in the cache.
//
// Parameters:
// - key: The cache key (will be namespaced with plugin ID)
// - value: The byte slice to store
// - ttlSeconds: Time-to-live in seconds (0 uses default of 24 hours)
//
// Returns an error if the operation fails.
func CacheSetBytes(key string, value []byte, ttlSeconds int64) (*CacheSetBytesResponse, error) {
panic("ndhost: CacheSetBytes is only available in WASM plugins")
}
// CacheGetBytes is a stub that panics on non-WASM platforms.
// GetBytes retrieves a byte slice from the cache.
//
// Parameters:
// - key: The cache key (will be namespaced with plugin ID)
//
// Returns the value and whether the key exists. If the key doesn't exist
// or the stored value is not a byte slice, exists will be false.
func CacheGetBytes(key string) (*CacheGetBytesResponse, error) {
panic("ndhost: CacheGetBytes is only available in WASM plugins")
}
// CacheHas is a stub that panics on non-WASM platforms.
// Has checks if a key exists in the cache.
//
// Parameters:
// - key: The cache key (will be namespaced with plugin ID)
//
// Returns true if the key exists and has not expired.
func CacheHas(key string) (*CacheHasResponse, error) {
panic("ndhost: CacheHas is only available in WASM plugins")
}
// CacheRemove is a stub that panics on non-WASM platforms.
// Remove deletes a value from the cache.
//
// Parameters:
// - key: The cache key (will be namespaced with plugin ID)
//
// Returns an error if the operation fails. Does not return an error if the key doesn't exist.
func CacheRemove(key string) (*CacheRemoveResponse, error) {
panic("ndhost: CacheRemove is only available in WASM plugins")
}

View File

@ -0,0 +1,132 @@
// Code generated by hostgen. DO NOT EDIT.
//
// This file contains stub implementations for non-WASM builds.
// These stubs allow IDE support and compilation on non-WASM platforms.
// They panic at runtime since host functions are only available in WASM plugins.
//
//go:build !wasip1
package ndhost
// KVStoreSetRequest is the request type for KVStore.Set.
type KVStoreSetRequest struct {
Key string `json:"key"`
Value []byte `json:"value"`
}
// KVStoreSetResponse is the response type for KVStore.Set.
type KVStoreSetResponse struct {
Error string `json:"error,omitempty"`
}
// KVStoreGetRequest is the request type for KVStore.Get.
type KVStoreGetRequest struct {
Key string `json:"key"`
}
// KVStoreGetResponse is the response type for KVStore.Get.
type KVStoreGetResponse struct {
Value []byte `json:"value,omitempty"`
Exists bool `json:"exists,omitempty"`
Error string `json:"error,omitempty"`
}
// KVStoreDeleteRequest is the request type for KVStore.Delete.
type KVStoreDeleteRequest struct {
Key string `json:"key"`
}
// KVStoreDeleteResponse is the response type for KVStore.Delete.
type KVStoreDeleteResponse struct {
Error string `json:"error,omitempty"`
}
// KVStoreHasRequest is the request type for KVStore.Has.
type KVStoreHasRequest struct {
Key string `json:"key"`
}
// KVStoreHasResponse is the response type for KVStore.Has.
type KVStoreHasResponse struct {
Exists bool `json:"exists,omitempty"`
Error string `json:"error,omitempty"`
}
// KVStoreListRequest is the request type for KVStore.List.
type KVStoreListRequest struct {
Prefix string `json:"prefix"`
}
// KVStoreListResponse is the response type for KVStore.List.
type KVStoreListResponse struct {
Keys []string `json:"keys,omitempty"`
Error string `json:"error,omitempty"`
}
// KVStoreGetStorageUsedResponse is the response type for KVStore.GetStorageUsed.
type KVStoreGetStorageUsedResponse struct {
Bytes int64 `json:"bytes,omitempty"`
Error string `json:"error,omitempty"`
}
// KVStoreSet is a stub that panics on non-WASM platforms.
// Set stores a byte value with the given key.
//
// Parameters:
// - key: The storage key (max 256 bytes, UTF-8)
// - value: The byte slice to store
//
// Returns an error if the storage limit would be exceeded or the operation fails.
func KVStoreSet(key string, value []byte) (*KVStoreSetResponse, error) {
panic("ndhost: KVStoreSet is only available in WASM plugins")
}
// KVStoreGet is a stub that panics on non-WASM platforms.
// Get retrieves a byte value from storage.
//
// Parameters:
// - key: The storage key
//
// Returns the value and whether the key exists.
func KVStoreGet(key string) (*KVStoreGetResponse, error) {
panic("ndhost: KVStoreGet is only available in WASM plugins")
}
// KVStoreDelete is a stub that panics on non-WASM platforms.
// Delete removes a value from storage.
//
// Parameters:
// - key: The storage key
//
// Returns an error if the operation fails. Does not return an error if the key doesn't exist.
func KVStoreDelete(key string) (*KVStoreDeleteResponse, error) {
panic("ndhost: KVStoreDelete is only available in WASM plugins")
}
// KVStoreHas is a stub that panics on non-WASM platforms.
// Has checks if a key exists in storage.
//
// Parameters:
// - key: The storage key
//
// Returns true if the key exists.
func KVStoreHas(key string) (*KVStoreHasResponse, error) {
panic("ndhost: KVStoreHas is only available in WASM plugins")
}
// KVStoreList is a stub that panics on non-WASM platforms.
// List returns all keys matching the given prefix.
//
// Parameters:
// - prefix: Key prefix to filter by (empty string returns all keys)
//
// Returns a slice of matching keys.
func KVStoreList(prefix string) (*KVStoreListResponse, error) {
panic("ndhost: KVStoreList is only available in WASM plugins")
}
// KVStoreGetStorageUsed is a stub that panics on non-WASM platforms.
// GetStorageUsed returns the total storage used by this plugin in bytes.
func KVStoreGetStorageUsed() (*KVStoreGetStorageUsedResponse, error) {
panic("ndhost: KVStoreGetStorageUsed is only available in WASM plugins")
}

View File

@ -0,0 +1,60 @@
// Code generated by hostgen. DO NOT EDIT.
//
// This file contains stub implementations for non-WASM builds.
// These stubs allow IDE support and compilation on non-WASM platforms.
// They panic at runtime since host functions are only available in WASM plugins.
//
//go:build !wasip1
package ndhost
// Library represents the Library data structure.
// Library represents a music library with metadata.
type Library struct {
ID int32 `json:"id"`
Name string `json:"name"`
Path string `json:"path"`
MountPoint string `json:"mountPoint"`
LastScanAt int64 `json:"lastScanAt"`
TotalSongs int32 `json:"totalSongs"`
TotalAlbums int32 `json:"totalAlbums"`
TotalArtists int32 `json:"totalArtists"`
TotalSize int64 `json:"totalSize"`
TotalDuration float64 `json:"totalDuration"`
}
// LibraryGetLibraryRequest is the request type for Library.GetLibrary.
type LibraryGetLibraryRequest struct {
Id int32 `json:"id"`
}
// LibraryGetLibraryResponse is the response type for Library.GetLibrary.
type LibraryGetLibraryResponse struct {
Result *Library `json:"result,omitempty"`
Error string `json:"error,omitempty"`
}
// LibraryGetAllLibrariesResponse is the response type for Library.GetAllLibraries.
type LibraryGetAllLibrariesResponse struct {
Result []Library `json:"result,omitempty"`
Error string `json:"error,omitempty"`
}
// LibraryGetLibrary is a stub that panics on non-WASM platforms.
// GetLibrary retrieves metadata for a specific library by ID.
//
// Parameters:
// - id: The library's unique identifier
//
// Returns the library metadata, or an error if the library is not found.
func LibraryGetLibrary(id int32) (*LibraryGetLibraryResponse, error) {
panic("ndhost: LibraryGetLibrary is only available in WASM plugins")
}
// LibraryGetAllLibraries is a stub that panics on non-WASM platforms.
// GetAllLibraries retrieves metadata for all configured libraries.
//
// Returns a slice of all libraries with their metadata.
func LibraryGetAllLibraries() (*LibraryGetAllLibrariesResponse, error) {
panic("ndhost: LibraryGetAllLibraries is only available in WASM plugins")
}

View File

@ -0,0 +1,84 @@
// Code generated by hostgen. DO NOT EDIT.
//
// This file contains stub implementations for non-WASM builds.
// These stubs allow IDE support and compilation on non-WASM platforms.
// They panic at runtime since host functions are only available in WASM plugins.
//
//go:build !wasip1
package ndhost
// SchedulerScheduleOneTimeRequest is the request type for Scheduler.ScheduleOneTime.
type SchedulerScheduleOneTimeRequest struct {
DelaySeconds int32 `json:"delaySeconds"`
Payload string `json:"payload"`
ScheduleID string `json:"scheduleId"`
}
// SchedulerScheduleOneTimeResponse is the response type for Scheduler.ScheduleOneTime.
type SchedulerScheduleOneTimeResponse struct {
NewScheduleID string `json:"newScheduleId,omitempty"`
Error string `json:"error,omitempty"`
}
// SchedulerScheduleRecurringRequest is the request type for Scheduler.ScheduleRecurring.
type SchedulerScheduleRecurringRequest struct {
CronExpression string `json:"cronExpression"`
Payload string `json:"payload"`
ScheduleID string `json:"scheduleId"`
}
// SchedulerScheduleRecurringResponse is the response type for Scheduler.ScheduleRecurring.
type SchedulerScheduleRecurringResponse struct {
NewScheduleID string `json:"newScheduleId,omitempty"`
Error string `json:"error,omitempty"`
}
// SchedulerCancelScheduleRequest is the request type for Scheduler.CancelSchedule.
type SchedulerCancelScheduleRequest struct {
ScheduleID string `json:"scheduleId"`
}
// SchedulerCancelScheduleResponse is the response type for Scheduler.CancelSchedule.
type SchedulerCancelScheduleResponse struct {
Error string `json:"error,omitempty"`
}
// SchedulerScheduleOneTime is a stub that panics on non-WASM platforms.
// ScheduleOneTime schedules a one-time event to be triggered after the specified delay.
// Plugins that use this function must also implement the SchedulerCallback capability
//
// Parameters:
// - delaySeconds: Number of seconds to wait before triggering the event
// - payload: Data to be passed to the scheduled event handler
// - scheduleID: Optional unique identifier for the scheduled job. If empty, one will be generated
//
// Returns the schedule ID that can be used to cancel the job, or an error if scheduling fails.
func SchedulerScheduleOneTime(delaySeconds int32, payload string, scheduleID string) (*SchedulerScheduleOneTimeResponse, error) {
panic("ndhost: SchedulerScheduleOneTime is only available in WASM plugins")
}
// SchedulerScheduleRecurring is a stub that panics on non-WASM platforms.
// ScheduleRecurring schedules a recurring event using a cron expression.
// Plugins that use this function must also implement the SchedulerCallback capability
//
// Parameters:
// - cronExpression: Standard cron format expression (e.g., "0 0 * * *" for daily at midnight)
// - payload: Data to be passed to each scheduled event handler invocation
// - scheduleID: Optional unique identifier for the scheduled job. If empty, one will be generated
//
// Returns the schedule ID that can be used to cancel the job, or an error if scheduling fails.
func SchedulerScheduleRecurring(cronExpression string, payload string, scheduleID string) (*SchedulerScheduleRecurringResponse, error) {
panic("ndhost: SchedulerScheduleRecurring is only available in WASM plugins")
}
// SchedulerCancelSchedule is a stub that panics on non-WASM platforms.
// CancelSchedule cancels a scheduled job identified by its schedule ID.
//
// This works for both one-time and recurring schedules. Once cancelled, the job will not trigger
// any future events.
//
// Returns an error if the schedule ID is not found or if cancellation fails.
func SchedulerCancelSchedule(scheduleID string) (*SchedulerCancelScheduleResponse, error) {
panic("ndhost: SchedulerCancelSchedule is only available in WASM plugins")
}

View File

@ -0,0 +1,29 @@
// Code generated by hostgen. DO NOT EDIT.
//
// This file contains stub implementations for non-WASM builds.
// These stubs allow IDE support and compilation on non-WASM platforms.
// They panic at runtime since host functions are only available in WASM plugins.
//
//go:build !wasip1
package ndhost
// SubsonicAPICallRequest is the request type for SubsonicAPI.Call.
type SubsonicAPICallRequest struct {
Uri string `json:"uri"`
}
// SubsonicAPICallResponse is the response type for SubsonicAPI.Call.
type SubsonicAPICallResponse struct {
ResponseJSON string `json:"responseJson,omitempty"`
Error string `json:"error,omitempty"`
}
// SubsonicAPICall is a stub that panics on non-WASM platforms.
// Call executes a Subsonic API request and returns the JSON response.
//
// The uri parameter should be the Subsonic API path without the server prefix,
// e.g., "getAlbumList2?type=random&size=10". The response is returned as raw JSON.
func SubsonicAPICall(uri string) (*SubsonicAPICallResponse, error) {
panic("ndhost: SubsonicAPICall is only available in WASM plugins")
}

View File

@ -0,0 +1,110 @@
// Code generated by hostgen. DO NOT EDIT.
//
// This file contains stub implementations for non-WASM builds.
// These stubs allow IDE support and compilation on non-WASM platforms.
// They panic at runtime since host functions are only available in WASM plugins.
//
//go:build !wasip1
package ndhost
// WebSocketConnectRequest is the request type for WebSocket.Connect.
type WebSocketConnectRequest struct {
Url string `json:"url"`
Headers map[string]string `json:"headers"`
ConnectionID string `json:"connectionId"`
}
// WebSocketConnectResponse is the response type for WebSocket.Connect.
type WebSocketConnectResponse struct {
NewConnectionID string `json:"newConnectionId,omitempty"`
Error string `json:"error,omitempty"`
}
// WebSocketSendTextRequest is the request type for WebSocket.SendText.
type WebSocketSendTextRequest struct {
ConnectionID string `json:"connectionId"`
Message string `json:"message"`
}
// WebSocketSendTextResponse is the response type for WebSocket.SendText.
type WebSocketSendTextResponse struct {
Error string `json:"error,omitempty"`
}
// WebSocketSendBinaryRequest is the request type for WebSocket.SendBinary.
type WebSocketSendBinaryRequest struct {
ConnectionID string `json:"connectionId"`
Data []byte `json:"data"`
}
// WebSocketSendBinaryResponse is the response type for WebSocket.SendBinary.
type WebSocketSendBinaryResponse struct {
Error string `json:"error,omitempty"`
}
// WebSocketCloseConnectionRequest is the request type for WebSocket.CloseConnection.
type WebSocketCloseConnectionRequest struct {
ConnectionID string `json:"connectionId"`
Code int32 `json:"code"`
Reason string `json:"reason"`
}
// WebSocketCloseConnectionResponse is the response type for WebSocket.CloseConnection.
type WebSocketCloseConnectionResponse struct {
Error string `json:"error,omitempty"`
}
// WebSocketConnect is a stub that panics on non-WASM platforms.
// Connect establishes a WebSocket connection to the specified URL.
//
// Plugins that use this function must also implement the WebSocketCallback capability
// to receive incoming messages and connection events.
//
// Parameters:
// - url: The WebSocket URL to connect to (ws:// or wss://)
// - headers: Optional HTTP headers to include in the handshake request
// - connectionID: Optional unique identifier for the connection. If empty, one will be generated
//
// Returns the connection ID that can be used to send messages or close the connection,
// or an error if the connection fails.
func WebSocketConnect(url string, headers map[string]string, connectionID string) (*WebSocketConnectResponse, error) {
panic("ndhost: WebSocketConnect is only available in WASM plugins")
}
// WebSocketSendText is a stub that panics on non-WASM platforms.
// SendText sends a text message over an established WebSocket connection.
//
// Parameters:
// - connectionID: The connection identifier returned by Connect
// - message: The text message to send
//
// Returns an error if the connection is not found or if sending fails.
func WebSocketSendText(connectionID string, message string) (*WebSocketSendTextResponse, error) {
panic("ndhost: WebSocketSendText is only available in WASM plugins")
}
// WebSocketSendBinary is a stub that panics on non-WASM platforms.
// SendBinary sends binary data over an established WebSocket connection.
//
// Parameters:
// - connectionID: The connection identifier returned by Connect
// - data: The binary data to send
//
// Returns an error if the connection is not found or if sending fails.
func WebSocketSendBinary(connectionID string, data []byte) (*WebSocketSendBinaryResponse, error) {
panic("ndhost: WebSocketSendBinary is only available in WASM plugins")
}
// WebSocketCloseConnection is a stub that panics on non-WASM platforms.
// CloseConnection gracefully closes a WebSocket connection.
//
// Parameters:
// - connectionID: The connection identifier returned by Connect
// - code: WebSocket close status code (e.g., 1000 for normal closure)
// - reason: Optional human-readable reason for closing
//
// Returns an error if the connection is not found or if closing fails.
func WebSocketCloseConnection(connectionID string, code int32, reason string) (*WebSocketCloseConnectionResponse, error) {
panic("ndhost: WebSocketCloseConnection is only available in WASM plugins")
}