{"id":21748336,"url":"https://github.com/surfstudio/surfgen","last_synced_at":"2026-02-11T14:31:24.805Z","repository":{"id":37087705,"uuid":"275373377","full_name":"surfstudio/SurfGen","owner":"surfstudio","description":"Powerful codegen tool for generating whatever you what from OpenAPI","archived":false,"fork":false,"pushed_at":"2025-02-20T12:59:11.000Z","size":33845,"stargazers_count":26,"open_issues_count":13,"forks_count":3,"subscribers_count":20,"default_branch":"master","last_synced_at":"2025-04-13T07:15:10.142Z","etag":null,"topics":["android","codegeneration","codegenerator","flutter","hacktoberfest","ios","language-agnostic","openapi","swift"],"latest_commit_sha":null,"homepage":"","language":"Swift","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/surfstudio.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2020-06-27T13:03:28.000Z","updated_at":"2024-03-26T02:08:36.000Z","dependencies_parsed_at":"2025-04-13T07:23:40.205Z","dependency_job_id":null,"html_url":"https://github.com/surfstudio/SurfGen","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/surfstudio/SurfGen","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/surfstudio%2FSurfGen","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/surfstudio%2FSurfGen/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/surfstudio%2FSurfGen/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/surfstudio%2FSurfGen/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/surfstudio","download_url":"https://codeload.github.com/surfstudio/SurfGen/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/surfstudio%2FSurfGen/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29335167,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-11T14:07:45.431Z","status":"ssl_error","status_checked_at":"2026-02-11T14:07:45.080Z","response_time":97,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["android","codegeneration","codegenerator","flutter","hacktoberfest","ios","language-agnostic","openapi","swift"],"created_at":"2024-11-26T08:13:07.196Z","updated_at":"2026-02-11T14:31:24.791Z","avatar_url":"https://github.com/surfstudio.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"Docs/logo.png\"\u003e\n\u003c/p\u003e\n\n![Build Status](https://github.com/surfstudio/SurfGen/workflows/release/badge.svg) \n ![Swift Version](https://img.shields.io/badge/swift-5.3.3-orange) ![LISENCE](https://img.shields.io/badge/LICENSE-MIT-green)\n\nSurfGen is an language and plaform agnostic CLI tool written which is used for generate Model and Service layers from OpenAPI 3.x specification\n\n## How it works\n\n1. SurfGen parses OpenAPI file \n2. Collects all dependencies (resolves `$ref` even for another files)\n3. Create an internal representation of specification\n4. Send internal representation to code generator\n5. Code generator read code templates and generate files via them.\n\nYou can use our templates, or just write your own.\n\nIn SurfGen you determine the result platform and language by templates you give to SurfGen!\n\n## Supported plaforms\n\nSurfGen can be run on:\n\n- MacOS\n- Ubuntu\n- On Windows (through WSL)\n\n## Templates\n\nAt this moment we have:\n\n- iOS\n- [Android](Templates/v2/Kotlin/README.md)\n- Flutter (See [Usage](./Usage/Flutter))\n\nTo create your own templates use [https://stencil.fuller.li](https://stencil.fuller.li)\n\n## Installation\n\n\u003e If you want to build it on Ubuntu beforehand you need to configure environment or just install Swift by our [bash script](InstallSwiftOnLinux.sh)\n\nJust add next snippet to your Podfile\n```\npod 'SurfGen', :git =\u003e \"https://github.com/surfstudio/SurfGen.git\"\n```\n\nAlso you can build it from source and just add it to your project using next snippet\n```sh\ngit clone https://github.com/surfstudio/SurfGen\ncd SurfGen\nmake executable\ncp -R Binary \u003cyour_project_path\u003e\n```\nIn order to use generate command you need to setup configuration file. See Configuration File \n\n## Usage\n\nSurfGen currently has 3 workflows: \n- **linter** for linting OpenAPI \n- **generator** for generating code from OpenAPI\n- **create-config** for generate config for **linter** and **generator**\n\n### Create-Config command\n\nUse it to generate config stub with marks and comment. Then you can change it manually to your needs\n```sh\nSurfGen create-config -f swift -t generator\n```\n\n| Parameter | Description |\n|---------|---------------|\n| `--file-ext` or `-f` | Value for property `fileExtension` in config |\n| `--type` or `-t` | Type of config. Must be `linter` or `generator`. **Required** |\n\n\n### Lint command\n\nUse `lint` command to check if your OpenAPI spec is correct in terms of SurfGen (source coude can be generated without errors). If not, you will see log with errors and warnings, describing what exactly is wrong with the spec.\n\n```sh\nSurfGen lint \u003cpathToSpec\u003e\n```\n\nwhere `pathToSpec` is a path either to one file in OpenAPI spec or to the directory containing whole spec.\n\n| Parameter | Description |\n|---------|---------------|\n| `--config` or `-c` | Path to config file. **Required**|\n| `--verbose` or `-v` | Prints `DEBUG` logs |\n\n\n#### Linter Config\n\n[Example (generated by `create-config`)](.surfgen.linter.yaml)\n\n```yaml\nexclude:\n- /Path/To/OpenAPI/Project/fileName.yaml\n- /Path/To/OpenAPI/Project/anotherFile.yaml\n```\n\nBy `exclude` keyword you can specify files which you want to exclude from linting.\n\n**Warning:** this ignore-list can contain paths only to files, not directories.\n\n### Generate command\n\nUse `generate` command to generate files with source code.\n\n```sh\nSurfGen generate -c \u003cpathToConfig\u003e \u003cpathToSpec\u003e\n```\n\nwhere `pathToSpec` is a path to one file in OpenAPI spec **which describes service** you need to generate.\n\n| Parameter | Description |\n|---------|---------------|\n| `--config` or `-c` | Path to config file. **Required** |\n| `--verbose` or `-v` | Prints `DEBUG` logs |\n| `--name` or `-n` | This name will be used for service which you want to generate. So models have their own names, but HTTP enpoint don't you need specify a name for you service. **Required**|\n| `--rewrite` or `-r` | If set wil rewrite old files by new ones. When SurfGen generate file it creates a name for file. If file with this name adlready exists then SurfGen will rewrite it. |\n\n#### Generator config\n\n[Example (generated by `create-config`)](.surfgen.generator.yaml)\n\n| Parameter | Description |\n|---------|---------------|\n| `templates`| Contains array of structures called `Tenpmlate` |\n| `prefixesToCutDownInServiceNames` | See [Prefix Cutting](#prefix-cutting)|\n| `useNewNullableDeterminationStrategy` | See [Nullability](#nullability) |\n| `exludedNodes` | See [NodesCutting](#node-cutting) |\n\n## Editing templates\n\nSee [Templates](TEMPLATES.md)\n\n## Analytcs\n\nThere is a way to collect usage analytcs for your needs.\n\nAnalytics collection is turned off by default, but you can set it up with config.\n\nTo do this you need to add `analytcsConfig` section to ypu config. It can look like:\n\n```Yaml\nanalytcsConfig:\n    logstashEnpointURI: http://127.0.0.1:6644\n    payload:\n        project: Test\n```\n\nWe use this setting to collect usage analytics (on out project inside out company). You can just delete it or configure for your own analytics.\n\n## Supported features\n\nWe support lots of thing. Just it will be more easy to say what we don't support (:\n\n### Nullability\n\nWe support properties nullability by two strategies\n\nOld strategy is based on `required` property of `schema` and we use it to determine if property nullable or not (if property is listed in `required` then it isn't nullable)\n\nBut also we have a new strategy that is based on `nullable` field. And if  `nullable: false` then the property will not be nullable. Also property won't be nullable if field `nullable` wasn't specified. If `nullable: true` then the property will be `nullable`\n\n**By default SurfGen use old strategy**\n\nWe do it in terms of backward compatibility, but we will change default behavior in next major release.\n\nNow if you want to use the new strategy you need to write it in root of your generator's config:\n\n```Yaml\n\nuseNewNullableDeterminationStrategy: true\n\ntemplates:\n    ...\nanalyticsConfig:\n    ...\n```\n\n### Prefix Cutting\n\nWe can cut URI prefixed from method names in generated files. For example we have endpoints with this URIs:\n```\n/api/v1/auth\n/api/v2/auth\n/api/test/auth\n```\n\nBut we dont want to have generated code like:\n```\nfunc apiv1Auth() {...}\nfunc apiv2Auth() {...}\nfunc apitestAuth() {...}\n```\n\nSo to avoid it we should define `prefixesToCutDownInServiceNames` in generator config:\n```\nprefixesToCutDownInServiceNames:\n    - /api/v1\n    - /api/v2\n    - /api/test\n```\n\n### Node Cutting\n\nSurfGen have an ability to cut specific OpenAPI node at run-time.\n\nIf you want to exclude some model or method from linting or generation you can utilize this functionality\n\n```Yaml\nexludedNodes:\n    - \"Tests/Common/NodeExcluding/models.yaml#/components/schemas/BadModel\"\n    - \"Tests/Common/NodeExcluding/api.yaml#/paths/api/v1.1/superAuth~delete\"\n```\nThis comfiguration will remove model `/components/schemas/BadModel` which is located in file `./Tests/Common/NodeExcluding/models.yaml`\n\nAnd will remove operation `delete` from path `/api/v1.1/superAuth` which is located in file  `./Tests/Common/NodeExcluding/api.yaml`\n\nYou can remove by this way leaf nodes like:\n- /components/schemas/*\n- /components/parameters/*\n- /components/header/*\n- /components/responses/*\n- /components/requestBodies/*\n- /paths/*\n\nTo exclude specific operation you can write something like `/paths/api/v1.1/auth~post`\n\nWhere:\n- `paths` - constant from OpenAPI specification\n- `/api/v1.1/auth` - method URI (just like in specification)\n- `post` - operation (you can skip it to remove whole method). Symbol ~ is used to mark specific operation.\n\n### Package separation\n\nSurfGen has an ability to generate models in separate packages according specification.\n\nDefine in generator config:\n```\nspecificationRootPath: /Users/username/your-swagger-repo\n```\n\nThe value is the same as `pwd` shell command output in your specification root.\n\nAfter generation you'll see same created directories as described in your specification.\n\nThe feature is useful for Kotlin projects.\n\nMore information [here](Templates/v2/Kotlin/PackageSeparation.md)\n\n## Unsupported OpenAPI features\n\n- We don't support key `not`\n- We don't support in-place schema declration (when you don't create a `components/schemas/Object` but you write schema just in place where you use it (for example in response))\n- We don't support groups (oneOf, allOf, anyOf) which are include arrays\n- We don't support arrays whose item's type is array (like arrays of arrays)\n- We don't support references to operations:\n```\npaths:\n  /auth/login:\n    $ref: \"./auth/auth_login.yml\"\n```\n- We don't support references to list of models:\n```\nschemas:\n    $ref: \"./definitions.yml\"\n```\n\n... and may be we forgot something ...\n\nBUT if you find something that isn't work - plz contact us, or create an issue and we will fix it!\n\nAnd if you need some of the features that isn't supported - create an issue, or create a PR (:\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsurfstudio%2Fsurfgen","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsurfstudio%2Fsurfgen","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsurfstudio%2Fsurfgen/lists"}