Skip to content

Commit

Permalink
generator for dart jaguar
Browse files Browse the repository at this point in the history
  • Loading branch information
jaumard authored and wing328 committed Sep 8, 2018
1 parent 1ead8bc commit a1e50a6
Show file tree
Hide file tree
Showing 165 changed files with 19,485 additions and 4 deletions.
43 changes: 43 additions & 0 deletions bin/dart-jaguar-petstore.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/bin/sh

SCRIPT="$0"

while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done

if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi

executable="./modules/swagger-codegen-cli/target/swagger-codegen-cli.jar"

if [ ! -f "$executable" ]
then
mvn clean package
fi

# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"

# Generate client
ags="$@ generate -t modules/swagger-codegen/src/main/resources/dart-jaguar -i modules/swagger-codegen/src/test/resources/2_0/petstore.yaml -l dart-jaguar -o samples/client/petstore/dart-jaguar/swagger -DhideGenerationTimestamp=true"
java $JAVA_OPTS -jar $executable $ags

# Generate non-browserClient and put it to the flutter sample app
ags="$@ generate -t modules/swagger-codegen/src/main/resources/dart-jaguar -i modules/swagger-codegen/src/test/resources/2_0/petstore.yaml -l dart-jaguar -o samples/client/petstore/dart-jaguar/flutter_petstore/swagger -DhideGenerationTimestamp=true"
java $JAVA_OPTS -jar $executable $ags

# There is a proposal to allow importing different libraries depending on the environment:
# https://github.com/munificent/dep-interface-libraries
# When this is implemented there will only be one library.

# The current petstore test will then work for both: the browser library and the vm library.

12 changes: 12 additions & 0 deletions bin/windows/dart-client-petstore.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
set executable=.\modules\swagger-codegen-cli\target\swagger-codegen-cli.jar

If Not Exist %executable% (
mvn clean package
)

REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M -DloggerPath=conf/log4j.properties
set ags=generate -i modules\swagger-codegen\src\test\resources\2_0\petstore.yaml -l dart-jaguar -o samples\client\petstore\dart-jaguar\swagger -DhideGenerationTimestamp=true -DbrowserClient=false
java %JAVA_OPTS% -jar %executable% %ags%

set ags=generate -i modules\swagger-codegen\src\test\resources\2_0\petstore.yaml -l dart-jaguar -o samples\client\petstore\dart-jaguar\flutter_petstore\swagger -DhideGenerationTimestamp=true
java %JAVA_OPTS% -jar %executable% %ags%
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
package io.swagger.codegen.languages;

