Merge branch 'development_heroserver' into development_fs

* development_heroserver:
  ....
  ..
  ...
  ...
  ...
  feat: Enhance logging and CORS handling
  feat: Add CORS support to HeroServer
  feat: enhance server documentation and configuration
  refactor: integrate heromodels RPC with heroserver
  ...
  feat: redesign API documentation template
  feat: generate dynamic API docs from OpenRPC spec
  feat: implement documentation handler
This commit is contained in:
2025-09-19 12:57:44 +02:00
53 changed files with 2890 additions and 2612 deletions

1
examples/hero/heromodels/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
heroserver_example

View File

@@ -0,0 +1,27 @@
#!/usr/bin/env -S v -n -w -gc none -cc tcc -d use_openssl -enable-globals -no-skip-unused run
import freeflowuniverse.herolib.hero.heromodels
import freeflowuniverse.herolib.hero.db
import time
fn main() {
// Start the server in a background thread with authentication disabled for testing
spawn fn () ! {
heromodels.new(reset: true, name: 'test')!
heromodels.server_start(
name: 'test'
port: 8086
auth_enabled: false // Disable auth for testing
cors_enabled: true
reset: true
allowed_origins: [
'http://localhost:5173',
]
) or { panic('Failed to start HeroModels server: ${err}') }
}()
// Keep the main thread alive
for {
time.sleep(time.second)
}
}

View File

@@ -1,49 +0,0 @@
#!/usr/bin/env -S v -n -w -gc none -cc tcc -d use_openssl -enable-globals -no-skip-unused run
import json
import freeflowuniverse.herolib.hero.heromodels.rpc
import freeflowuniverse.herolib.schemas.jsonrpc
import freeflowuniverse.herolib.hero.heromodels
import time
fn main() {
println('Starting RPC server on port 9090...')
// Start the server in a background thread
spawn fn () {
rpc.start(http_port: 9090) or { panic('Failed to start RPC server: ${err}') }
}()
// Wait for server to start
time.sleep(time.second * 2)
println('Server started, now testing with some requests...')
// Create a calendar object to test with
mut mydb := heromodels.new()!
mut my_calendar := mydb.calendar.new(
color: '#FF0000'
timezone: 'UTC'
is_public: true
events: []u32{}
)!
my_calendar.name = 'Test Calendar'
my_calendar.description = 'A test calendar for RPC'
// Test the calendar_set RPC method
request := jsonrpc.new_request('calendar_set', json.encode(my_calendar))
println('Sending request: ${request}')
// TODO: Add HTTP client to actually send the request to localhost:9090
// For now, just show what would be sent
// Keep the server running
println('Server is running on http://localhost:9090')
println('You can test it with curl or other HTTP clients')
println('Press Ctrl+C to stop the server')
// Keep main thread alive so server continues running
for {
time.sleep(time.second * 10)
println('Server still running...')
}
}

View File

@@ -35,8 +35,7 @@ if http_port == 0 {
curl -X POST -H "Content-Type: application/json" -d \'\{"jsonrpc":"2.0","method":"comment_set","params":{"comment":"Hello world!","parent":0,"author":42},"id":1\}\' http://localhost:9933
'
)
')
}
rpc.start(http_port: http_port)!
rpc.start(port: http_port)!

1
examples/hero/heroserver/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
heroserver

View File

@@ -5,7 +5,7 @@ import freeflowuniverse.herolib.schemas.openrpc
import os
// 1. Create a new server instance
mut server := heroserver.new(port: 8080)!
mut server := heroserver.new(port: 8086)!
// 2. Create and register your OpenRPC handlers
// These handlers must conform to the `openrpc.OpenRPCHandler` interface.
@@ -14,8 +14,8 @@ openrpc_path := os.join_path(script_dir, 'openrpc.json')
handler := openrpc.new_handler(openrpc_path)!
server.register_handler('comments', handler)!
println('Server starting on http://localhost:8080')
println('Documentation available at: http://localhost:8080/doc/comments/')
println('Comments API available at: http://localhost:8080/api/comments')
println('Server starting on http://localhost:8086')
println('Documentation available at: http://localhost:8086/doc/comments/')
println('Comments API available at: http://localhost:8086/api/comments')
server.start()!

View File

@@ -26,6 +26,43 @@
"type": "string"
}
}
},
{
"name": "get_comment",
"summary": "Get a comment by ID",
"description": "Retrieves a specific comment using its unique identifier.",
"params": [
{
"name": "id",
"description": "The unique identifier of the comment to retrieve.",
"required": true,
"schema": {
"type": "string",
"example": "comment_12345"
}
},
{
"name": "include_metadata",
"description": "Whether to include metadata in the response.",
"required": false,
"schema": {
"type": "boolean",
"example": true
}
}
],
"result": {
"name": "comment",
"description": "The requested comment object.",
"schema": {
"type": "object",
"example": {
"id": "comment_12345",
"text": "This is a sample comment",
"created_at": "2024-01-15T10:30:00Z"
}
}
}
}
],
"components": {}