slate-final-1770513664/pkg/openapi/schema.go
jordan f2ab90548d
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
ci/woodpecker/manual/woodpecker Pipeline was successful
Initialize project from skeleton template
2026-02-08 01:21:05 +00:00

232 lines
6.0 KiB
Go

package openapi
// Schema represents a JSON Schema for OpenAPI.
type Schema map[string]any
// String creates a string schema.
func String() Schema {
return Schema{"type": "string"}
}
// StringWithFormat creates a string schema with a format.
// Common formats: email, uri, uuid, date, date-time, password
func StringWithFormat(format string) Schema {
return Schema{"type": "string", "format": format}
}
// StringEnum creates a string schema restricted to specific values.
func StringEnum(values ...string) Schema {
return Schema{"type": "string", "enum": values}
}
// StringWithMinMax creates a string schema with length constraints.
func StringWithMinMax(min, max int) Schema {
s := Schema{"type": "string"}
if min > 0 {
s["minLength"] = min
}
if max > 0 {
s["maxLength"] = max
}
return s
}
// Int creates an integer schema.
func Int() Schema {
return Schema{"type": "integer"}
}
// IntWithMinMax creates an integer schema with constraints.
func IntWithMinMax(min, max int) Schema {
s := Schema{"type": "integer"}
if min != 0 {
s["minimum"] = min
}
if max != 0 {
s["maximum"] = max
}
return s
}
// Int64 creates a 64-bit integer schema.
func Int64() Schema {
return Schema{"type": "integer", "format": "int64"}
}
// Number creates a number (float) schema.
func Number() Schema {
return Schema{"type": "number"}
}
// Bool creates a boolean schema.
func Bool() Schema {
return Schema{"type": "boolean"}
}
// Array creates an array schema with the given item type.
func Array(items Schema) Schema {
return Schema{
"type": "array",
"items": items,
}
}
// Object creates an object schema with the given properties.
// Required fields can be specified separately.
func Object(props map[string]Schema, required ...string) Schema {
properties := make(map[string]any, len(props))
for k, v := range props {
properties[k] = v
}
s := Schema{
"type": "object",
"properties": properties,
}
if len(required) > 0 {
s["required"] = required
}
return s
}
// Ref creates a $ref to a schema in components/schemas.
func Ref(name string) Schema {
return Schema{"$ref": "#/components/schemas/" + name}
}
// RefArray creates an array of $ref items.
func RefArray(name string) Schema {
return Array(Ref(name))
}
// Nullable makes a schema nullable using oneOf pattern.
func Nullable(s Schema) Schema {
return Schema{
"oneOf": []Schema{
s,
{"type": "null"},
},
}
}
// WithDescription adds a description to a schema.
func (s Schema) WithDescription(desc string) Schema {
s["description"] = desc
return s
}
// WithExample adds an example to a schema.
func (s Schema) WithExample(example any) Schema {
s["example"] = example
return s
}
// WithDefault adds a default value to a schema.
func (s Schema) WithDefault(value any) Schema {
s["default"] = value
return s
}
// WithPattern adds a regex pattern to a string schema.
func (s Schema) WithPattern(pattern string) Schema {
s["pattern"] = pattern
return s
}
// Format sets the format for a schema.
func (s Schema) Format(format string) Schema {
s["format"] = format
return s
}
// Description is an alias for WithDescription for cleaner chaining.
func (s Schema) Description(desc string) Schema {
return s.WithDescription(desc)
}
// Example is an alias for WithExample for cleaner chaining.
func (s Schema) Example(example any) Schema {
return s.WithExample(example)
}
// Default is an alias for WithDefault for cleaner chaining.
func (s Schema) Default(value any) Schema {
return s.WithDefault(value)
}
// Pattern is an alias for WithPattern for cleaner chaining.
func (s Schema) Pattern(pattern string) Schema {
return s.WithPattern(pattern)
}
// UUID creates a UUID string schema.
func UUID() Schema {
return StringWithFormat("uuid").WithExample("550e8400-e29b-41d4-a716-446655440000")
}
// Email creates an email string schema.
func Email() Schema {
return StringWithFormat("email").WithExample("user@example.com")
}
// URL creates a URL string schema.
func URL() Schema {
return StringWithFormat("uri").WithExample("https://example.com")
}
// DateTime creates a date-time string schema.
func DateTime() Schema {
return StringWithFormat("date-time").WithExample("2024-01-15T10:30:00Z")
}
// Password creates a password string schema (hidden in docs).
func Password() Schema {
return StringWithFormat("password")
}
// Pagination creates a common pagination object schema.
func Pagination() Schema {
return Object(map[string]Schema{
"page": Int().WithDescription("Current page number").WithExample(1),
"per_page": Int().WithDescription("Items per page").WithExample(20),
"total": Int().WithDescription("Total number of items").WithExample(100),
"total_pages": Int().WithDescription("Total number of pages").WithExample(5),
})
}
// ResponseSchema creates the standard response envelope schema.
func ResponseSchema(dataSchema Schema) Schema {
return Object(map[string]Schema{
"data": dataSchema,
"meta": Object(map[string]Schema{
"request_id": String().WithDescription("Request correlation ID"),
"timestamp": DateTime().WithDescription("Response timestamp"),
}),
})
}
// ErrorResponseSchema creates the standard error response schema.
func ErrorResponseSchema() Schema {
return Object(map[string]Schema{
"error": Object(map[string]Schema{
"code": String().WithDescription("Machine-readable error code").WithExample("BAD_REQUEST"),
"message": String().WithDescription("Human-readable error message").WithExample("Invalid request"),
"details": Schema{"type": "object"}.WithDescription("Additional error details"),
}, "code", "message"),
"meta": Object(map[string]Schema{
"request_id": String().WithDescription("Request correlation ID"),
"timestamp": DateTime().WithDescription("Response timestamp"),
}),
})
}
// ValidationErrorSchema creates a validation error details schema.
func ValidationErrorSchema() Schema {
return Array(Object(map[string]Schema{
"field": String().WithDescription("Field that failed validation").WithExample("email"),
"message": String().WithDescription("Validation error message").WithExample("is required"),
}, "field", "message"))
}