import com.samskivert.mustache.Mustache;
import com.samskivert.mustache.Template;
import io.swagger.codegen.*;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.MapProperty;
import io.swagger.models.properties.Property;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class DartJaguarClientCodegen extends DartClientCodegen {
private static Set<String> modelToIgnore = new HashSet<>();
static {
modelToIgnore.add("datetime");
modelToIgnore.add("list");
modelToIgnore.add("map");
modelToIgnore.add("file");
}
public DartJaguarClientCodegen() {
super();
browserClient = false;
outputFolder = "generated-code/dart-jaguar";
embeddedTemplateDir = templateDir = "dart-jaguar";
}

@Override
public String getName() {
return "dart-jaguar";
}

@Override
public String getHelp() {
return "Generates a Dart Jaguar client library.";
}

@Override
public String toDefaultValue(Property p) {
if (p instanceof MapProperty) {
return "const {}";
} else if (p instanceof ArrayProperty) {
return "const []";
}
return super.toDefaultValue(p);
}

@Override
public void processOpts() {
if (additionalProperties.containsKey(PUB_NAME)) {
this.setPubName((String) additionalProperties.get(PUB_NAME));
} else {
//not set, use to be passed to template
additionalProperties.put(PUB_NAME, pubName);
}

if (additionalProperties.containsKey(PUB_VERSION)) {
this.setPubVersion((String) additionalProperties.get(PUB_VERSION));
} else {
//not set, use to be passed to template
additionalProperties.put(PUB_VERSION, pubVersion);
}

if (additionalProperties.containsKey(PUB_DESCRIPTION)) {
this.setPubDescription((String) additionalProperties.get(PUB_DESCRIPTION));
} else {
//not set, use to be passed to template
additionalProperties.put(PUB_DESCRIPTION, pubDescription);
}

if (additionalProperties.containsKey(USE_ENUM_EXTENSION)) {
this.setUseEnumExtension(convertPropertyToBooleanAndWriteBack(USE_ENUM_EXTENSION));
} else {
// Not set, use to be passed to template.
additionalProperties.put(USE_ENUM_EXTENSION, useEnumExtension);
}

if (additionalProperties.containsKey(CodegenConstants.SOURCE_FOLDER)) {
this.setSourceFolder((String) additionalProperties.get(CodegenConstants.SOURCE_FOLDER));
}

// make api and model doc path available in mustache template
additionalProperties.put("apiDocPath", apiDocPath);
additionalProperties.put("modelDocPath", modelDocPath);

final String libFolder = sourceFolder + File.separator + "lib";
supportingFiles.add(new SupportingFile("pubspec.mustache", "", "pubspec.yaml"));
supportingFiles.add(new SupportingFile("analysis_options.mustache", "", ".analysis_options"));
supportingFiles.add(new SupportingFile("apilib.mustache", libFolder, "api.dart"));

supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
supportingFiles.add(new SupportingFile("gitignore.mustache", "", ".gitignore"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
}


@Override
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
objs = super.postProcessModels(objs);
List<Object> models = (List<Object>) objs.get("models");
for (Object _mo : models) {
Map<String, Object> mo = (Map<String, Object>) _mo;
Set<String> modelImports = new HashSet<>();
CodegenModel cm = (CodegenModel) mo.get("model");
for (String modelImport : cm.imports) {
if(!modelToIgnore.contains(modelImport.toLowerCase())) {
modelImports.add(underscore(modelImport));
}
}
cm.imports = modelImports;
cm.vendorExtensions.put("hasVars", cm.vars.size() > 0);
}
//objs.put("modelImports", modelImports);
return objs;
}

@Override
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
objs = super.postProcessOperations(objs);
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
List<CodegenOperation> operationList = (List<CodegenOperation>) operations.get("operation");

Set<String> modelImports = new HashSet<>();

for (CodegenOperation op : operationList) {
op.httpMethod = StringUtils.capitalize(op.httpMethod.toLowerCase());
boolean isJson = true; //default to JSON
boolean isForm = false;
boolean isMultipart = false;
if(op.consumes != null) {
for (Map<String, String> consume : op.consumes) {
if (consume.containsKey("mediaType")) {
String type = consume.get("mediaType");
isJson = type.equalsIgnoreCase("application/json");
isForm = type.equalsIgnoreCase("application/x-www-form-urlencoded");
isMultipart = type.equalsIgnoreCase("multipart/form-data");
break;
}
}
}

op.vendorExtensions.put("isJson", isJson);
op.vendorExtensions.put("isForm", isForm);
op.vendorExtensions.put("isMultipart", isMultipart);

Set<String> imports = new HashSet<>();
for (String item : op.imports) {
if(!modelToIgnore.contains(item.toLowerCase())) {
imports.add(underscore(item));
}
}
modelImports.addAll(imports);
op.imports = imports;

String[] items = op.path.split("/", -1);
String jaguarPath = "";

for (int i = 0; i < items.length; ++i) {
if (items[i].matches("^\\{(.*)\\}$")) { // wrap in {}
jaguarPath = jaguarPath + ":" + items[i].replace("{", "").replace("}", "");
} else {
jaguarPath = jaguarPath + items[i];
}

if (i != items.length -1) {
jaguarPath = jaguarPath + "/";
}
}

op.path = jaguarPath;
}

objs.put("modelImports", modelImports);

return objs;
}
}
142 changes: 142 additions & 0 deletions modules/swagger-codegen/src/main/resources/dart-jaguar/README.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
# {{pubName}}
{{#appDescription}}
{{{appDescription}}}
{{/appDescription}}

This Dart package is automatically generated by the [Swagger Codegen](https://github.com/swagger-api/swagger-codegen) project:

- API version: {{appVersion}}
{{#artifactVersion}}
- Package version: {{artifactVersion}}
{{/artifactVersion}}
{{^hideGenerationTimestamp}}
- Build date: {{generatedDate}}
{{/hideGenerationTimestamp}}
- Build package: {{generatorClass}}
{{#infoUrl}}
For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}})
{{/infoUrl}}

## Requirements

Dart 2 or later OR Flutter 0.7.0 or later.

Once your code is generated, you need to run the build_runner command to let Jaguar implement your API:

```sh
flutter packages pub run build_runner build
or
pub run build_runner build
```

## Installation & Usage

### Github
If this Dart package is published to Github, please include the following in pubspec.yaml
```
name: {{pubName}}
version: {{pubVersion}}
description: {{pubDescription}}
dependencies:
{{pubName}}:
git: https://github.com/{{gitUserId}}/{{gitRepoId}}.git
version: 'any'
```

### Local
To use the package in your local drive, please include the following in pubspec.yaml
```
dependencies:
{{pubName}}:
path: /path/to/{{pubName}}
```

## Tests

TODO

## Getting Started

Please follow the [installation procedure](#installation--usage) and then run the following:

```dart
import 'package:{{pubName}}/api.dart';
{{#apiInfo}}{{#apis}}{{#-first}}{{#operations}}{{#operation}}{{#-first}}
{{#hasAuthMethods}}
{{#authMethods}}
{{#isBasic}}
// TODO Configure HTTP basic authorization: {{{name}}}
//{{pubName}}.api.Configuration.username = 'YOUR_USERNAME';
//{{pubName}}.api.Configuration.password = 'YOUR_PASSWORD';
{{/isBasic}}
{{#isApiKey}}
// TODO Configure API key authorization: {{{name}}}
//{{pubName}}.api.Configuration.apiKey{'{{{keyParamName}}}'} = 'YOUR_API_KEY';
// uncomment below to setup prefix (e.g. Bearer) for API key, if needed
//{{pubName}}.api.Configuration.apiKeyPrefix{'{{{keyParamName}}}'} = "Bearer";
{{/isApiKey}}
{{#isOAuth}}
// TODO Configure OAuth2 access token for authorization: {{{name}}}
//{{pubName}}.api.Configuration.accessToken = 'YOUR_ACCESS_TOKEN';
{{/isOAuth}}
{{/authMethods}}
{{/hasAuthMethods}}

final swaggerGen = SwaggerGen();
var api_instance = swaggerGen.get{{classname}}();
{{#allParams}}
var {{paramName}} = {{#isListContainer}}[{{/isListContainer}}{{#isBodyParam}}new {{dataType}}(){{/isBodyParam}}{{^isBodyParam}}{{{example}}}{{/isBodyParam}}{{#isListContainer}}]{{/isListContainer}}; // {{{dataType}}} | {{{description}}}
{{/allParams}}

try {
{{#returnType}}var result = {{/returnType}}api_instance.{{{operationId}}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
{{#returnType}}
print(result);
{{/returnType}}
} catch (e) {
print("Exception when calling {{classname}}->{{operationId}}: $e\n");
}
{{/-first}}{{/operation}}{{/operations}}{{/-first}}{{/apis}}{{/apiInfo}}
```

## Documentation for API Endpoints

All URIs are relative to *{{basePath}}*

Class | Method | HTTP request | Description
------------ | ------------- | ------------- | -------------
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}*{{classname}}* | [**{{operationId}}**]({{apiDocPath}}/{{classname}}.md#{{operationIdLowerCase}}) | **{{httpMethod}}** {{path}} | {{#summary}}{{summary}}{{/summary}}
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}

## Documentation For Models

{{#models}}{{#model}} - [{{{classname}}}]({{modelDocPath}}/{{{classname}}}.md)
{{/model}}{{/models}}

## Documentation For Authorization

{{^authMethods}} All endpoints do not require authorization.
{{/authMethods}}{{#authMethods}}{{#last}} Authentication schemes defined for the API:{{/last}}{{/authMethods}}
{{#authMethods}}## {{{name}}}

{{#isApiKey}}- **Type**: API key
- **API key parameter name**: {{{keyParamName}}}
- **Location**: {{#isKeyInQuery}}URL query string{{/isKeyInQuery}}{{#isKeyInHeader}}HTTP header{{/isKeyInHeader}}
{{/isApiKey}}
{{#isBasic}}- **Type**: HTTP basic authentication
{{/isBasic}}
{{#isOAuth}}- **Type**: OAuth
- **Flow**: {{{flow}}}
- **Authorization URL**: {{{authorizationUrl}}}
- **Scopes**: {{^scopes}}N/A{{/scopes}}
{{#scopes}} - **{{{scope}}}**: {{{description}}}
{{/scopes}}
{{/isOAuth}}

{{/authMethods}}

## Author

{{#apiInfo}}{{#apis}}{{^hasMore}}{{infoEmail}}
{{/hasMore}}{{/apis}}{{/apiInfo}}

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
analyzer:
strong-mode: true
Loading

0 comments on commit a1e50a6

Please sign in to comment.