Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Typescript+Axios: Separate model and api classfiles and package #2005

Merged
merged 23 commits into from
Mar 5, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
62e46f6
Typescript 3.2
mvanniekerkdvt Jan 25, 2019
6064f57
Typescript spread operator
mvanniekerkdvt Jan 25, 2019
c5ef723
Add vendor extension to the operation
mvanniekerkdvt Jan 25, 2019
8a32553
Remove url.URLSearchParams
mvanniekerkdvt Jan 25, 2019
dce5438
Generate form data in API
mvanniekerkdvt Jan 25, 2019
b45432b
Make axios scripts executable
mvanniekerkdvt Jan 28, 2019
6452cfe
Reran generator
mvanniekerkdvt Jan 28, 2019
b661748
Generate sample code
mvanniekerkdvt Jan 28, 2019
d952ffd
Codegen having the model and api extra flag
mvanniekerkdvt Jan 28, 2019
9818ee8
Revert to 2.4 Typescript
mvanniekerkdvt Jan 28, 2019
9e33519
COLLECTION_FORMAT.{{collectionFormat}} everywhere for consistency
mvanniekerkdvt Jan 28, 2019
3ba25dc
Consistency on the CollectionFormats, comment on the vendor extension
mvanniekerkdvt Jan 28, 2019
e771a74
Merge branch 'bugfix-multipart-form-data' into feature-separate-model…
mvanniekerkdvt Jan 28, 2019
b90daa0
Throw exception if api and model packages are not given
mvanniekerkdvt Jan 28, 2019
c948769
Templates splitting api and models
mvanniekerkdvt Jan 28, 2019
c0f23fe
Post process the operations in the the process
mvanniekerkdvt Jan 28, 2019
7a75648
Beginning to get the axios tests up
mvanniekerkdvt Jan 28, 2019
fa79b64
Ensure-up-to-date doesnt include TS/Axios tests
mvanniekerkdvt Jan 28, 2019
fd5f7dc
Docs update for Typescript/Axios
mvanniekerkdvt Jan 28, 2019
c099c26
Merge branch 'master' into feature-separate-model-and-api
mvanniekerkdvt Feb 26, 2019
ed31f45
Merge master
mvanniekerkdvt Feb 26, 2019
d873641
Api tests re-run
mvanniekerkdvt Feb 26, 2019
098971d
Add windows bat file
mvanniekerkdvt Feb 26, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions bin/typescript-axios-petstore-all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@

./bin/typescript-axios-petstore-target-es6.sh
./bin/typescript-axios-petstore-with-npm-version.sh
./bin/typescript-axios-petstore-with-npm-version-and-separate-models-and-api.sh
./bin/typescript-axios-petstore-interfaces.sh
./bin/typescript-axios-petstore.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"npmName": "@swagger/typescript-axios-petstore",
"npmVersion": "1.0.0",
"npmRepository": "https://skimdb.npmjs.com/registry",
"snapshot": false,
"withSeparateModelsAndApi": true,
"modelPackage": "model.some.levels.deep",
"apiPackage": "api.another.level"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/bin/sh

SCRIPT="$0"
echo "# START SCRIPT: $SCRIPT"

while [ -h "$SCRIPT" ] ; do
mvniekerk marked this conversation as resolved.
Show resolved Hide resolved
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/openapi-generator-cli/target/openapi-generator-cli.jar"

if [ ! -f "$executable" ]
then
mvn -B 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"
ags="generate -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g typescript-axios -c bin/typescript-axios-petstore-with-npm-version-and-separate-models-and-api.json -o samples/client/petstore/typescript-axios/builds/with-npm-version-and-separate-models-and-api $@"

