{"id":29551205,"url":"https://github.com/d1vbyz3r0/typed","last_synced_at":"2025-07-18T04:02:48.017Z","repository":{"id":299859424,"uuid":"1004410033","full_name":"d1vbyz3r0/typed","owner":"d1vbyz3r0","description":"Code-first OpenAPI 3.0 generator for Echo framework — powered by Go AST and reflection","archived":false,"fork":false,"pushed_at":"2025-07-13T15:11:33.000Z","size":199,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-07-13T17:23:22.089Z","etag":null,"topics":["api","documentation","echo-swagger","golang","openapi","openapi3","swagger"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/d1vbyz3r0.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-18T15:23:23.000Z","updated_at":"2025-07-13T15:08:44.000Z","dependencies_parsed_at":"2025-07-13T17:28:18.489Z","dependency_job_id":null,"html_url":"https://github.com/d1vbyz3r0/typed","commit_stats":null,"previous_names":["d1vbyz3r0/typed"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/d1vbyz3r0/typed","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/d1vbyz3r0%2Ftyped","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/d1vbyz3r0%2Ftyped/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/d1vbyz3r0%2Ftyped/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/d1vbyz3r0%2Ftyped/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/d1vbyz3r0","download_url":"https://codeload.github.com/d1vbyz3r0/typed/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/d1vbyz3r0%2Ftyped/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265697906,"owners_count":23813099,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","documentation","echo-swagger","golang","openapi","openapi3","swagger"],"created_at":"2025-07-18T04:01:58.524Z","updated_at":"2025-07-18T04:02:47.956Z","avatar_url":"https://github.com/d1vbyz3r0.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Typed - OpenAPI Specification Generator for Echo Framework\n\n[![Go Version](https://img.shields.io/badge/Go-%3E%3D%201.24-blue)](https://golang.org/)\n[![License](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)\n\n**Typed** is a Go tool that automatically generates OpenAPI 3.0 specifications for projects using the Echo web\nframework.\nIt uses a sophisticated two-stage approach combining AST (Abstract Syntax Tree) parsing and reflection to analyze your\ncode and produce accurate, comprehensive API documentation.\n\n## 🎯 Why Typed?\n\nMost of existing code-first OpenAPI generators for Go require extensive manual annotations.\nTyped solves this by automatically analyzing your Echo handlers and generating accurate OpenAPI specifications without\nlarge code modifications.\n\n## 🚀 Features\n\n- **Two-Stage Generation Process**: Combines AST analysis with runtime reflection for maximum accuracy\n- **Code-first OpenAPI Generation approach**: Generates OpenAPI 3.0 specifications from your echo server, no magic\n  comments required\n- **Intelligent Parameter Detection**: Automatically detects path, query, and form parameters from inline usage\n- **Type Inference**: Determines parameter types from usage context (e.g. `strconv.Atoi`, `uuid.Parse`)\n- **Extensible Architecture**: Customizable type providers and schema customizers\n- **Multiple Parameter Sources**: Supports path parameters, query parameters, and form data (including file uploads)\n- **Type Registry Generation**: Creates Go code with type registry for reflection-based analysis\n- **Multiple Output Formats**: Supports both YAML and JSON output formats\n- **Echo Framework Integration**: Specifically designed for Echo-based projects\n- **Library Mode**: Generated code can be used as a library\n\n\n\n## 📦 Installation\n\n```bash\ngo install github.com/d1vbyz3r0/typed/cmd/typed@latest\ngo get github.com/d1vbyz3r0/typed@latest\n```\n\n## Demo\nYou can find demo swagger [here](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/d1vbyz3r0/typed/refs/heads/master/examples/gen/example.yaml). \nUsed openapi spec was generated with typed, you can find it in [examples](./examples)\n\n\n## 🛠️ Usage\n\n### Basic Usage\n\nTo generate OpenAPI specification for your Echo project, write yaml config and add go generate directives to your code (\nor run them manually).\nExample of config file can be found [here](./examples/typed.yaml)\n\nYou should have somewhere an object, which will expose routes and middlewares and implement following interface:\n```go\ntype RoutesProvider interface {\n\tOnRouteAdded(func(\n\t\thost string,\n\t\troute echo.Route,\n\t\thandler echo.HandlerFunc,\n\t\tmiddleware []echo.MiddlewareFunc,\n\t))\n\tProvideRoutes()\n}\n```\n\nThen provide a package of your implementation and name of object constructor in configuration file:\n```yaml\nroutes-provider-ctor: NewServerBuilder\nroutes-provider-pkg: github.com/d1vbyz3r0/typed/examples/api\n```\n\n```bash\n//go:generate typed -config ../typed.yaml\n//go:generate go run ../gen/spec_gen.go\n```\n\nIf you don't want to implement interface, you can use typed as library and provide options to Generate function\n\n### Command Line Options\n\n```bash\ntyped [flags]\n\nFlags:\n  -config string Path to config file\n```\n\n### Supported Output Formats\n\nThe tool automatically detects the output format based on file extension:\n\n- **YAML**: `.yaml` or `.yml` extensions\n- **JSON**: `.json` extension\n\n\n## 🧠 Intelligent Parameter Detection\n\nOne of Typed's most powerful features is its ability to automatically detect and analyze parameter usage from your Echo\nhandlers:\n\n### Path Parameters\n\n```go\nfunc GetUser(c echo.Context) error {\n    // Typed detects 'id' parameter and infers int type from strconv.Atoi usage. Note that for now you should pass c.Param directly as argument\n    id, err := strconv.Atoi(c.Param(\"id\"))\n    if err != nil {\n        return err\n    }\n    // Handler logic...\n    return c.JSON(http.StatusOK, user)\n}\n\n// Route: e.GET(\"/users/:id\", GetUser)\n// Result: OpenAPI path parameter 'id' with integer type\n```\n\n### Query Parameters\n\n```go\nfunc SearchUsers(c echo.Context) error {\n    // Typed detects 'limit' as integer and 'active' as boolean\n    limit, _ := strconv.Atoi(c.QueryParam(\"limit\"))\n    active, _ := strconv.ParseBool(c.QueryParam(\"active\"))\n    \n    // Handler logic...\n    return c.JSON(http.StatusOK, users)\n}\n\n// Result: OpenAPI query parameters with correct types\n```\n\n### Form Parameters \u0026 File Uploads\n\n```go\nfunc UpdateProfile(c echo.Context) error {\n    // Typed detects form fields and file uploads\n    name := c.FormValue(\"name\")\n    email := c.FormValue(\"email\")\n    \n    // File upload detection\n    avatar, err := c.FormFile(\"avatar\")\n    if err != nil {\n        return err\n    }\n    \n    // Handler logic...\n    return c.JSON(http.StatusOK, response)\n}\n\n// Result: OpenAPI form schema with string fields and binary file field\n```\n\nOf course, you also can declare parameters as struct fields with\nnecessary [tags](https://echo.labstack.com/docs/binding).\nWhen both struct tag and inline usage are found, the struct field will have priority.\n\n#### Some limitations\nFor now, xml and form tags are not fully supported. You can still use them, but names should be as they occur in field names if the tag is standalone:\n```go\ntype AuthForm struct {\n\tName string `form:\"Name\"`\n\tAge  int    `xml:\"Age\"`\n}\n```\n\nOr same as json tag, if you for some reason need to process multiple data formats\n```go\ntype AuthForm struct {\n\tName string `json:\"name\" form:\"name\" xml:\"name\"`\n\tAge  int    `json:\"age\" form:\"name\" xml:\"name\"`\n}\n```\n\nIt will be fixed in the nearest future, when I figure out how to properly implement that\n\nAlso, file arrays are not properly handled in forms\n\n### Supported Type Inference\n\nTyped automatically infers parameter types from common conversion functions:\n\n| Package   | Function             | Inferred Type |\n|-----------|----------------------|---------------|\n| `strconv` | `Atoi`               | `int`         |\n| `strconv` | `ParseInt`           | `int64`       |\n| `strconv` | `ParseUint`          | `uint`        |\n| `strconv` | `ParseFloat`         | `float64`     |\n| `strconv` | `ParseBool`          | `bool`        |\n| `uuid`    | `Parse`, `MustParse` | `uuid.UUID`   |\n| `time`    | `Parse`              | `time.Time`   |\n\n\n## 📋 Enum Support\n\nTyped automatically detects and extracts Go enums (constants with custom types) and includes them in the OpenAPI\nspecification as enum values. This ensures your API documentation accurately reflects the allowed values for enum\nfields.\n\n### Automatic Enum Detection\n\nTyped analyzes your Go constants and automatically generates OpenAPI enum schemas:\n\n```go\n// String-based enums\ntype Role string\n\nconst (\n    RoleAdmin = Role(\"admin\")\n    RoleUser = Role(\"user\")\n    RoleGuest = Role(\"guest\")\n)\n\n// Integer-based enums\ntype Status int\n\nconst (\n    StatusNew Status = 1\n    StatusDone Status = 2\n    StatusCancelled Status = 3\n)\n\n// Usage in structs\ntype User struct {\n    ID     int    `json:\"id\"`\n    Name   string `json:\"name\"`\n    Role   Role   `json:\"role\"`\n    Status Status `json:\"status\"`\n}\n```\n\n### Generated OpenAPI Schema\n\nThe above Go enums are automatically converted to OpenAPI enum schemas:\n\n```yaml\ncomponents:\n  schemas:\n    User:\n      type: object\n      properties:\n        id:\n          type: integer\n        name:\n          type: string\n        role:\n          type: string\n          enum: [ \"admin\", \"user\", \"guest\" ]\n        status:\n          type: integer\n          enum: [ 1, 2, 3 ]\n```\n\n### Supported Enum Types\n\nTyped supports various enum value types:\n\n| Go Type   | Example         | OpenAPI Type               |\n|-----------|-----------------|----------------------------|\n| `string`  | `Role(\"admin\")` | `string` with enum values  |\n| `int`     | `Status(1)`     | `integer` with enum values |\n| `float64` | `Priority(1.5)` | `number` with enum values  |\n| `bool`    | `Flag(true)`    | `boolean` with enum values |\n\n\n## 🔧 Extensibility\n\n### Custom Type Providers\n\nYou can extend type inference by registering custom type providers:\n\n```go\n// Example from common/typing/type.go\nfunc RegisterTypeProvider(p Provider) {\n    providers = append(providers, p)\n}\n\n// Custom provider example\nfunc customProvider(pkg string, funcName string) (reflect.Type, bool) {\n    if pkg == \"mypackage\" \u0026\u0026 funcName == \"ParseCustomType\" {\n        return reflect.TypeOf(MyCustomType{}), true\n    }\n    return nil, false\n}\n```\n\n### Schema Customizers\n\nCustomize OpenAPI schema generation with custom functions:\n\n```go\n// Example from customizers.go\nfunc RegisterCustomizer(fn openapi3gen.SchemaCustomizerFn) {\n    customizers = append(customizers, fn)\n}\n\n// Built-in customizers include:\n// - Field name overrides from struct tags\n// - File upload handling\n// - UUID format specification\n// - Enum value support\n```\n\n\n## 🔌 Handler Processing Hooks\n\nTyped provides a hook system that allows you to customize OpenAPI specification generation based on handler analysis.\nThis is particularly useful for automatically detecting and documenting middleware-specific behavior.\n\n### Built-in Hooks\n\n#### JWT Authentication Hook\n\nTyped includes a built-in hook that automatically detects Echo JWT middleware usage and adds appropriate security\nschemes to your OpenAPI specification:\nTo enable it, add following to your config file:\n\n```yaml\nprocessing-hooks:\n  - \"EchoJWTMiddlewareHook\"\n```\n\n```go\nfunc GetProtectedResource(c echo.Context) error {\n    // Your protected handler logic\n    return c.JSON(http.StatusOK, data)\n}\n\n// Route with JWT middleware\nprotected := e.Group(\"/api\")\nprotected.Use(echojwt.WithConfig(echojwt.Config{\n    SigningKey: []byte(\"secret\"),\n}))\nprotected.GET(\"/users\", GetProtectedResource)\n```\n\n**Result**: Automatically adds Bearer token security scheme to the OpenAPI specification:\n\n```yaml\ncomponents:\n  securitySchemes:\n    bearerAuthScheme:\n      type: http\n      scheme: bearer\n      bearerFormat: JWT\npaths:\n  /api/users:\n    get:\n      security:\n        - bearerAuthScheme: [ ]\n```\n\n### Custom Hooks\n\nYou can register custom hooks to extend the specification generation process:\n\n```go\n// Example from middlewares.go\nfunc RegisterHandlerProcessingHook(hook HandlerProcessingHookFn) {\n    handlerProcessingHooks = append(handlerProcessingHooks, hook)\n}\n\n// Custom hook example\nfunc CustomAuthHook(spec *openapi3.T, operation *openapi3.Operation, handler handlers.Handler) {\n    // Analyze handler middlewares\n    for _, mw := range handler.Middlewares() {\n        middlewareName := typed.GetMiddlewareFuncName(mw)\n        \n        if strings.Contains(middlewareName, \"myauth\") {\n            // Add custom security scheme\n            if spec.Components.SecuritySchemes == nil {\n                spec.Components.SecuritySchemes = make(map[string]*openapi3.SecuritySchemeRef)\n            }\n            \n            spec.Components.SecuritySchemes[\"customAuth\"] = \u0026openapi3.SecuritySchemeRef{\n                Value: \u0026openapi3.SecurityScheme{\n                    Type: \"apiKey\",\n                    In:   \"header\",\n                    Name: \"X-API-Key\",\n                },\n            }\n            \n            // Apply to operation\n            if operation.Security == nil {\n\t\t\t\toperation.Security = openapi3.NewSecurityRequirements()\n            }\n            operation.Security.With(openapi3.SecurityRequirement{\n                \"customAuth\": []string{},\n            })\n        }\n    }\n}\n\n// Register your custom hook\nfunc init() {\n    typed.RegisterHandlerProcessingHook(CustomAuthHook)\n}\n```\n\n### Hook Function Signature\n\n```go\ntype HandlerProcessingHookFn func (spec *openapi3.T, operation *openapi3.Operation, handler handlers.Handler)\n```\n\n**Parameters:**\n\n- `spec`: The OpenAPI specification being built\n- `operation`: The current operation being processed\n- `handler`: Handler information including middlewares, route, and metadata\n\n### Use Cases for Custom Hooks\n\n- **Authentication/Authorization**: Automatically detect auth middlewares and add security schemes\n- **Rate Limiting**: Add rate limit headers and responses based on middleware detection\n- **CORS**: Document CORS headers and preflight responses\n- **Validation**: Add validation error responses based on validation middleware\n- **Logging/Monitoring**: Add operation IDs or tags based on middleware configuration\n- **Custom Headers**: Document custom headers added by middlewares\n\n### Middleware Detection\n\nTyped provides utilities to analyze middleware functions:\n\n```go\n// Get middleware function name for analysis\nmiddlewareName := GetMiddlewareFuncName(middleware)\n\n// Example middleware names:\n// \"github.com/labstack/echo-jwt.(*Config).ToMiddleware.func1\"\n// \"github.com/labstack/echo/v4/middleware.CORS.func1\"\n// \"myproject/middleware.CustomAuth\"\n```\n\nThis hook system makes Typed highly extensible and allows it to automatically document complex middleware behavior\nwithout manual specification.\n\n\n## 🏗️ How It Works\n\nTyped uses a sophisticated two-stage approach to overcome the limitations of pure AST analysis:\n\n### Stage 1: Code Generation \u0026 Type Registry\n\n1. **AST Parsing**: Analyzes your Go source code using Go's AST parser\n2. **Type Discovery**: Identifies all types used in Echo handlers and routes\n3. **Registry Generation**: Generates Go code with a type registry containing all discovered types\n4. **Standard Functions**: Includes utility functions for reflection-based analysis\n5. **Library Output**: The generated code can be used as a standalone library\n\n### Stage 2: Specification Generation\n\n1. **Registry Execution**: Runs the generated code to access `reflect.Type` information\n2. **Echo Route Analysis**: Maps Echo routes to their corresponding handlers\n3. **Schema Generation**: Uses [kin-openapi](https://github.com/getkin/kin-openapi) to create OpenAPI schemas from\n   reflection data\n4. **Specification Assembly**: Builds complete OpenAPI 3.0 specification with proper SchemaRefs\n5. **Output Generation**: Saves specification in requested format (YAML/JSON)\n\n### Why Two Stages?\n\nThe two-stage approach is necessary because:\n\n- **AST Limitation**: During AST analysis, we cannot access `reflect.Type` information\n- **Runtime Reflection**: We need actual type information to generate accurate schemas\n- **Best of Both Worlds**: Combines compile-time analysis with runtime type information\n\n### Key Dependencies\n\n- **[kin-openapi](https://github.com/getkin/kin-openapi)**: Powers the OpenAPI 3.0 specification generation, schema\n  creation, and SchemaRef handling\n- **Go AST**: For source code analysis and type discovery\n- **Go Reflection**: For runtime type information access\n\n\n## 🤝 Contributing\n\nContributions are welcome! This project was created because similar tools weren't available for Echo framework projects.\n\n\n## 📄 License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n\n## Acknowledgments\n\n- **[kin-openapi](https://github.com/getkin/kin-openapi)** - Essential for OpenAPI 3.0 specification generation and\n  schema handling\n- **[Echo Framework](https://echo.labstack.com/)** - High performance, minimalist Go web framework\n- **Go AST \u0026 Reflection** - Powerful code analysis and runtime type inspection capabilities\n\n\n## 🐛 Issues \u0026 Support\n\nIf you encounter any issues or have questions:\n\n1. Check existing [Issues](https://github.com/d1vbyz3r0/typed/issues)\n2. Create a new issue with detailed description\n3. Include code examples and error messages\n\n\n## 🔮 Roadmap\n- [ ] Add support for form and xml tags\n- [ ] Write doc for configuration\n- [ ] Enhanced comment parsing for OpenAPI descriptions\n- [ ] Headers support\n- [ ] Add more std hooks \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fd1vbyz3r0%2Ftyped","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fd1vbyz3r0%2Ftyped","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fd1vbyz3r0%2Ftyped/lists"}