From cd3ee136f4f705eb182b6b8722c9c81c836e0f7c Mon Sep 17 00:00:00 2001 From: Deluan Date: Mon, 29 Dec 2025 16:49:17 -0500 Subject: [PATCH] feat(plugins): generate Go client stubs for non-WASM platforms Signed-off-by: Deluan --- plugins/cmd/hostgen/integration_test.go | 19 +- plugins/cmd/hostgen/internal/generator.go | 26 ++ .../cmd/hostgen/internal/generator_test.go | 51 +++- .../internal/templates/client_go_stub.go.tmpl | 56 ++++ .../hostgen/internal/templates/doc_go.go.tmpl | 2 - plugins/cmd/hostgen/main.go | 43 ++- plugins/examples/crypto-ticker/main.go | 4 +- plugins/host/go/doc.go | 2 - plugins/host/go/go.mod | 2 +- plugins/host/go/nd_host_artwork_stub.go | 105 ++++++++ plugins/host/go/nd_host_cache_stub.go | 248 ++++++++++++++++++ plugins/host/go/nd_host_kvstore_stub.go | 132 ++++++++++ plugins/host/go/nd_host_library_stub.go | 60 +++++ plugins/host/go/nd_host_scheduler_stub.go | 84 ++++++ plugins/host/go/nd_host_subsonicapi_stub.go | 29 ++ plugins/host/go/nd_host_websocket_stub.go | 110 ++++++++ 16 files changed, 952 insertions(+), 21 deletions(-) create mode 100644 plugins/cmd/hostgen/internal/templates/client_go_stub.go.tmpl create mode 100644 plugins/host/go/nd_host_artwork_stub.go create mode 100644 plugins/host/go/nd_host_cache_stub.go create mode 100644 plugins/host/go/nd_host_kvstore_stub.go create mode 100644 plugins/host/go/nd_host_library_stub.go create mode 100644 plugins/host/go/nd_host_scheduler_stub.go create mode 100644 plugins/host/go/nd_host_subsonicapi_stub.go create mode 100644 plugins/host/go/nd_host_websocket_stub.go diff --git a/plugins/cmd/hostgen/integration_test.go b/plugins/cmd/hostgen/integration_test.go index a1d0f7c9e..a82e7162b 100644 --- a/plugins/cmd/hostgen/integration_test.go +++ b/plugins/cmd/hostgen/integration_test.go @@ -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 } } diff --git a/plugins/cmd/hostgen/internal/generator.go b/plugins/cmd/hostgen/internal/generator.go index 5902fd5ad..859d4472b 100644 --- a/plugins/cmd/hostgen/internal/generator.go +++ b/plugins/cmd/hostgen/internal/generator.go @@ -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 diff --git a/plugins/cmd/hostgen/internal/generator_test.go b/plugins/cmd/hostgen/internal/generator_test.go index 5216a5b1b..c2aebe49c 100644 --- a/plugins/cmd/hostgen/internal/generator_test.go +++ b/plugins/cmd/hostgen/internal/generator_test.go @@ -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 diff --git a/plugins/cmd/hostgen/internal/templates/client_go_stub.go.tmpl b/plugins/cmd/hostgen/internal/templates/client_go_stub.go.tmpl new file mode 100644 index 000000000..69802e717 --- /dev/null +++ b/plugins/cmd/hostgen/internal/templates/client_go_stub.go.tmpl @@ -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}} diff --git a/plugins/cmd/hostgen/internal/templates/doc_go.go.tmpl b/plugins/cmd/hostgen/internal/templates/doc_go.go.tmpl index cf6d8e554..2a1ecc4b2 100644 --- a/plugins/cmd/hostgen/internal/templates/doc_go.go.tmpl +++ b/plugins/cmd/hostgen/internal/templates/doc_go.go.tmpl @@ -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. diff --git a/plugins/cmd/hostgen/main.go b/plugins/cmd/hostgen/main.go index fd5d281fc..5fc35569d 100644 --- a/plugins/cmd/hostgen/main.go +++ b/plugins/cmd/hostgen/main.go @@ -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 } diff --git a/plugins/examples/crypto-ticker/main.go b/plugins/examples/crypto-ticker/main.go index 6f8285b46..400c8ca60 100755 --- a/plugins/examples/crypto-ticker/main.go +++ b/plugins/examples/crypto-ticker/main.go @@ -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"` diff --git a/plugins/host/go/doc.go b/plugins/host/go/doc.go index 2f0c2f2d7..211368063 100644 --- a/plugins/host/go/doc.go +++ b/plugins/host/go/doc.go @@ -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. diff --git a/plugins/host/go/go.mod b/plugins/host/go/go.mod index 1a1e39c9b..954c98071 100644 --- a/plugins/host/go/go.mod +++ b/plugins/host/go/go.mod @@ -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 diff --git a/plugins/host/go/nd_host_artwork_stub.go b/plugins/host/go/nd_host_artwork_stub.go new file mode 100644 index 000000000..9bf0b1352 --- /dev/null +++ b/plugins/host/go/nd_host_artwork_stub.go @@ -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") +} diff --git a/plugins/host/go/nd_host_cache_stub.go b/plugins/host/go/nd_host_cache_stub.go new file mode 100644 index 000000000..d5a8932a9 --- /dev/null +++ b/plugins/host/go/nd_host_cache_stub.go @@ -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") +} diff --git a/plugins/host/go/nd_host_kvstore_stub.go b/plugins/host/go/nd_host_kvstore_stub.go new file mode 100644 index 000000000..d90e4071e --- /dev/null +++ b/plugins/host/go/nd_host_kvstore_stub.go @@ -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") +} diff --git a/plugins/host/go/nd_host_library_stub.go b/plugins/host/go/nd_host_library_stub.go new file mode 100644 index 000000000..c71a30cd1 --- /dev/null +++ b/plugins/host/go/nd_host_library_stub.go @@ -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") +} diff --git a/plugins/host/go/nd_host_scheduler_stub.go b/plugins/host/go/nd_host_scheduler_stub.go new file mode 100644 index 000000000..4a6029429 --- /dev/null +++ b/plugins/host/go/nd_host_scheduler_stub.go @@ -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") +} diff --git a/plugins/host/go/nd_host_subsonicapi_stub.go b/plugins/host/go/nd_host_subsonicapi_stub.go new file mode 100644 index 000000000..e99f52ebb --- /dev/null +++ b/plugins/host/go/nd_host_subsonicapi_stub.go @@ -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") +} diff --git a/plugins/host/go/nd_host_websocket_stub.go b/plugins/host/go/nd_host_websocket_stub.go new file mode 100644 index 000000000..75b4ae0f9 --- /dev/null +++ b/plugins/host/go/nd_host_websocket_stub.go @@ -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") +}