V0.6.2 docs openapi (#37)
All checks were successful
All checks were successful
Co-authored-by: Jeffrey Smith <jasafpro@gmail.com> Co-committed-by: Jeffrey Smith <jasafpro@gmail.com>
This commit was merged in pull request #37.
This commit is contained in:
@@ -332,6 +332,107 @@ func hasPermission(granted []string, perm string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// ── api_schema support (v0.6.2) ─────────────────────────────────────
|
||||
|
||||
// APISchemaEntry represents one route's OpenAPI-level documentation
|
||||
// declared via the optional manifest "api_schema" array.
|
||||
type APISchemaEntry struct {
|
||||
Path string `json:"path"`
|
||||
Method string `json:"method"`
|
||||
Summary string `json:"summary,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Params map[string]any `json:"params,omitempty"`
|
||||
Body map[string]any `json:"body,omitempty"`
|
||||
Response map[string]any `json:"response,omitempty"`
|
||||
}
|
||||
|
||||
// ParseAPISchema extracts the optional api_schema array from a package manifest.
|
||||
// Malformed entries are logged and skipped — never blocks extension loading.
|
||||
func ParseAPISchema(manifest map[string]any) []APISchemaEntry {
|
||||
raw, ok := manifest["api_schema"]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
arr, ok := raw.([]any)
|
||||
if !ok {
|
||||
log.Printf("[ext_api] api_schema is not an array, skipping")
|
||||
return nil
|
||||
}
|
||||
|
||||
var entries []APISchemaEntry
|
||||
for i, item := range arr {
|
||||
m, ok := item.(map[string]any)
|
||||
if !ok {
|
||||
log.Printf("[ext_api] api_schema[%d]: not an object, skipping", i)
|
||||
continue
|
||||
}
|
||||
path, _ := m["path"].(string)
|
||||
method, _ := m["method"].(string)
|
||||
if path == "" || method == "" {
|
||||
log.Printf("[ext_api] api_schema[%d]: missing path or method, skipping", i)
|
||||
continue
|
||||
}
|
||||
entry := APISchemaEntry{
|
||||
Path: path,
|
||||
Method: strings.ToUpper(method),
|
||||
}
|
||||
if s, ok := m["summary"].(string); ok {
|
||||
entry.Summary = s
|
||||
}
|
||||
if s, ok := m["description"].(string); ok {
|
||||
entry.Description = s
|
||||
}
|
||||
if p, ok := m["params"].(map[string]any); ok {
|
||||
entry.Params = p
|
||||
}
|
||||
if b, ok := m["body"].(map[string]any); ok {
|
||||
entry.Body = b
|
||||
}
|
||||
if r, ok := m["response"].(map[string]any); ok {
|
||||
entry.Response = r
|
||||
}
|
||||
entries = append(entries, entry)
|
||||
}
|
||||
return entries
|
||||
}
|
||||
|
||||
// ExtractAPIRoutes returns all declared path+method pairs from the manifest.
|
||||
// Used by the OpenAPI builder to enumerate routes for stub generation.
|
||||
func ExtractAPIRoutes(manifest map[string]any) []struct{ Method, Path string } {
|
||||
raw, ok := manifest["api_routes"]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Boolean shorthand — no specific routes to enumerate
|
||||
if _, ok := raw.(bool); ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
routes, ok := raw.([]any)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
var result []struct{ Method, Path string }
|
||||
for _, entry := range routes {
|
||||
route, ok := entry.(map[string]any)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
method, _ := route["method"].(string)
|
||||
path, _ := route["path"].(string)
|
||||
if method == "" || path == "" {
|
||||
continue
|
||||
}
|
||||
result = append(result, struct{ Method, Path string }{
|
||||
Method: strings.ToUpper(method),
|
||||
Path: path,
|
||||
})
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// HasAPIRoutes checks whether a package manifest declares API routes.
|
||||
// Used by startup discovery and admin UI to identify API-capable packages.
|
||||
func HasAPIRoutes(manifest map[string]any) bool {
|
||||
|
||||
Reference in New Issue
Block a user