Swiftpack.co - Package - yonaskolb/SwagGen

SwagGen

Platforms SPM Git Version Build Status license

SwagGen is a library and command line tool for parsing and generating code for OpenAPI/Swagger 3.0 specs, completely written in Swift.

Swagger 2 support has been removed. For Swagger 2 use version 3.0.2 or the swagger_2 branch

Swagger parser

It contains a Swagger library that can be used in Swift to load and parse Swagger specs.

Swagger code generator

SwagGen is command line tool that generates code from a OpenAPI/Swagger 3.0 spec. Templates for any language can be written that leverage this generator.

It is an alternative the official swagger-codegen java code generator, and adds some improvements such as speed, configurability, simplicity, extensibility, and an improved templating language.

Swift template

SwagGen includes a bundled template for generating a client side Swift library for interfacing with the Swagger spec. It includes support for model inheritance, shared enums, discrete and mutable request objects, inline schemas, Codable and Equatable models, configurable options, generic networking stack, and many other niceties.

Installing

Make sure Xcode 10.2 is installed first.

Mint

$ mint install yonaskolb/SwagGen

Homebrew

$ brew tap yonaskolb/SwagGen https://github.com/yonaskolb/SwagGen.git
$ brew install SwagGen

Make

$ git clone https://github.com/yonaskolb/SwagGen.git
$ cd SwagGen
$ make install

Swift Package Manager

Use as CLI

$ git clone https://github.com/yonaskolb/SwagGen.git
$ cd swaggen
$ swift run

Use as dependency

Add the following to your Package.swift file's dependencies:

.package(url: "https://github.com/yonaskolb/SwagGen.git", from: "4.3.0"),

And then import wherever needed:

import SwagGenKit
import Swagger

Usage

Use --help to see usage information

swaggen --help
Usage: swaggen <command> [options]

Commands:
  generate        Generates a template from a Swagger spec
  help            Prints this help information
  version         Prints the current version of this app

generate

swaggen generate path_to_spec

Use swaggen generate --help to see the list of generation options.

  • spec: This is the path to the Swagger spec and is a required parameter. It can either be a file path or a web url to a YAML or JSON file

  • --language: The language to generate a template for. This defaults to swift for now.

  • --template:: This is the path to the template config yaml file. It can either be a direct path to the file, or a path to the parent directory which will by default look for /template.yml. If this is not passed, the default template for the language will be used.

  • --destination: The directory that the generated files will be added to.

  • --option: An option that will be merged with the template config options with those in this argument taking precedence, meaning any existing options of the same name will be overwritten. This argument can be repeated to pass in multiple options. Options must specify the option name and option value separated by a colon, with any spaces contained in quotes. Nested options in dictionaries can be set by using a dot syntax. The following formats are allowed:

    • -- option myOption:myValue
    • -- option modelSuffix: Model
    • -- option propertyNames.identifier: id
    • -- option "myOption: my value"
  • --clean: Controls if and how the destination directory is cleaned of non generated files. Options are:

    • none: no files are removed (default)
    • all: all other files are removed
    • leave.files: all files and directories except those that start with . in the destination directory are removed. This is useful for keeping configuration files and directories such as .git around, while still making sure that items removed from the spec are removed from the generated API.
  • --verbose: Show more verbose output

  • --silent: Silences any standard output. Errors will still be shown

Example:

swaggen generate http://myapi.com/spec --template Templates/Swift  --destination generated --option name:MyAPI --option "customProperty: custom value --clean leave.files"

For the Swift template, a handy option is name, which changes the name of the generated framework from the default of API. This can be set in the template or by passing in --option name:MyCoolAPI.

Swift Template

List of all available options:

name | action | expected values | default value --- | --- | --- | --- name | name of the API | String | API authors | authors in podspec | String | Yonas Kolb baseURL | baseURL in APIClient | String | first scheme, host, and base path of spec fixedWidthIntegers | whether to use types like Int32 and Int64 | Bool | false homepage | homepage in podspec | String | https://github.com/yonaskolb/SwagGen modelPrefix | model by adding a prefix and model file name | String | null modelSuffix | model by adding a suffix and model file name | String | null mutableModels | whether model properties are mutable | Bool | true modelType | whether each model is a struct or class | String | class modelInheritance | whether models use inheritance. Must be false for structs | Bool | true modelNames | override model names | [String: String] | [:] modelProtocol | customize protocol name that all models conform to | String | APIModel enumNames | override enum names | [String: String] | [:] enumUndecodableCase | whether to add undecodable case to enums | Bool | false propertyNames | override property names | [String: String] | [:] safeArrayDecoding | filter out invalid items in array instead of throwing | Bool | false safeOptionalDecoding | set invalid optionals to nil instead of throwing | Bool | false tagPrefix | prefix for all tags | String | null tagSuffix | suffix for all tags | String | null codableResponses | constrains all responses to be Codable | Bool | false

