Skip to content

Javascript Flow typed #8101

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

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
34 changes: 34 additions & 0 deletions bin/javascript-flowtyped-petstore.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/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"
ags="$@ generate -t modules/swagger-codegen/src/main/resources/Javascript-Flowtyped \
-i modules/swagger-codegen/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml \
-l javascript-flowtyped \
-o samples/client/petstore/javascript-flowtyped"

java $JAVA_OPTS -jar $executable $ags
1 change: 1 addition & 0 deletions bin/javascript-petstore-all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
./bin/javascript-promise-petstore.sh
./bin/javascript-es6-petstore.sh
./bin/javascript-promise-es6-petstore.sh
./bin/javascript-flowtyped-petstore.sh
2 changes: 1 addition & 1 deletion docker-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pattern="@Command(name = \"$1\""
if expr "x$1" : 'x[a-z][a-z-]*$' > /dev/null && fgrep -qe "$pattern" "$cmdsrc"/*.java || expr "$1" = 'help' > /dev/null; then
# If ${GEN_DIR} has been mapped elsewhere from default, and that location has not been built
if [[ ! -f "${codegen}" ]]; then
(cd "${GEN_DIR}" && exec mvn -am -pl "modules/swagger-codegen-cli" -Duser.home=$(dirname MAVEN_CONFIG) package)
(cd "${GEN_DIR}" && exec mvn -am -pl "modules/swagger-codegen-cli" -Duser.home=$(dirname $MAVEN_CONFIG) package)
fi
command=$1
shift
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,260 @@
package io.swagger.codegen.languages;

import io.swagger.codegen.*;
import io.swagger.models.Info;
import io.swagger.models.License;
import io.swagger.models.ModelImpl;
import io.swagger.models.Swagger;
import io.swagger.models.properties.*;
import org.apache.commons.lang3.StringUtils;

import java.text.SimpleDateFormat;
import java.util.*;

public class JavascriptFlowtypedCodegen extends AbstractTypeScriptClientCodegen {
private static final SimpleDateFormat SNAPSHOT_SUFFIX_FORMAT = new SimpleDateFormat("yyyyMMddHHmm");

public static final String NPM_NAME = "npmName";
public static final String NPM_VERSION = "npmVersion";
public static final String NPM_REPOSITORY = "npmRepository";
public static final String SNAPSHOT = "snapshot";

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

public JavascriptFlowtypedCodegen() {
super();

// clear import mapping (from default generator) as TS does not use it
// at the moment
importMapping.clear();

setReservedWordsLowerCase(Arrays.asList(
// local variable names used in API methods (endpoints)
"varLocalPath", "queryParameters", "headerParams", "formParams", "useFormData", "varLocalDeferred",
"requestOptions",
// Typescript reserved words
"abstract", "arguments", "boolean", "break", "byte",
"case", "catch", "char", "class", "const",
"continue", "debugger", "default", "delete", "do",
"double", "else", "enum", "eval", "export",
"extends", "false", "final", "finally", "float",
"for", "function", "goto", "if", "implements",
"import", "in", "instanceof", "int", "interface",
"let", "long", "native", "new", "null",
"package", "private", "protected", "public", "return",
"short", "static", "super", "switch", "synchronized",
"this", "throw", "throws", "transient", "true",
"try", "typeof", "var", "void", "volatile",
"while", "with", "yield",
"Array", "Date", "eval", "function", "hasOwnProperty",
"Infinity", "isFinite", "isNaN", "isPrototypeOf",
"Math", "NaN", "Number", "Object",
"prototype", "String", "toString", "undefined", "valueOf"));

languageSpecificPrimitives = new HashSet<String>(
Arrays.asList("string", "boolean", "number", "Array", "Object", "Date", "File", "Blob")
);

instantiationTypes.put("array", "Array");
instantiationTypes.put("list", "Array");
instantiationTypes.put("map", "Object");
typeMapping.clear();
typeMapping.put("array", "Array");
typeMapping.put("map", "Object");
typeMapping.put("List", "Array");
typeMapping.put("boolean", "boolean");
typeMapping.put("string", "string");
typeMapping.put("int", "number");
typeMapping.put("float", "number");
typeMapping.put("number", "number");
typeMapping.put("DateTime", "Date");
typeMapping.put("date", "Date");
typeMapping.put("long", "number");
typeMapping.put("short", "number");
typeMapping.put("char", "string");
typeMapping.put("double", "number");
typeMapping.put("object", "Object");
typeMapping.put("integer", "number");
// binary not supported in JavaScript client right now, using String as a workaround
typeMapping.put("binary", "string");
typeMapping.put("ByteArray", "string");
typeMapping.put("UUID", "string");

defaultIncludes = new HashSet<String>(languageSpecificPrimitives);
outputFolder = "generated-code/javascript-flowtyped";
embeddedTemplateDir = templateDir = "Javascript-Flowtyped";

this.cliOptions.add(new CliOption(NPM_NAME, "The name under which you want to publish generated npm package"));
this.cliOptions.add(new CliOption(NPM_VERSION, "The version of your npm package"));
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", BooleanProperty.TYPE).defaultValue(Boolean.FALSE.toString()));

}

@Override
public CodegenType getTag() {
return CodegenType.CLIENT;
}

@Override
protected void addAdditionPropertiesToCodeGenModel(CodegenModel codegenModel, ModelImpl swaggerModel) {
codegenModel.additionalPropertiesType = getTypeDeclaration(swaggerModel.getAdditionalProperties());
addImport(codegenModel, codegenModel.additionalPropertiesType);
}

@Override
public void processOpts() {
super.processOpts();
supportingFiles.add(new SupportingFile("index.mustache", "src", "index.js"));
supportingFiles.add(new SupportingFile("api.mustache", "src", "api.js"));
supportingFiles.add(new SupportingFile("configuration.mustache", "src", "configuration.js"));
supportingFiles.add(new SupportingFile("gitignore", "", ".gitignore"));

addNpmPackageGeneration();
}

@Override
public String getTypeDeclaration(Property p) {
Property inner;
if(p instanceof ArrayProperty) {
ArrayProperty ap = (ArrayProperty)p;
inner = ap.getItems();
return this.getSwaggerType(p) + "<" + this.getTypeDeclaration(inner) + ">";
} else if(p instanceof MapProperty) {
MapProperty mp = (MapProperty)p;
inner = mp.getAdditionalProperties();
return "{ [key: string]: " + this.getTypeDeclaration(inner) + "; }";
} else if(p instanceof FileProperty || p instanceof ObjectProperty) {
return "any";
} else {
return super.getTypeDeclaration(p);
}
}

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

if (additionalProperties.containsKey(NPM_VERSION)) {
this.setNpmVersion(additionalProperties.get(NPM_VERSION).toString());
}

if (additionalProperties.containsKey(SNAPSHOT) && Boolean.valueOf(additionalProperties.get(SNAPSHOT).toString())) {
this.setNpmVersion(npmVersion + "-SNAPSHOT." + SNAPSHOT_SUFFIX_FORMAT.format(new Date()));
}
additionalProperties.put(NPM_VERSION, npmVersion);

if (additionalProperties.containsKey(NPM_REPOSITORY)) {
this.setNpmRepository(additionalProperties.get(NPM_REPOSITORY).toString());
}

//Files for building our lib
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("package.mustache", "", "package.json"));
supportingFiles.add(new SupportingFile("flowconfig.mustache", "", ".flowconfig"));
supportingFiles.add(new SupportingFile("babelrc", "", ".babelrc"));
}

@Override
public void preprocessSwagger(Swagger swagger) {
if (swagger.getInfo() != null) {
Info info = swagger.getInfo();
if (StringUtils.isBlank(npmName) && info.getTitle() != null) {
// when projectName is not specified, generate it from info.title
npmName = sanitizeName(dashize(info.getTitle()));
}
if (StringUtils.isBlank(npmVersion)) {
// when projectVersion is not specified, use info.version
npmVersion = escapeUnsafeCharacters(escapeQuotationMark(info.getVersion()));
}
}

// default values
if (StringUtils.isBlank(npmName)) {
npmName = "swagger-js-client";
}
if (StringUtils.isBlank(npmVersion)) {
npmVersion = "1.0.0";
}

additionalProperties.put(NPM_NAME, npmName);
additionalProperties.put(NPM_VERSION, npmVersion);
additionalProperties.put(CodegenConstants.API_PACKAGE, apiPackage);
}

@Override
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
// process enum in models
List<Object> models = (List<Object>) postProcessModelsEnum(objs).get("models");
for (Object _mo : models) {
Map<String, Object> mo = (Map<String, Object>) _mo;
CodegenModel cm = (CodegenModel) mo.get("model");
cm.imports = new TreeSet(cm.imports);
// name enum with model name, e.g. StatusEnum => Pet.StatusEnum
for (CodegenProperty var : cm.vars) {
if (Boolean.TRUE.equals(var.isEnum)) {
var.datatypeWithEnum = var.datatypeWithEnum.replace(var.enumName, cm.classname + "" + var.enumName);
}
}
if (cm.parent != null) {
for (CodegenProperty var : cm.allVars) {
if (Boolean.TRUE.equals(var.isEnum)) {
var.datatypeWithEnum = var.datatypeWithEnum
.replace(var.enumName, cm.classname + "" + var.enumName);
}
}
}
}

return objs;
}

@Override
public String escapeQuotationMark(String input) {
// remove ', " to avoid code injection
return input.replace("\"", "").replace("'", "");
}

@Override
public String escapeUnsafeCharacters(String input) {
return input.replace("*/", "*_/").replace("/*", "/_*");
}

@Override
public String getName() {
return "javascript-flowtyped";
}

@Override
public String getHelp() {
return "Generates a Javascript client library using Flow types and Fetch API.";
}

public String getNpmName() {
return npmName;
}

public void setNpmName(String npmName) {
this.npmName = npmName;
}

public String getNpmVersion() {
return npmVersion;
}

public void setNpmVersion(String npmVersion) {
this.npmVersion = npmVersion;
}

public String getNpmRepository() {
return npmRepository;
}

public void setNpmRepository(String npmRepository) {
this.npmRepository = npmRepository;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
## {{npmName}}@{{npmVersion}}

This generator creates Flow typed JavaScript client that utilizes [Fetch API](https://fetch.spec.whatwg.org/). The generated Node module can be used in the following environments:

Environment
* Node.js
* Webpack
* Browserify

Language level
* ES6

Module system
* ES6 module system

### Building

To build an compile the flow typed sources to javascript use:
```
npm install
npm run build
```

### Publishing

First build the package then run ```npm publish```

### Consuming

navigate to the folder of your consuming project and run one of the following commands.

_published:_

```
npm install {{npmName}}@{{npmVersion}} --save
```

_unPublished (not recommended):_

```
npm install PATH_TO_GENERATED_PACKAGE --save
Loading