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")) }