feat: release v0.26 portable i18n and presentation adapters

This commit is contained in:
2026-09-29 13:31:42 +08:00
parent 6a95cad184
commit d1a747c36f
75 changed files with 5681 additions and 52 deletions

46
errors/localization.go Normal file
View File

@@ -0,0 +1,46 @@
package apierrors
import "context"
// Translation is an explicit reference into an independently owned dictionary.
// It does not change the logical error key, status, public code or parameters.
type Translation struct {
Namespace string `json:"namespace"`
Key string `json:"key"`
}
// Localizer is an optional presentation adapter. false preserves the original
// public message. Implementations must support concurrent calls and must not
// mutate registry or failure, or expose causes/parameter values in diagnostics.
type Localizer interface {
Localize(context.Context, *Registry, *APIError) (string, bool)
}
// Definition returns detached metadata for the effective catalog scope.
func (r *Registry) Definition(key string) (Definition, bool) {
if r == nil {
return Definition{}, false
}
d, ok := r.catalog.Definitions[key]
if d.Params != nil {
d.Params = append([]Parameter{}, d.Params...)
}
if d.Translation != nil {
ref := *d.Translation
d.Translation = &ref
}
return d, ok
}
// Parameters returns detached public template arguments. This is for explicit
// presentation adapters, not automatic serialization into an API response.
func (e *APIError) Parameters() map[string]any {
if e == nil {
return nil
}
out := make(map[string]any, len(e.params))
for k, v := range e.params {
out[k] = v
}
return out
}