Skip to content

Commit

Permalink
Merge pull request #1965 from wing328/ts_option_property_naming
Browse files Browse the repository at this point in the history
[TypeScript] add an option to determine property naming convention
  • Loading branch information
wing328 committed Jan 26, 2016
2 parents afd451e + 17f8931 commit f2ab4db
Show file tree
Hide file tree
Showing 15 changed files with 239 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,9 @@ public class CodegenConstants {
public static final String OPTIONAL_PROJECT_GUID = "packageGuid";
public static final String OPTIONAL_PROJECT_GUID_DESC = "The GUID that will be associated with the C# project";

public static final String MODEL_PROPERTY_NAMING = "modelPropertyNaming";
public static final String MODEL_PROPERTY_NAMING_DESC = "Naming convention for the property: 'camelCase', 'PascalCase', 'snake_case' and 'original', which keeps the original name";

public static enum MODEL_PROPERTY_NAMING_TYPE {camelCase, PascalCase, snake_case, original}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen implements CodegenConfig {

protected String modelPropertyNaming= "camelCase";

public AbstractTypeScriptClientCodegen() {
super();
supportsInheritance = true;
Expand Down Expand Up @@ -50,8 +52,21 @@ public AbstractTypeScriptClientCodegen() {
typeMapping.put("DateTime", "Date");
//TODO binary should be mapped to byte array
// mapped to String as a workaround
typeMapping.put("binary", "string");
typeMapping.put("binary", "string");

cliOptions.add(new CliOption(CodegenConstants.MODEL_PROPERTY_NAMING, CodegenConstants.MODEL_PROPERTY_NAMING_DESC).defaultValue("camelCase"));


}

@Override
public void processOpts() {
super.processOpts();
if (additionalProperties.containsKey(CodegenConstants.MODEL_PROPERTY_NAMING)) {
setModelPropertyNaming((String) additionalProperties.get(CodegenConstants.MODEL_PROPERTY_NAMING));
}
}


@Override
public CodegenType getTag() {
Expand All @@ -74,7 +89,7 @@ public String modelFileFolder() {
}

@Override
public String toVarName(String name) {
public String toParamName(String name) {
// replace - with _ e.g. created-at => created_at
name = name.replaceAll("-", "_"); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.

Expand All @@ -94,9 +109,9 @@ public String toVarName(String name) {
}

@Override
public String toParamName(String name) {
public String toVarName(String name) {
// should be the same as variable name
return toVarName(name);
return getNameUsingModelPropertyNaming(name);
}

@Override
Expand Down Expand Up @@ -146,19 +161,47 @@ public String getSwaggerType(Property p) {
return type;
}

@Override
public String toOperationId(String operationId) {
// throw exception if method name is empty
if (StringUtils.isEmpty(operationId)) {
throw new RuntimeException("Empty method name (operationId) not allowed");
}

// method name cannot use reserved keyword, e.g. return
// append _ at the beginning, e.g. _return
if (reservedWords.contains(operationId)) {
return escapeReservedWord(camelize(sanitizeName(operationId), true));
}

return camelize(sanitizeName(operationId), true);
@Override
public String toOperationId(String operationId) {
// throw exception if method name is empty
if (StringUtils.isEmpty(operationId)) {
throw new RuntimeException("Empty method name (operationId) not allowed");
}

// method name cannot use reserved keyword, e.g. return
// append _ at the beginning, e.g. _return
if (reservedWords.contains(operationId)) {
return escapeReservedWord(camelize(sanitizeName(operationId), true));
}

return camelize(sanitizeName(operationId), true);
}

public void setModelPropertyNaming(String naming) {
if ("original".equals(naming) || "camelCase".equals(naming) ||
"PascalCase".equals(naming) || "snake_case".equals(naming)) {
this.modelPropertyNaming = naming;
} else {
throw new IllegalArgumentException("Invalid model property naming '" +
naming + "'. Must be 'original', 'camelCase', " +
"'PascalCase' or 'snake_case'");
}
}

public String getModelPropertyNaming() {
return this.modelPropertyNaming;
}

public String getNameUsingModelPropertyNaming(String name) {
switch (CodegenConstants.MODEL_PROPERTY_NAMING_TYPE.valueOf(getModelPropertyNaming())) {
case original: return name;
case camelCase: return camelize(name, true);
case PascalCase: return camelize(name);
case snake_case: return underscore(name);
default: throw new IllegalArgumentException("Invalid model property naming '" +
name + "'. Must be 'original', 'camelCase', " +
"'PascalCase' or 'snake_case'");
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
public class TypeScriptAngularClientOptionsProvider implements OptionsProvider {
public static final String SORT_PARAMS_VALUE = "false";
public static final String ENSURE_UNIQUE_PARAMS_VALUE = "true";
public static final String MODEL_PROPERTY_NAMING_VALUE = "camelCase";

@Override
public String getLanguage() {
Expand All @@ -20,6 +21,7 @@ public Map<String, String> createOptions() {
ImmutableMap.Builder<String, String> builder = new ImmutableMap.Builder<String, String>();
return builder.put(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG, SORT_PARAMS_VALUE)
.put(CodegenConstants.ENSURE_UNIQUE_PARAMS, ENSURE_UNIQUE_PARAMS_VALUE)
.put(CodegenConstants.MODEL_PROPERTY_NAMING, MODEL_PROPERTY_NAMING_VALUE)
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
public class TypeScriptNodeClientOptionsProvider implements OptionsProvider {
public static final String SORT_PARAMS_VALUE = "false";
public static final String ENSURE_UNIQUE_PARAMS_VALUE = "true";
public static final String MODEL_PROPERTY_NAMING_VALUE = "camelCase";

@Override
public String getLanguage() {
Expand All @@ -20,6 +21,7 @@ public Map<String, String> createOptions() {
ImmutableMap.Builder<String, String> builder = new ImmutableMap.Builder<String, String>();
return builder.put(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG, SORT_PARAMS_VALUE)
.put(CodegenConstants.ENSURE_UNIQUE_PARAMS, ENSURE_UNIQUE_PARAMS_VALUE)
.put(CodegenConstants.MODEL_PROPERTY_NAMING, MODEL_PROPERTY_NAMING_VALUE)
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ protected void setExpectations() {
new Expectations(clientCodegen) {{
clientCodegen.setSortParamsByRequiredFlag(Boolean.valueOf(TypeScriptAngularClientOptionsProvider.SORT_PARAMS_VALUE));
times = 1;
clientCodegen.setModelPropertyNaming(TypeScriptAngularClientOptionsProvider.MODEL_PROPERTY_NAMING_VALUE);
times = 1;
}};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ protected void setExpectations() {
new Expectations(clientCodegen) {{
clientCodegen.setSortParamsByRequiredFlag(Boolean.valueOf(TypeScriptNodeClientOptionsProvider.SORT_PARAMS_VALUE));
times = 1;
clientCodegen.setModelPropertyNaming(TypeScriptNodeClientOptionsProvider.MODEL_PROPERTY_NAMING_VALUE);
times = 1;
}};
}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

This file was deleted.

Binary file not shown.
58 changes: 58 additions & 0 deletions samples/client/petstore/typescript-angular/API/Client/PetApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,64 @@ namespace API.Client {
httpRequestParams = this.extendObj(httpRequestParams, extraHttpRequestParams);
}

return this.$http(httpRequestParams);
}
/**
* Fake endpoint to test byte array return by &#39;Find pet by ID&#39;
* Returns a pet when ID &lt; 10. ID &gt; 10 or nonintegers will simulate API error conditions
* @param petId ID of pet that needs to be fetched
*/
public getPetByIdWithByteArray (petId: number, extraHttpRequestParams?: any ) : ng.IHttpPromise<string> {
const path = this.basePath + '/pet/{petId}?testing_byte_array=true'
.replace('{' + 'petId' + '}', String(petId));

let queryParameters: any = {};
let headerParams: any = this.extendObj({}, this.defaultHeaders);
// verify required parameter 'petId' is set
if (!petId) {
throw new Error('Missing required parameter petId when calling getPetByIdWithByteArray');
}
let httpRequestParams: any = {
method: 'GET',
url: path,
json: true,


params: queryParameters,
headers: headerParams
};

if (extraHttpRequestParams) {
httpRequestParams = this.extendObj(httpRequestParams, extraHttpRequestParams);
}

return this.$http(httpRequestParams);
}
/**
* Fake endpoint to test byte array in body parameter for adding a new pet to the store
*
* @param body Pet object in the form of byte array
*/
public addPetUsingByteArray (body?: string, extraHttpRequestParams?: any ) : ng.IHttpPromise<{}> {
const path = this.basePath + '/pet?testing_byte_array=true';

let queryParameters: any = {};
let headerParams: any = this.extendObj({}, this.defaultHeaders);
let httpRequestParams: any = {
method: 'POST',
url: path,
json: true,
data: body,


params: queryParameters,
headers: headerParams
};

if (extraHttpRequestParams) {
httpRequestParams = this.extendObj(httpRequestParams, extraHttpRequestParams);
}

return this.$http(httpRequestParams);
}
}
Expand Down
107 changes: 107 additions & 0 deletions samples/client/petstore/typescript-node/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1071,6 +1071,113 @@ export class PetApi {
}
});

return deferred.promise;
}
/**
* Fake endpoint to test byte array return by &#39;Find pet by ID&#39;
* Returns a pet when ID &lt; 10. ID &gt; 10 or nonintegers will simulate API error conditions
* @param petId ID of pet that needs to be fetched
*/
public getPetByIdWithByteArray (petId: number) : Promise<{ response: http.ClientResponse; body: string; }> {
const path = this.basePath + '/pet/{petId}?testing_byte_array=true'
.replace('{' + 'petId' + '}', String(petId));
let queryParameters: any = {};
let headerParams: any = this.extendObj({}, this.defaultHeaders);
let formParams: any = {};


// verify required parameter 'petId' is set
if (!petId) {
throw new Error('Missing required parameter petId when calling getPetByIdWithByteArray');
}

let useFormData = false;

let deferred = promise.defer<{ response: http.ClientResponse; body: string; }>();

let requestOptions: request.Options = {
method: 'GET',
qs: queryParameters,
headers: headerParams,
uri: path,
json: true,
}

this.authentications.api_key.applyToRequest(requestOptions);

this.authentications.default.applyToRequest(requestOptions);

if (Object.keys(formParams).length) {
if (useFormData) {
(<any>requestOptions).formData = formParams;
} else {
requestOptions.form = formParams;
}
}

request(requestOptions, (error, response, body) => {
if (error) {
deferred.reject(error);
} else {
if (response.statusCode >= 200 && response.statusCode <= 299) {
deferred.resolve({ response: response, body: body });
} else {
deferred.reject({ response: response, body: body });
}
}
});

return deferred.promise;
}
/**
* Fake endpoint to test byte array in body parameter for adding a new pet to the store
*
* @param body Pet object in the form of byte array
*/
public addPetUsingByteArray (body?: string) : Promise<{ response: http.ClientResponse; body?: any; }> {
const path = this.basePath + '/pet?testing_byte_array=true';
let queryParameters: any = {};
let headerParams: any = this.extendObj({}, this.defaultHeaders);
let formParams: any = {};


let useFormData = false;

let deferred = promise.defer<{ response: http.ClientResponse; body?: any; }>();

let requestOptions: request.Options = {
method: 'POST',
qs: queryParameters,
headers: headerParams,
uri: path,
json: true,
body: body,
}

this.authentications.petstore_auth.applyToRequest(requestOptions);

this.authentications.default.applyToRequest(requestOptions);

if (Object.keys(formParams).length) {
if (useFormData) {
(<any>requestOptions).formData = formParams;
} else {
requestOptions.form = formParams;
}
}

request(requestOptions, (error, response, body) => {
if (error) {
deferred.reject(error);
} else {
if (response.statusCode >= 200 && response.statusCode <= 299) {
deferred.resolve({ response: response, body: body });
} else {
deferred.reject({ response: response, body: body });
}
}
});

return deferred.promise;
}
}
Expand Down

0 comments on commit f2ab4db

Please sign in to comment.