package api import "strings" // Parameter represents an OpenAPI parameter. type Parameter map[string]any // PathParam creates a required path parameter. // // Example: // // PathParam("id", "User identifier") func PathParam(name, description string) Parameter { return Parameter{ "name": name, "in": "path", "required": true, "description": description, "schema": String(), } } // PathParamWithSchema creates a required path parameter with a custom schema. func PathParamWithSchema(name, description string, schema Schema) Parameter { return Parameter{ "name": name, "in": "path", "required": true, "description": description, "schema": schema, } } // QueryParam creates an optional query parameter. // // Example: // // QueryParam("page", "Page number", false) func QueryParam(name, description string, required bool) Parameter { return Parameter{ "name": name, "in": "query", "required": required, "description": description, "schema": String(), } } // QueryParamWithSchema creates a query parameter with a custom schema. func QueryParamWithSchema(name, description string, required bool, schema Schema) Parameter { return Parameter{ "name": name, "in": "query", "required": required, "description": description, "schema": schema, } } // HeaderParam creates a header parameter. func HeaderParam(name, description string, required bool) Parameter { return Parameter{ "name": name, "in": "header", "required": required, "description": description, "schema": String(), } } // CookieParam creates a cookie parameter. func CookieParam(name, description string, required bool) Parameter { return Parameter{ "name": name, "in": "cookie", "required": required, "description": description, "schema": String(), } } // WithExample adds an example to a parameter. func (p Parameter) WithExample(example any) Parameter { p["example"] = example return p } // WithDefault adds a default value to a parameter. func (p Parameter) WithDefault(value any) Parameter { if schema, ok := p["schema"].(Schema); ok { schema["default"] = value p["schema"] = schema } return p } // WithDeprecated marks a parameter as deprecated. func (p Parameter) WithDeprecated(deprecated bool) Parameter { p["deprecated"] = deprecated return p } // ----------------------------------------------------------------------------- // Common Parameter Presets // ----------------------------------------------------------------------------- // IDParam creates a standard ID path parameter. func IDParam() Parameter { return PathParamWithSchema("id", "Resource identifier", UUID()) } // PageParam creates a standard pagination page parameter. func PageParam() Parameter { return QueryParamWithSchema("page", "Page number (1-indexed)", false, Int().WithDefault(1)) } // PerPageParam creates a standard items-per-page parameter. func PerPageParam() Parameter { return QueryParamWithSchema("per_page", "Items per page (max 100)", false, IntWithMinMax(1, 100).WithDefault(20)) } // SortParam creates a sort parameter. // If allowedFields are provided, they're listed in the description. func SortParam(allowedFields ...string) Parameter { desc := "Sort field and direction (e.g., name:asc, created_at:desc)" if len(allowedFields) > 0 { desc = "Sort by: " + strings.Join(allowedFields, ", ") + " (append :asc or :desc)" } return QueryParamWithSchema("sort", desc, false, String().WithExample("created_at:desc")) } // SearchParam creates a search query parameter. func SearchParam() Parameter { return QueryParam("q", "Search query", false).WithExample("keyword") } // APIKeyHeader creates the X-API-Key header parameter. func APIKeyHeader() Parameter { return HeaderParam("X-API-Key", "API key for authentication", true) } // AuthorizationHeader creates the Authorization header parameter. func AuthorizationHeader() Parameter { return HeaderParam("Authorization", "Bearer token for authentication", true). WithExample("Bearer eyJhbGciOiJIUzI1NiIs...") } // ----------------------------------------------------------------------------- // Request Body Helpers // ----------------------------------------------------------------------------- // RequestBody creates a JSON request body. func RequestBody(schema Schema, required bool) map[string]any { return map[string]any{ "required": required, "content": map[string]any{ "application/json": map[string]any{ "schema": schema, }, }, } } // ----------------------------------------------------------------------------- // Response Helpers // ----------------------------------------------------------------------------- // OpResponse creates a response definition for an OpenAPI operation. func OpResponse(description string, schema Schema) map[string]any { return map[string]any{ "description": description, "content": map[string]any{ "application/json": map[string]any{ "schema": schema, }, }, } } // OpResponseNoContent creates a 204 No Content response. func OpResponseNoContent() map[string]any { return map[string]any{ "description": "No content", } } // OpResponses creates a responses map for an operation. func OpResponses(responses map[string]map[string]any) map[string]any { result := make(map[string]any, len(responses)) for code, resp := range responses { result[code] = resp } return result } // OpStandardResponses returns common error responses to include in operations. func OpStandardResponses() map[string]map[string]any { return map[string]map[string]any{ "400": OpResponse("Bad request", ErrorResponseSchema()), "401": OpResponse("Unauthorized", ErrorResponseSchema()), "403": OpResponse("Forbidden", ErrorResponseSchema()), "404": OpResponse("Not found", ErrorResponseSchema()), "422": OpResponse("Unprocessable entity", ErrorResponseSchema()), "429": OpResponse("Too many requests", ErrorResponseSchema()), "500": OpResponse("Internal server error", ErrorResponseSchema()), "503": OpResponse("Service unavailable", ErrorResponseSchema()), } }