Due to changes in the priorities, this project is currently not being supported. The project is archived as of 9/17/21 and will be available in a read-only state. Please note, since archival, the project is not maintained or reviewed.
A library for generating completely customizable code from the Open API Specification (FKA Swagger) RESTful API documentation using the scripting power of Node.js.
Install oas-nodegen through npm
$ npm install oas-nodegen
This library is used to compose scripts that produce customizable output using the simple components depicted below. Most of the customization occurs in the various callbacks that the library exposes. Phase callbacks are used to modify the specification data prior to being sent to templates. The Write callbacks are used to route processed portions of the specification to their target template and location in the filesystem.
- 100% scriptable and customizable code generation.
Loader
handles loading the API specification as well as any referenced external specification.Modules
registers and loads out of the box or custom code generation modules.Templates
registers new template engines and compiles template source into functions.- The included engines are:
- Template files can be overridden by adding a template directory with overlapping template file names.
Generator
takes a "composition over inheritance" approach that allows you to register any number of modules for model decoration.Writer
handles cleaning the target directory, recursively creating directories, and writing files with content that is usually generated by templates.
Require the module before using
var nodgen = require('oas-nodegen');
var loader = nodegen.createLoader();
var modules = nodegen.createModules();
var templates = nodegen.createTemplates();
var writer = nodegen.createWriter(baseDir);
var generator = nodegen.createGenerator(config);
var utils = nodegen.Utilities;
Currently, this library contains several modules for generating Java-based producers and consumers. We'll likely add modules for other popular and emerging languages (e.g. Scala and Golang). That doesn't stop you from creating a module for your favorite language or framework now! The Java module is a good starting point for understanding the handling type translation and language features such as annotations, etc. If you think it would help the community, please contribute it back!
- load( pathOrUri ).then( function onSuccess ).fail( function onFailure );
- registerLibrary( library );
- registerModuleDirectory( [ path ] );
- registerModule( path );
- get( [ names ] );
- setDefaultOptions( defaultOptions );
- registerLibrary( library );
- registerEngineDirectory( path );
- registerEngine( pathOrObject );
- registerTemplateDirectory( path )
- compileFromSource( engineName, source, options );
- compileFromFile( templateFile, options );
- setLeadingFileComments( comments );
- setTrailingFileComments( comments );
- preventDeletionOf( pathNames... );
- clean();
- write( [ path ], filename, content );
- configure( config );
- addIgnoredOperations( operationNames );
- addIgnoredParameters( parameterNames );
- setModules( parameters );
- use( moduleNamesOrObjects );
- emit( phase, event, data );
- on( phase, event, data );
- onPrepare( event, listener );
- onDecorate( event, listener );
- onFinalize( event, listener );
- write( event, data );
- onWrite( event, listener );
- process( spec, references );
- groupOperation( operation );
- groupSort( group );
- operationSort( operation );
- getSuccessResponse( operation );
- translate( obj, spec, references );
- resolveReference( obj, spec, references );
- getReferenceName( $ref );
- extractModelName( $ref );
- getMimeType( array );
- sortKeys( object );
- capitalize( string );
- uncapitalize( string );
- random( low, high );
The modules below are designed to enrich the API specification with information to be used by templates. The best approach is to try to keep templates as generic and simple as possible and let the addition of modules change the generated output. For example, most of the Java-based modules below deal with annotations. The provided templates simply render the list of annotations and the modules handle the heavy lifting.
-
Operations:
fullPath
- Concatenated base path and operation pathaccepts
- Most preferred mime type for the Accepts headercontentType
- Most preferred mime type for the ContentType headeroperationId
- If null, set based on HTTP method and path (however, its recommended to explicitly specify operationId in the specification)resolvedConsumes
- Resolved consumes mimetypes for this operation or base specificationresolvedProduces
- Resolved produces mimetypes for this operation or base specification- Response helpers:
successResponse
- Property that reflects the 200 or 201 responsehasReturn
- Boolean flag that denotes of a response body is returned
parameters
- Updates the parameters array for filter out ignored parametersisQuery
- Boolean flag that denotes if the query string parameters comprise are all optional (e.g. collection query)- Parameter grouping by type:
bodyParam
- The body parameter, if applicablepathParams
- List of path parametersqueryParams
- List of query parametersheaderParams
- List of header parametersformParams
- List of form parametersrequiredParams
- List of all required parameters
-
Models:
name
- The model name pulled from the definitions map keyreferences
- The list of models that this model referencesreferencedBy
- The list of models this model is referenced byrecursiveReferencedBy
- The recursive list of models this model is referenced byrequired
- Updated with a materialized list from other entities refereced by $allOfproperties
- Updated with a materialized map from other entities refereced by $allOfvars
- The model's properties represented as a list instead of a map- Materialized information from other models that reference this model
allReferences
- A recursive list of models referenced by this modelallProperties
- Allproperties
from this model and models that reference this modelallRequired
- Allrequired
property names from this model and models that reference this modelallVars
- Allvars
from this model and models that reference this model
-
Properties:
name
- The property name pull from the properties map keyrequired
- Boolean flag indicated if the property is required - pulled from the model's required list
- General:
annotations
:- List of annotations for operations, parameters, models, and properties
- Added by
generator.addAnnotation(annotation, operation|parameter|model|property);
imports
- List of imports for resources and models
- Added by
generator.addImport(className, resource|model);
- Generator utility methods:
addKnownImports(imports...)
- Adds a known import that can be added via a simple class namefindImport(simpleName)
- Finds an import using its simple name
classname
- Java-friendly class name for resources and models- Type translation methods:
translateType(schema, resource|model, spec, references)
- Converts a schema into a Java typeaddTypeTranslator(function(schema, resource|model))
- Adds a hook used bytranslateType
to allow for custom typesoverrideModelPackage($ref, model)
- Hook method that can be replaced in order to override model package name (returningnull
defaults toconfig.modelPackage
)variableName(value)
- Produces a Java-friendly variable name from a string value
- Other utility / helper methods:
escapeJavaString(value)
- Converts a value into a Java string literaljoinStrings(values)
- Escapes and joins a set of values - useful for declaring arrays
- Operations:
methodName
- Java-friendle method namereturnType
- The class name of the return typereturnDescription
- The description from the success response
- Parameters:
varname
- Java-friendly variable namedataType
- The data type of the parameter - can be a generic collectionitemType
- The item type if the data type is a collectionmethod
- The method to use to set the parameter from a client's perspective
- Models:
allImports
- Materialized list of imports from the model and property scopesparent
- The class name of the parent which is based on the first reference under $allOfserialVersionUID
- The long value to use for serialVersionUID for implementing Serializable
- Properties:
varname
- Java-friendly variable namedataType
- The data type of the property - can be a generic collectiongetter
- The getter accessor method namesetter
- The setter accessor method namedefaultValue
- The property's default value expression
- Properties:
dataType
- Uses java.util.Optional* types when fields are not required
- Replaces Integer, Long, and Double with OptionalInt, OptionalLong, and OptionalDouble respectively
- Wraps other classes with Optional
empty
- The expression to create an empty optional instanceassign
- The expression to convert and assign a value to an optional instance
- Parameters & Properties:
- Adds @Min/DecimalMin, @Max/DecimalMax, @Size, @Pattern, @Valid and @NotNull
- Models:
- Adds @XmlRootElement, @XmlType, @XmlAccessorType, @XmlSeeAlso
- Properties:
- Adds @XmlElementWrapper, @XmlElement based on defined
xml
objects
- Adds @XmlElementWrapper, @XmlElement based on defined
- Resources:
- Adds @Path, @Consumes, @Produces
- Operations:
- Adds @Path, @Consumes, @Produces
- Adds @GET, @POST, @PUT, @DELETE, @HttpMethod("PATCH")
- Parameters:
- Adds @PathParam, @QueryParam, @HeaderParam, @FormParam, @DefaultValue
To try an example, use the commands below to build and run a Java/Spring Boot API (assumes MongoDB is running and listening on 27017 - authentication disabled):
$ git clone https://github.com/capitalone/oas-nodegen-example.git
$ cd oas-nodegen-example
$ gradle bootRun
To run the test suite, first install the dependencies, then run npm test
:
$ npm install
$ npm test
We welcome your interest in Capital One’s Open Source Projects (the “Project”). Any Contributor to the project must accept and sign a CLA indicating agreement to the license terms. Except for the license granted in this CLA to Capital One and to recipients of software distributed by Capital One, you reserve all right, title, and interest in and to your contributions; this CLA does not impact your rights to use your own contributions for any other purpose.
This project adheres to the Open Source Code of Conduct. By participating, you are expected to honor this code.