If writing your own Swift template there are a few types that are generated that you will need to provide typealias's for:

  • ID: The UUID format. Usually UUID or String
  • File: The file format. Usually URL, Data or a custom type with a mimeType and fileName
  • DateTime: The date-time format. Usually Date
  • DateDay: The date format. Usually Date or a custom type.

Editing

$ git clone https://github.com/yonaskolb/SwagGen.git
$ cd SwagGen
$ swift package generate-xcodeproj

This use Swift Project Manager to create an xcodeproj file that you can open, edit and run in Xcode, which makes editing any code easier.

If you want to pass any required arguments when running in XCode, you can edit the scheme to include launch arguments.

Templates

Templates are made up of a template config file, a bunch of Stencil files, and other files that will be copied over during generation

Template config

This is the configuration and manifest file for the template in YAML or JSON format. It can contain:

  • formatter: Optional formatter to use. This affects what properties are available in the templates and how they are formatted e.g. Swift
  • templateFiles: a list of template files. These can each have their paths, contents and destination directories modified through Stencil tags. One template file can also output to multiple files if they path is changed depending on a list context. Each file contains:
    • path: relative path to the template config. The extension is usually .stencil or the type it is going to end up as
    • context: optional context within the spec. This is provided to the generated file, otherwise the full context will be passed. If this is a list then a file will be created for each object and the context within that list is used. (e.g. a file for every model in the spec definitions gets it's own definition context). Note that properties in the template options field can be used here
    • destination: optional destination path. This can contain stencil tags whose context is that from the context above. e.g. if context was definitions then the path could be Models/{{ type }}.swift and the filename would be the type of the definition. If this is left out the destination will be the same as the path, relative to the final destination directory. If it resolves to an empty string it will be skipped and not generated.
  • copiedFiles: this is an array of relative paths that will be copied to the destination. They can be files or directories. This is used for files that won't have their contents, filenames or paths changed.
  • options: these are the options passed into every stencil file and can be used to customize the template. These options are merged with the options argument, with the argument options taking precendance. These options can be references in template file paths and their contents.

An example template for Swift can be found here

Template Files

These files follow the Stencil file format outlined here https://stencil.fuller.li

Formatters

Formatters change what information is available to the templates and how it's formatted. They can be specified via the formatter property in the template config. Usually these would map to a specific target language, but can be customized for different purposes.

Output Languages

SwagGen can be used to generate code for any language. At the moment there is only a formatter and template for Swift

Swift API usage

Usage documentation can be found in the Readme that is generated with your template.


Attributions

This tool is powered by:

Thanks also to Logan Shire and his initial work on Swagger Parser

Contributions

Pull requests and issues are welcome

License

SwagGen is licensed under the MIT license. See LICENSE for more info.

Github

link
Stars: 263

Used By

Total: 0

Releases

4.3.0 - 2019-11-19 10:35:05

Added

  • Added ability to set nested template options from the command line using dot syntax eg --option "typeAliases.ID: String" #189
  • Added a customizable jsonEncoder on APIClient #172 #203
  • Added support for using a custom encoder per request #172 #203

Changes

  • List operations by path and then by method to keep the order consistent between code generations #185
  • Add codableResponses option that constrains all models and responses to Codable #198
  • Add propertyNames option that allow to override the name of properties #196

Fixed

  • Fixed responses from silently failing to parse when missing a description, which is now an optional property that defaults to an empty string #193
  • Add missing custom model protocol name #191
  • Fixed missing customization of JSONEncoder instance to encode request's body #147
  • Fixed string uploads #161

Commits

4.2.0 - 2019-07-11 14:36:55

Swift Template Changes

  • Added support for objects in query params #158
  • Added support for nullable properties #165
  • Removed 3rd party Result framework #174
  • Fixed path to Enum.swift on Linux #157
  • Fixed model initializers with multiple levels of inheritance #175

Fixes

  • Decode Swagger specs with no components #180

Changes

  • Update dependencies

Commits

4.1.0 - 2019-03-29 12:12:41

Added

  • Added swift template option enumUndecodableCase that adds an undecodable case to enums when decoding fails #141

Fixed

  • Fixed installing in Swift 5 #139
  • Fixed Swift template building in Swift 5 by Alamofire #139

Changed:

  • Updated codebase to Swift 5 and dropped Swift 4.2 #139

Commits

4.0.0 - 2019-03-19 12:12:49

Added

  • Added support for OpenAPISpec/Swagger 3. Support for Swagger 2 has been removed. For that please use release 3.0.2 or the swagger_2 branch #118 #121
  • Added StencilSwiftKit support for templates #111
  • Added oneOf and anyOf with discriminators #121
  • Added support for generating inline schemas when they are wrapped in an array #121

Swift Template Updates

  • Swagger 3 support #118
  • Added generated Server #118
  • Discriminated oneOf and anyOf enums #121
  • Allow both form and path parameters in the same request #118
  • Add headers to request #120
  • Add framework Info.plist #117
  • Use safeArrayDecoding #117
  • Catch APIClientError from RequestBehaviour validation #117
  • Added typeAliases option #117
  • Validation error changed from a String to an Error #117
  • Improve request description and summary #117
  • Change SecurityRequirement.scope string to SecurityRequirement.scopes array #117
  • Use StringCodingKey instead of enum types #117
  • Replace DateTime with Date #117
  • Update Alamofire dependency to 4.8.1 #123
  • Update Result dependency to 4.1.0 #123
  • Enums conform to Equatable and CaseIterable #124
  • Removed support for Swift 4.1 #124
  • Only generate isEqual in model classes not structs #117
  • Fixed path params that don't have swift friendly names #130
  • Fixed operations with mutiple success responses and no error responses #127
  • Fix nested schemas in subclasses thinking they have a parent #128
  • Handle nil modelProtocol option #117

Removed

  • Removed support for Swagger 2 #118
  • Removed Swift 4.1 support #134

Commits

3.0.2 - 2019-02-14 23:57:08

Added

  • Added example and default to the generator

Fixed

  • Changed default date formatter in templates to use yyyy not YYY #114
  • Fixed date formatting of DateDay properties #114
  • Fixed encoding of dictionary types #113

Internal

  • Updated to Swift 4.2
  • Updated YAMS, Rainbow and SwiftCLI

Commits

3.0.1 - 2018-08-25 04:48:19

Added

  • Added new modelProtocol template option which defaults to APIModel #109

Fixed

  • Fixed crash in Swift template when not using any RequestBehaviours #108

Commits

3.0.0 - 2018-08-24 08:50:43

Added

  • Added File upload support #103
  • Added top level security support #104
  • Added modelType option to Swift template for class or struct models #94
  • Added modelInheritance template option #94
  • Added modelNames and enumNames template options for overriding names #95
  • Added x-enum-name property to Swagger for custom enum names #98
  • Added operation summary to generation and template

Changed

  • Swift template changes #104
    • Renamed APIError to APIClientError
    • Removed APIClient.authorizer
    • Added RequestBehavour.validate (replaces APIClient.authorizer)
    • APIClient.makeRequest now returns a CancellableRequest instead of Alamofire.Request
    • A new APIClient.jsonDecoder property which is used for json requests
    • Renamed queue to completionQueue in APIClient.makeRequest
    • Replaced APIError. authorizationError with APIClientError. validationError
    • Rename APIService.authorization to APIService.securityRequirement
  • Generated type changes in Swift template. You will now have to handle or typealias the following types #104
    • ID: The UUID format. Usually UUID or String
    • File: The file format. Usually URL, Data or a custom type with a mimeType and fileName

Fixed

  • Sort operations in generated Readme
  • Better name camel casing #100
  • Fix empty string field decoding in YAML #101
  • Escape Protocol in swift templates

2.1.2 - 2018-06-24 12:03:07

Added

  • Added generated Swift template documenation #87

Fixed

  • Fixed nil AnyCodable values being encoded as null
  • Fixed inbuilt templates not being found in Mint installations

2.1.1 - 2018-06-01 10:21:04

Added

  • Added support for ASCI encoded swagger specs #80

Fixed

  • Fixed homebrew installation on machines with both Xcode 9.3 and Command line tools installed
  • Fixed UUID parameter encoding #81

2.1.0 - 2018-05-17 07:10:01

Added

  • Separated date and date-time formats into DateDay and DateTime structs #74 #77
  • Added new modelPrefix and modelSuffix options #75

Fixed

  • Fixed regression where request bodies were not being encoding properly #76
  • Fixed safeOptionalDecoding not working on optional Arrays
  • Fixed date-time not decoding in some cases #77

2.0.0 - 2018-05-04 15:03:39

Added

  • Swift template: added Codable support to models #61
  • Swift template: added Equatable support to models #63
  • Swift template: added mutableModels option #64
  • Swift template: added safeArrayDecoding option #71
  • Swift template: added safeOptionalDecoding option #71
  • Bundle templates with installation #65
  • New language argument which defaults to swift for now #65
  • Default template for language is now used if no template path is specified #65
  • Added support for inline anonymous schemas in definitions, body params, and responses #66
  • Added UUID support #72
  • Added --silent flag #68
  • Added --verbose flag #68
  • Added --version flag #68

Changes

  • Swift template: move sources out of now unnessary subdirectory #62
  • Swift template: reorganise template #69
  • Swift template: updated dependencies
  • Swift template: Update to Swift 4.1
  • Updated CLI #68
  • Improved error output #68
  • Make executable lowercase swaggen (breaking on linux) #68
  • BREAKING generation moved into generate command: swaggen generate #68
  • BREAKING --spec has changed to a required parameter: swaggen generate path_to_spec #68

Removed

  • BREAKING Swift template: models no longer have init(jsonDictionary: JSONDictionary) or encode() -> JSONDictionary functions #61
  • Swift template: removed JSONUtilities dependency #61

1.2.0 - 2018-01-11 07:08:22

Added

  • Added fixedWidthIntegers option to Swift template. Thanks @martinknabbe
  • Added support for response references #58

Fixed

  • Fixed Swift 4.0.2 warnings
  • Fixed Brew install

1.1.0 - 2017-09-26 22:02:28

Added

  • Generate typealias for models with reference and array types #42 thanks @Liquidsoul
  • generate typealias for models that only have additional properties

Fixed

  • fixed SPM installation issue

1.0.0 - 2017-09-25 13:04:19

Added

  • Swift template: decode response on background queue and then call completion on main thread or new queue parameter

Changed

  • Updated project to Swift 4 #42
  • Updated Swift templates to Swift 4 #42

0.6.1 - 2017-08-25 18:30:52

Added

  • Homebrew and Make installations
  • Enums now also have a raw property to access original json

Changed

  • Requests in Swift template are final

Fixed

  • Fixed parameters with a file type not being generated

0.6.0 - 2017-07-11 12:30:16

This includes a large rewrite with a lot more test cases so many more specs should be supported

Added

  • Integer, Double and Float enums are now generated
  • operation now has hasFileParam and isFile #27 Thanks @dangthaison91
  • spec.operationsByTag now also includes operations without tags with an empty string name #28 Thanks @dangthaison91
  • Operations now include common parameters defined in the path #29 Thanks @dangthaison91
  • Added a bunch of test specs which are now validated against
  • Added a script that generates and then compiles all test specs

Fixed

  • Removed symbols from generated filenames
  • Generate Floats as Float not Double
  • Fixed some array query parameters not joining their contents with the collectionFormat seperator (uses comma delimeted by default now if none is provided)
  • Arrays and dictionaries of enums are now encoded
  • Arrays of models are now encoded
  • Support for a default response with no schema
  • Support for [String: Any] responses
  • Simple type definitions including enums are generated properly
  • Fixed generation of operations without tags
  • Enums in responses are now generated
  • Overall more solid spec support. For example the whole fake petstore example now generates and compiles properly

Changed

  • Within templates tags is now just a list of all tag names. The previous tag dictionary which contains name and operations has been moved to operationsByTag
  • request response enum cases have been renamed

0.5.3 - 2017-05-22 11:29:33

Swift template fixes

  • fixed not building with Swift Package Manager in certain situations
  • fixed array bodies being generated as inline classes
  • fix compiler error when operations have no default response
  • escape built in Swift Foundation types like Error and Data
  • escape filenames in different way to class names

Swift template changes

  • now uses Stencil includes. Paves the way for recursive nested schemas
  • changed how operations are decoded. Paves the way for non json responses
  • added APIError.name
  • made RequestAuthorizer.authorize completed parameter escaping
  • add tag to printed request and service descriptions

Added

Added suite of tests for parsing, generating and compiling templates from a list of specs. Will improve stability and help prevent regressions. Still some work to do in this area

0.5.2 - 2017-05-16 10:22:19

Added

  • added SuccessType typealias to APIResponseValue. This lets you map from a response to successful value

Changed

  • Replaced CustomDebugStringConvertible with PrettyPrinted conformance on Models, so you can specify your own CustomDebugStringConvertible. Same string is available at model.prettyPrinted
  • Moved generated request enums and anonymous schema from APIRequest.Request to one level higher in scope

0.5.1 - 2017-05-16 05:41:22

Added

  • A request's response now has a responseResult with either .success(SuccessValue) or .failure(FailureValue). This is only generated if there is a single schema type for successes responses and a single schema type for failure responses

Changed

  • Added back successType in response context for backwards compatibility with old templates
  • Updated Alamofire to 4.4.0

Fixed

  • Fixed api name not being replaced in Decoding.swift anymore

0.5.0 - 2017-05-15 17:34:38

Added

  • APIClient.makeRequest now returns an Alamofire Request if one was created, so requests can now be cancelled
  • All operation responses are now generated, not just the successful one, meaning you get access to typed errors

Template Changes

Model
  • Properties in a model subclass initialiser will now be ordered so that all required properties come first, instead of parent and then child's properties
  • Now provides a CustomDebugStringConvertible conformance that pretty prints all nested values
APIRequest
  • Each APIRequest now has a typed Response enum that includes all it's responses in the spec. Each case has the decoded schema as an associated enum if specified
APIClient

The APIClient.makeRequest complete closure parameter has changed from DataResponse to APIResponse which:

  • replaces result value with the new response enum
  • has result error of APIError enum via antitypical/Result which has cases for:
    • unexpectedStatusCode(statusCode: Int, data: Data)
    • jsonDeserializationError(JSONUtilsError)
    • decodingError(DecodingError)
    • invalidBaseURL(String)
    • authorizationError(AuthorizationError)
    • networkError(Error)
    • unknownError(Error)
Descriptions

Models, Requests, Errors and Responses now have CustomStringConvertible and/or CustomDebugStringConvertible conformances

Fixed

  • Path parameters are no longer also encoded as url parameters in the request template

0.4.1 - 2017-05-11 18:03:27

Fixed

Improved the generation of complicated specs:

  • escape all Swift keywords:
  • escape and rename invalid characters
  • escape symbols starting with numbers
  • better support for deeply nested arrays and dictionaries
  • fixed nested enums

0.4.0 - 2017-05-10 11:10:53

Added

  • Added generated API Client in Swift template #16
    • monitoring and modification of requests via request behaviours
    • asynchronous authorization of requests
    • central place for api options
    • configurable Alamofire SessionManager
  • Models now have support for additionalProperties #15
  • Swift template is now Swift Package Manager compatible #17
  • New clean CI arguement for ignoring dot files #18

Changed

  • Names and properties in Swift template are now escaped with `` instead of appending Type,Enum ...etc

Fixed

  • Swift names and types are now escaped with a greater range of swift keywords

0.3.0 - 2017-05-04 12:59:02

Fixed

  • Operations with multiple path variables now properly generate an operationId. #11 Thanks @HSchultjan
  • Operation parameters that contain anonymous schemas (those that don't reference a definition schema but define a schema inline) are now genererated properly as nested structs within the APIRequest #13

0.2.0 - 2017-05-03 01:19:07

Added

  • Operation, Definition, Property and Parameter, now have a raw property that can be accessed from templates. This represents the raw data that was in the original spec. This lets you access any custom properties you have in your spec

Changed

  • Property and Parameter have lost their rawType and rawName properties in favour of the above, so they are now raw.type and raw.name
  • Upgraded Stencil to 0.9

0.1.0 - 2017-05-03 01:18:35

First official release