java $JAVA_OPTS -jar $executable $ags
1 change: 1 addition & 0 deletions bin/utils/ensure-up-to-date
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ declare -a scripts=("./bin/openapi3/ruby-client-petstore.sh"
"./bin/php-ze-ph-petstore-server.sh"
"./bin/openapi3/php-petstore.sh"
"./bin/typescript-angular-petstore-all.sh"
"./bin/typescript-axios-petstore-all.sh"
"./bin/typescript-fetch-petstore-all.sh"
"./bin/typescript-node-petstore-all.sh"
"./bin/typescript-inversify-petstore.sh"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
@ECHO OFF

set executable=.\modules\openapi-generator-cli\target\openapi-generator-cli.jar

If Not Exist %executable% (
mvn clean package
)

REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore.yaml -g typescript-axios -c bin\typescript-axios-petstore-with-npm-version-and-separate-models-and-api.json -o samples\client\petstore\typescript-axios\builds\with-npm-version-and-separate-models-and-api

java %JAVA_OPTS% -jar %executable% %ags%
1 change: 1 addition & 0 deletions docs/generators/typescript-axios.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ sidebar_label: typescript-axios
|npmRepository|Use this property to set an url your private npmRepo in the package.json| |null|
|snapshot|When setting this property to true the version will be suffixed with -SNAPSHOT.yyyyMMddHHmm| |false|
|withInterfaces|Setting this property to true will generate interfaces next to the default class implementations.| |false|
|withSeparateModelsAndApi|Put the model and api in separate folders and in separate classes| |false|
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.parser.util.SchemaTypeUtil;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.CliOption;
import org.openapitools.codegen.CodegenModel;
import org.openapitools.codegen.CodegenOperation;
Expand All @@ -37,11 +38,14 @@ public class TypeScriptAxiosClientCodegen extends AbstractTypeScriptClientCodege
public static final String NPM_REPOSITORY = "npmRepository";
public static final String SNAPSHOT = "snapshot";
public static final String WITH_INTERFACES = "withInterfaces";
public static final String SEPARATE_MODELS_AND_API = "withSeparateModelsAndApi";

protected String npmName = null;
protected String npmVersion = "1.0.0";
protected String npmRepository = null;

private String tsModelPackage = "";

public TypeScriptAxiosClientCodegen() {
super();

Expand All @@ -57,6 +61,7 @@ public TypeScriptAxiosClientCodegen() {
this.cliOptions.add(new CliOption(NPM_REPOSITORY, "Use this property to set an url your private npmRepo in the package.json"));
this.cliOptions.add(new CliOption(SNAPSHOT, "When setting this property to true the version will be suffixed with -SNAPSHOT.yyyyMMddHHmm", SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.FALSE.toString()));
this.cliOptions.add(new CliOption(WITH_INTERFACES, "Setting this property to true will generate interfaces next to the default class implementations.", SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.FALSE.toString()));
this.cliOptions.add(new CliOption(SEPARATE_MODELS_AND_API, "Put the model and api in separate folders and in separate classes", SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.FALSE.toString()));
}

@Override
Expand Down Expand Up @@ -93,19 +98,57 @@ public void setNpmRepository(String npmRepository) {
this.npmRepository = npmRepository;
}

private static String getRelativeToRoot(String path) {
StringBuilder sb = new StringBuilder();
int slashCount = path.split("/").length;
if (slashCount == 0) {
sb.append("./");
} else {
for (int i = 0; i < slashCount; ++i) {
sb.append("../");
}
}
return sb.toString();
}

@Override
public void processOpts() {
super.processOpts();
tsModelPackage = modelPackage.replaceAll("\\.", "/");
String tsApiPackage = apiPackage.replaceAll("\\.", "/");

String modelRelativeToRoot = getRelativeToRoot(tsModelPackage);
String apiRelativeToRoot = getRelativeToRoot(tsApiPackage);

additionalProperties.put("tsModelPackage", tsModelPackage);
additionalProperties.put("tsApiPackage", tsApiPackage);
additionalProperties.put("apiRelativeToRoot", apiRelativeToRoot);
additionalProperties.put("modelRelativeToRoot", modelRelativeToRoot);

supportingFiles.add(new SupportingFile("index.mustache", "", "index.ts"));
supportingFiles.add(new SupportingFile("baseApi.mustache", "", "base.ts"));
supportingFiles.add(new SupportingFile("api.mustache", "", "api.ts"));
supportingFiles.add(new SupportingFile("configuration.mustache", "", "configuration.ts"));
supportingFiles.add(new SupportingFile("custom.d.mustache", "", "custom.d.ts"));
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
supportingFiles.add(new SupportingFile("gitignore", "", ".gitignore"));

boolean separateModelsAndApi = (boolean)additionalProperties.getOrDefault(SEPARATE_MODELS_AND_API, false);

if (separateModelsAndApi) {
modelTemplateFiles.put("model.mustache", ".ts");
apiTemplateFiles.put("apiInner.mustache", ".ts");
supportingFiles.add(new SupportingFile("modelIndex.mustache", tsModelPackage, "index.ts"));
}

if (additionalProperties.containsKey(NPM_NAME)) {
addNpmPackageGeneration();
}

boolean emptyModelOrApi = separateModelsAndApi && StringUtils.isAnyBlank(modelPackage, apiPackage);
if (emptyModelOrApi) {
throw new RuntimeException("apiPackage and modelPackage must be defined");
}
}

@Override
Expand All @@ -129,8 +172,8 @@ public String getTypeDeclaration(Schema p) {
@Override
public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> objs, List<Object> allModels) {
objs = super.postProcessOperationsWithModels(objs, allModels);
Map<String, Object> vals = (Map<String, Object>) objs.get("operations");
List<CodegenOperation> operations = (List<CodegenOperation>) vals.get("operation");
Map<String, Object> vals = (Map<String, Object>) objs.getOrDefault("operations", new HashMap<>());
List<CodegenOperation> operations = (List<CodegenOperation>) vals.getOrDefault("operation", new ArrayList<>());
/*
Filter all the operations that are multipart/form-data operations and set the vendor extension flag
'multipartFormData' for the template to work with.
Expand All @@ -148,6 +191,37 @@ protected void addAdditionPropertiesToCodeGenModel(CodegenModel codegenModel, Sc
addImport(codegenModel, codegenModel.additionalPropertiesType);
}

@Override
@SuppressWarnings("unchecked")
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
Map<String, Object> ret = super.postProcessModels(objs);
// Deduce the model file name in kebab case
List<Map<String, Object>> models = (List<Map<String, Object>>) ret.get("models");
for (Map<String, Object> m : models) {
CodegenModel model = (CodegenModel) m.get("model");
model.classFilename = model.classname.replaceAll("([a-z0-9])([A-Z])", "$1-$2").toLowerCase(Locale.ROOT);
}
// Apply the model file name to the imports as well
for (Map<String, String> m : (List<Map<String, String>>) ret.get("imports")) {
String javaImport = m.get("import").substring(modelPackage.length() + 1);
String tsImport = tsModelPackage + "/" + javaImport;
m.put("tsImport", tsImport);
m.put("class", javaImport);
m.put("filename", javaImport.replaceAll("([a-z0-9])([A-Z])", "$1-$2").toLowerCase(Locale.ROOT));
}
return ret;
}

@Override
public String toModelFilename(String name) {
return super.toModelFilename(name).replaceAll("([a-z0-9])([A-Z])", "$1-$2").toLowerCase(Locale.ROOT);
}

@Override
public String toApiFilename(String name) {
return super.toApiFilename(name).replaceAll("([a-z0-9])([A-Z])", "$1-$2").toLowerCase(Locale.ROOT);
}

private void addNpmPackageGeneration() {
if (additionalProperties.containsKey(NPM_NAME)) {
this.setNpmName(additionalProperties.get(NPM_NAME).toString());
Expand Down
Loading