Fix javascript-apollo generator/template (#13191)

* bump apollo-datasource-rest to 3.6.1

* Fix RESTDataSource import

* fix ApiClient template

* fix parameters in callApi, add requestInit param

* change parameters to RESTDataSource convenience methods

* add .babelrc file, even in ES6

* simplify .babelrc... no need for all those fancy things, i think

* fix API test mustache template

* Update package.mustache

* add Set as a language-specific primitive

* Update JavascriptApolloClientCodegen.java

* make babel packages dev dependencies only

* Get inspiration from the main Javascript Generator 😖

* correctly get the basePath from spec

* fix basePath template reference

* Do not sanitize project description

Project descriptions are a multiline string — we just need to escape a few special characters (which we're already doing by invoking escapeText() on line 334)

* Fix module name when generating scoped package

If we set the project name to "@myorg/mypackage" (scoped package[1]), running `npm test` will fail, as it will generate faulty code.

[1] https://docs.npmjs.com/about-scopes
This commit is contained in:
João Neto 2022-08-22 12:39:50 +02:00 committed by GitHub
parent fa22ba9dd9
commit ed10360fc6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 176 additions and 53 deletions

View File

@ -20,6 +20,7 @@ import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info; import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License; import io.swagger.v3.oas.models.info.License;
import io.swagger.v3.oas.models.media.ArraySchema; import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.ComposedSchema;
import io.swagger.v3.oas.models.media.Schema; import io.swagger.v3.oas.models.media.Schema;
import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@ -49,8 +50,11 @@ public class JavascriptApolloClientCodegen extends DefaultCodegen implements Cod
public static final String MODULE_NAME = "moduleName"; public static final String MODULE_NAME = "moduleName";
public static final String PROJECT_DESCRIPTION = "projectDescription"; public static final String PROJECT_DESCRIPTION = "projectDescription";
public static final String PROJECT_VERSION = "projectVersion"; public static final String PROJECT_VERSION = "projectVersion";
public static final String USE_PROMISES = "usePromises";
public static final String USE_INHERITANCE = "useInheritance"; public static final String USE_INHERITANCE = "useInheritance";
public static final String EMIT_MODEL_METHODS = "emitModelMethods";
public static final String EMIT_JS_DOC = "emitJSDoc"; public static final String EMIT_JS_DOC = "emitJSDoc";
public static final String USE_ES6 = "useES6";
public static final String NPM_REPOSITORY = "npmRepository"; public static final String NPM_REPOSITORY = "npmRepository";
final String[][] JAVASCRIPT_SUPPORTING_FILES = { final String[][] JAVASCRIPT_SUPPORTING_FILES = {
@ -60,7 +64,8 @@ public class JavascriptApolloClientCodegen extends DefaultCodegen implements Cod
new String[]{"git_push.sh.mustache", "git_push.sh"}, new String[]{"git_push.sh.mustache", "git_push.sh"},
new String[]{"README.mustache", "README.md"}, new String[]{"README.mustache", "README.md"},
new String[]{"mocha.opts", "mocha.opts"}, new String[]{"mocha.opts", "mocha.opts"},
new String[]{"travis.yml", ".travis.yml"} new String[]{"travis.yml", ".travis.yml"},
new String[]{"gitignore.mustache", ".gitignore"}
}; };
final String[][] JAVASCRIPT_ES6_SUPPORTING_FILES = { final String[][] JAVASCRIPT_ES6_SUPPORTING_FILES = {
@ -71,7 +76,8 @@ public class JavascriptApolloClientCodegen extends DefaultCodegen implements Cod
new String[]{"README.mustache", "README.md"}, new String[]{"README.mustache", "README.md"},
new String[]{"mocha.opts", "mocha.opts"}, new String[]{"mocha.opts", "mocha.opts"},
new String[]{"travis.yml", ".travis.yml"}, new String[]{"travis.yml", ".travis.yml"},
new String[]{".babelrc.mustache", ".babelrc"} new String[]{".babelrc.mustache", ".babelrc"},
new String[]{"gitignore.mustache", ".gitignore"}
}; };
protected String projectName; protected String projectName;
@ -82,11 +88,14 @@ public class JavascriptApolloClientCodegen extends DefaultCodegen implements Cod
protected String invokerPackage; protected String invokerPackage;
protected String sourceFolder = "src"; protected String sourceFolder = "src";
protected boolean usePromises;
protected boolean emitModelMethods;
protected boolean emitJSDoc = true; protected boolean emitJSDoc = true;
protected String apiDocPath = "docs/"; protected String apiDocPath = "docs/";
protected String modelDocPath = "docs/"; protected String modelDocPath = "docs/";
protected String apiTestPath = "api/"; protected String apiTestPath = "api/";
protected String modelTestPath = "model/"; protected String modelTestPath = "model/";
protected boolean useES6 = true; // default is ES6
protected String npmRepository = null; protected String npmRepository = null;
private String modelPropertyNaming = "camelCase"; private String modelPropertyNaming = "camelCase";
@ -95,10 +104,6 @@ public class JavascriptApolloClientCodegen extends DefaultCodegen implements Cod
modifyFeatureSet(features -> features.includeDocumentationFeatures(DocumentationFeature.Readme)); modifyFeatureSet(features -> features.includeDocumentationFeatures(DocumentationFeature.Readme));
generatorMetadata = GeneratorMetadata.newBuilder(generatorMetadata)
.stability(Stability.BETA)
.build();
outputFolder = "generated-code/js"; outputFolder = "generated-code/js";
modelTemplateFiles.put("model.mustache", ".js"); modelTemplateFiles.put("model.mustache", ".js");
modelTestTemplateFiles.put("model_test.mustache", ".js"); modelTestTemplateFiles.put("model_test.mustache", ".js");
@ -115,7 +120,7 @@ public class JavascriptApolloClientCodegen extends DefaultCodegen implements Cod
hideGenerationTimestamp = Boolean.TRUE; hideGenerationTimestamp = Boolean.TRUE;
// reference: http://www.w3schools.com/js/js_reserved.asp // reference: http://www.w3schools.com/js/js_reserved.asp
setReservedWordsLowerCase( reservedWords = new HashSet<>(
Arrays.asList( Arrays.asList(
"abstract", "arguments", "boolean", "break", "byte", "abstract", "arguments", "boolean", "break", "byte",
"case", "catch", "char", "class", "const", "case", "catch", "char", "class", "const",
@ -142,10 +147,12 @@ public class JavascriptApolloClientCodegen extends DefaultCodegen implements Cod
defaultIncludes = new HashSet<>(languageSpecificPrimitives); defaultIncludes = new HashSet<>(languageSpecificPrimitives);
instantiationTypes.put("array", "Array"); instantiationTypes.put("array", "Array");
instantiationTypes.put("set", "Array");
instantiationTypes.put("list", "Array"); instantiationTypes.put("list", "Array");
instantiationTypes.put("map", "Object"); instantiationTypes.put("map", "Object");
typeMapping.clear(); typeMapping.clear();
typeMapping.put("array", "Array"); typeMapping.put("array", "Array");
typeMapping.put("set", "Array");
typeMapping.put("map", "Object"); typeMapping.put("map", "Object");
typeMapping.put("List", "Array"); typeMapping.put("List", "Array");
typeMapping.put("boolean", "Boolean"); typeMapping.put("boolean", "Boolean");
@ -153,7 +160,7 @@ public class JavascriptApolloClientCodegen extends DefaultCodegen implements Cod
typeMapping.put("int", "Number"); typeMapping.put("int", "Number");
typeMapping.put("float", "Number"); typeMapping.put("float", "Number");
typeMapping.put("number", "Number"); typeMapping.put("number", "Number");
typeMapping.put("BigDecimal", "Number"); typeMapping.put("decimal", "Number");
typeMapping.put("DateTime", "Date"); typeMapping.put("DateTime", "Date");
typeMapping.put("date", "Date"); typeMapping.put("date", "Date");
typeMapping.put("long", "Number"); typeMapping.put("long", "Number");
@ -167,6 +174,7 @@ public class JavascriptApolloClientCodegen extends DefaultCodegen implements Cod
typeMapping.put("file", "File"); typeMapping.put("file", "File");
typeMapping.put("UUID", "String"); typeMapping.put("UUID", "String");
typeMapping.put("URI", "String"); typeMapping.put("URI", "String");
typeMapping.put("AnyType", "Object");
importMapping.clear(); importMapping.clear();
@ -184,6 +192,12 @@ public class JavascriptApolloClientCodegen extends DefaultCodegen implements Cod
"version of the project (Default: using info.version or \"1.0.0\")")); "version of the project (Default: using info.version or \"1.0.0\")"));
cliOptions.add(new CliOption(CodegenConstants.LICENSE_NAME, cliOptions.add(new CliOption(CodegenConstants.LICENSE_NAME,
"name of the license the project uses (Default: using info.license.name)")); "name of the license the project uses (Default: using info.license.name)"));
cliOptions.add(new CliOption(USE_PROMISES,
"use Promises as return values from the client API, instead of superagent callbacks")
.defaultValue(Boolean.FALSE.toString()));
cliOptions.add(new CliOption(EMIT_MODEL_METHODS,
"generate getters and setters for model properties")
.defaultValue(Boolean.FALSE.toString()));
cliOptions.add(new CliOption(EMIT_JS_DOC, cliOptions.add(new CliOption(EMIT_JS_DOC,
"generate JSDoc comments") "generate JSDoc comments")
.defaultValue(Boolean.TRUE.toString())); .defaultValue(Boolean.TRUE.toString()));
@ -241,12 +255,18 @@ public class JavascriptApolloClientCodegen extends DefaultCodegen implements Cod
if (additionalProperties.containsKey(CodegenConstants.INVOKER_PACKAGE)) { if (additionalProperties.containsKey(CodegenConstants.INVOKER_PACKAGE)) {
setInvokerPackage((String) additionalProperties.get(CodegenConstants.INVOKER_PACKAGE)); setInvokerPackage((String) additionalProperties.get(CodegenConstants.INVOKER_PACKAGE));
} }
if (additionalProperties.containsKey(USE_PROMISES)) {
setUsePromises(convertPropertyToBooleanAndWriteBack(USE_PROMISES));
}
if (additionalProperties.containsKey(USE_INHERITANCE)) { if (additionalProperties.containsKey(USE_INHERITANCE)) {
setUseInheritance(convertPropertyToBooleanAndWriteBack(USE_INHERITANCE)); setUseInheritance(convertPropertyToBooleanAndWriteBack(USE_INHERITANCE));
} else { } else {
supportsInheritance = true; supportsInheritance = true;
supportsMixins = true; supportsMixins = true;
} }
if (additionalProperties.containsKey(EMIT_MODEL_METHODS)) {
setEmitModelMethods(convertPropertyToBooleanAndWriteBack(EMIT_MODEL_METHODS));
}
if (additionalProperties.containsKey(EMIT_JS_DOC)) { if (additionalProperties.containsKey(EMIT_JS_DOC)) {
setEmitJSDoc(convertPropertyToBooleanAndWriteBack(EMIT_JS_DOC)); setEmitJSDoc(convertPropertyToBooleanAndWriteBack(EMIT_JS_DOC));
} }
@ -277,7 +297,7 @@ public class JavascriptApolloClientCodegen extends DefaultCodegen implements Cod
if (StringUtils.isEmpty(info.getDescription())) { if (StringUtils.isEmpty(info.getDescription())) {
projectDescription = "JS API client generated by OpenAPI Generator"; projectDescription = "JS API client generated by OpenAPI Generator";
} else { } else {
projectDescription = sanitizeName(info.getDescription()); projectDescription = info.getDescription();
} }
} }
@ -293,7 +313,7 @@ public class JavascriptApolloClientCodegen extends DefaultCodegen implements Cod
projectName = "openapi-js-client"; projectName = "openapi-js-client";
} }
if (StringUtils.isBlank(moduleName)) { if (StringUtils.isBlank(moduleName)) {
moduleName = camelize(underscore(projectName)); moduleName = camelize(underscore(sanitizeName(projectName)));
} }
if (StringUtils.isBlank(projectVersion)) { if (StringUtils.isBlank(projectVersion)) {
projectVersion = "1.0.0"; projectVersion = "1.0.0";
@ -314,8 +334,11 @@ public class JavascriptApolloClientCodegen extends DefaultCodegen implements Cod
additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage); additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);
additionalProperties.put(CodegenConstants.MODEL_PACKAGE, modelPackage); additionalProperties.put(CodegenConstants.MODEL_PACKAGE, modelPackage);
additionalProperties.put(CodegenConstants.SOURCE_FOLDER, sourceFolder); additionalProperties.put(CodegenConstants.SOURCE_FOLDER, sourceFolder);
additionalProperties.put(USE_PROMISES, usePromises);
additionalProperties.put(USE_INHERITANCE, supportsInheritance); additionalProperties.put(USE_INHERITANCE, supportsInheritance);
additionalProperties.put(EMIT_MODEL_METHODS, emitModelMethods);
additionalProperties.put(EMIT_JS_DOC, emitJSDoc); additionalProperties.put(EMIT_JS_DOC, emitJSDoc);
additionalProperties.put(USE_ES6, useES6);
additionalProperties.put(NPM_REPOSITORY, npmRepository); additionalProperties.put(NPM_REPOSITORY, npmRepository);
// make api and model doc path available in mustache template // make api and model doc path available in mustache template
@ -323,6 +346,9 @@ public class JavascriptApolloClientCodegen extends DefaultCodegen implements Cod
additionalProperties.put("modelDocPath", modelDocPath); additionalProperties.put("modelDocPath", modelDocPath);
String[][] supportingTemplateFiles = JAVASCRIPT_SUPPORTING_FILES; String[][] supportingTemplateFiles = JAVASCRIPT_SUPPORTING_FILES;
if (useES6) {
supportingTemplateFiles = JAVASCRIPT_ES6_SUPPORTING_FILES;
}
for (String[] supportingTemplateFile : supportingTemplateFiles) { for (String[] supportingTemplateFile : supportingTemplateFiles) {
supportingFiles.add(new SupportingFile(supportingTemplateFile[0], "", supportingTemplateFile[1])); supportingFiles.add(new SupportingFile(supportingTemplateFile[0], "", supportingTemplateFile[1]));
@ -417,6 +443,10 @@ public class JavascriptApolloClientCodegen extends DefaultCodegen implements Cod
this.licenseName = licenseName; this.licenseName = licenseName;
} }
public void setUsePromises(boolean usePromises) {
this.usePromises = usePromises;
}
public void setNpmRepository(String npmRepository) { public void setNpmRepository(String npmRepository) {
this.npmRepository = npmRepository; this.npmRepository = npmRepository;
} }
@ -426,6 +456,10 @@ public class JavascriptApolloClientCodegen extends DefaultCodegen implements Cod
this.supportsMixins = useInheritance; this.supportsMixins = useInheritance;
} }
public void setEmitModelMethods(boolean emitModelMethods) {
this.emitModelMethods = emitModelMethods;
}
public void setEmitJSDoc(boolean emitJSDoc) { public void setEmitJSDoc(boolean emitJSDoc) {
this.emitJSDoc = emitJSDoc; this.emitJSDoc = emitJSDoc;
} }
@ -507,6 +541,11 @@ public class JavascriptApolloClientCodegen extends DefaultCodegen implements Cod
return name; return name;
} }
@Override
protected boolean isReservedWord(String word) {
return word != null && reservedWords.contains(word);
}
@Override @Override
public String toParamName(String name) { public String toParamName(String name) {
// should be the same as variable name // should be the same as variable name
@ -867,22 +906,36 @@ public class JavascriptApolloClientCodegen extends DefaultCodegen implements Cod
return null; return null;
} }
private String getModelledType(String dataType) {
return "module:" + (StringUtils.isEmpty(invokerPackage) ? "" : (invokerPackage + "/"))
+ (StringUtils.isEmpty(modelPackage) ? "" : (modelPackage + "/")) + dataType;
}
private String getJSDocType(CodegenModel cm, CodegenProperty cp) { private String getJSDocType(CodegenModel cm, CodegenProperty cp) {
if (Boolean.TRUE.equals(cp.isContainer)) { if (Boolean.TRUE.equals(cp.isContainer)) {
if (cp.containerType.equals("array")) if (cp.containerType.equals("array") || cp.containerType.equals("set"))
return "Array.<" + cp.items + ">"; return "Array.<" + getJSDocType(cm, cp.items) + ">";
else if (cp.containerType.equals("map")) else if (cp.containerType.equals("map"))
return "Object.<String, " + cp.items + ">"; return "Object.<String, " + getJSDocType(cm, cp.items) + ">";
} }
String dataType = trimBrackets(cp.datatypeWithEnum); String dataType = trimBrackets(cp.datatypeWithEnum);
if (cp.isEnum) { if (cp.isEnum) {
dataType = cm.classname + '.' + dataType; dataType = cm.classname + '.' + dataType;
} }
if (isModelledType(cp))
dataType = getModelledType(dataType);
return dataType; return dataType;
} }
private boolean isModelledType(CodegenProperty cp) {
// N.B. enums count as modelled types, file is not modelled (SuperAgent uses some 3rd party library).
return cp.isEnum || !languageSpecificPrimitives.contains(cp.baseType == null ? cp.dataType : cp.baseType);
}
private String getJSDocType(CodegenParameter cp) { private String getJSDocType(CodegenParameter cp) {
String dataType = trimBrackets(cp.dataType); String dataType = trimBrackets(cp.dataType);
if (isModelledType(cp))
dataType = getModelledType(dataType);
if (Boolean.TRUE.equals(cp.isArray)) { if (Boolean.TRUE.equals(cp.isArray)) {
return "Array.<" + dataType + ">"; return "Array.<" + dataType + ">";
} else if (Boolean.TRUE.equals(cp.isMap)) { } else if (Boolean.TRUE.equals(cp.isMap)) {
@ -891,9 +944,16 @@ public class JavascriptApolloClientCodegen extends DefaultCodegen implements Cod
return dataType; return dataType;
} }
private boolean isModelledType(CodegenParameter cp) {
// N.B. enums count as modelled types, file is not modelled (SuperAgent uses some 3rd party library).
return cp.isEnum || !languageSpecificPrimitives.contains(cp.baseType == null ? cp.dataType : cp.baseType);
}
private String getJSDocType(CodegenOperation co) { private String getJSDocType(CodegenOperation co) {
String returnType = trimBrackets(co.returnType); String returnType = trimBrackets(co.returnType);
if (returnType != null) { if (returnType != null) {
if (isModelledType(co))
returnType = getModelledType(returnType);
if (Boolean.TRUE.equals(co.isArray)) { if (Boolean.TRUE.equals(co.isArray)) {
return "Array.<" + returnType + ">"; return "Array.<" + returnType + ">";
} else if (Boolean.TRUE.equals(co.isMap)) { } else if (Boolean.TRUE.equals(co.isMap)) {
@ -903,12 +963,16 @@ public class JavascriptApolloClientCodegen extends DefaultCodegen implements Cod
return returnType; return returnType;
} }
private boolean isModelledType(CodegenOperation co) {
// This seems to be the only way to tell whether an operation return type is modelled.
return !Boolean.TRUE.equals(co.returnTypeIsPrimitive);
}
private boolean isPrimitiveType(String type) { private boolean isPrimitiveType(String type) {
final String[] primitives = {"number", "integer", "string", "boolean", "null"}; final String[] primitives = {"number", "integer", "string", "boolean", "null"};
return Arrays.asList(primitives).contains(type); return Arrays.asList(primitives).contains(type);
} }
@SuppressWarnings("unchecked")
@Override @Override
public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<ModelMap> allModels) { public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<ModelMap> allModels) {
// Generate and store argument list string of each operation into // Generate and store argument list string of each operation into
@ -937,6 +1001,9 @@ public class JavascriptApolloClientCodegen extends DefaultCodegen implements Cod
argList.add("opts"); argList.add("opts");
} }
// add the 'requestInit' parameter
argList.add("requestInit");
String joinedArgList = StringUtils.join(argList, ", "); String joinedArgList = StringUtils.join(argList, ", ");
operation.vendorExtensions.put("x-codegen-arg-list", joinedArgList); operation.vendorExtensions.put("x-codegen-arg-list", joinedArgList);
operation.vendorExtensions.put("x-codegen-has-optional-params", hasOptionalParams); operation.vendorExtensions.put("x-codegen-has-optional-params", hasOptionalParams);
@ -1146,5 +1213,23 @@ public class JavascriptApolloClientCodegen extends DefaultCodegen implements Cod
} }
@Override @Override
public GeneratorLanguage generatorLanguage() { return GeneratorLanguage.JAVASCRIPT; } protected String getCollectionFormat(CodegenParameter codegenParameter) {
// This method will return `passthrough` when the parameter data format is binary and an array.
// `passthrough` is not part of the OAS spec. However, this will act like a flag that we should
// not do any processing on the collection type (i.e. convert to tsv, csv, etc..). This is
// critical to support multi file uploads correctly.
if (codegenParameter.isArray && Objects.equals(codegenParameter.dataFormat, "binary")) {
return "passthrough";
}
return super.getCollectionFormat(codegenParameter);
}
@Override
public GeneratorLanguage generatorLanguage() { return GeneratorLanguage.JAVASCRIPT; }
@Override
protected void addImport(ComposedSchema composed, Schema childSchema, CodegenModel model, String modelName ) {
// import everything (including child schema of a composed schema)
addImport(model, modelName);
}
} }

View File

@ -1,6 +1,6 @@
{{>licenseInfo}} {{>licenseInfo}}
import RESTDataSource from 'apollo-datasource-rest'; import { RESTDataSource } from 'apollo-datasource-rest';
{{#emitJSDoc}}/** {{#emitJSDoc}}/**
* @module {{#invokerPackage}}{{.}}/{{/invokerPackage}}ApiClient * @module {{#invokerPackage}}{{.}}/{{/invokerPackage}}ApiClient
@ -14,9 +14,16 @@ import RESTDataSource from 'apollo-datasource-rest';
* @class * @class
*/{{/emitJSDoc}} */{{/emitJSDoc}}
export default class ApiClient extends RESTDataSource { export default class ApiClient extends RESTDataSource {
constructor() { constructor(baseURL = '{{{basePath}}}') {
super() super()
{{#emitJSDoc}}/**
* The base URL against which to resolve every API call's (relative) path.
* @type {String}
* @default {{{basePath}}}
*/{{/emitJSDoc}}
this.baseURL = baseURL.replace(/\/+$/, '');
{{#emitJSDoc}}/** {{#emitJSDoc}}/**
* The authentication methods to be included for all API calls. * The authentication methods to be included for all API calls.
* @type {Array.<String>} * @type {Array.<String>}
@ -53,7 +60,7 @@ export default class ApiClient extends RESTDataSource {
} }
parametrizePath(path, pathParams) { parametrizePath(path, pathParams) {
return url.replace(/\{([\w-]+)\}/g, (fullMatch, key) => { return path.replace(/\{([\w-]+)\}/g, (fullMatch, key) => {
var value; var value;
if (pathParams.hasOwnProperty(key)) { if (pathParams.hasOwnProperty(key)) {
value = this.paramToString(pathParams[key]); value = this.paramToString(pathParams[key]);
@ -176,7 +183,7 @@ export default class ApiClient extends RESTDataSource {
async callApi(path, httpMethod, pathParams, async callApi(path, httpMethod, pathParams,
queryParams, headerParams, formParams, bodyParam, authNames, queryParams, headerParams, formParams, bodyParam, authNames,
returnType) { contentTypes, accepts, returnType, requestInit) {
var parameterizedPath = this.parametrizePath(path, pathParams); var parameterizedPath = this.parametrizePath(path, pathParams);
var fetchOptions = { var fetchOptions = {
@ -203,9 +210,9 @@ export default class ApiClient extends RESTDataSource {
var httpMethodFn = httpMethod.toLowerCase(); var httpMethodFn = httpMethod.toLowerCase();
if (httpMethodFn == 'get' || httpMethodFn == 'delete') { if (httpMethodFn == 'get' || httpMethodFn == 'delete') {
response = await this[httpMethodFn](parameterizedPath, fetchOptions); response = await this[httpMethodFn](parameterizedPath, [], requestInit);
} else { } else {
response = await this[httpMethodFn](parameterizedPath, body, fetchOptions) response = await this[httpMethodFn](parameterizedPath, body, requestInit)
} }
var convertedResponse = ApiClient.convertToType(response, returnType); var convertedResponse = ApiClient.convertToType(response, returnType);
@ -234,7 +241,7 @@ export default class ApiClient extends RESTDataSource {
case 'Blob': case 'Blob':
return data; return data;
default: default:
if (type === Object) { if (typeof type === "object") {
// generic object, return directly // generic object, return directly
return data; return data;
} else if (typeof type.constructFromObject === 'function') { } else if (typeof type.constructFromObject === 'function') {

View File

@ -19,9 +19,8 @@ export default class <&classname> extends ApiClient {
* @alias module:<#invokerPackage><&invokerPackage>/</invokerPackage><#apiPackage><&apiPackage>/</apiPackage><classname> * @alias module:<#invokerPackage><&invokerPackage>/</invokerPackage><#apiPackage><&apiPackage>/</apiPackage><classname>
* @class * @class
*/</emitJSDoc> */</emitJSDoc>
constructor() { constructor(baseURL = '<&basePath>') {
super(); super(baseURL);
this.baseURL = <#servers.0>basePath</servers.0><^servers.0>null</servers.0>;
} }
<#operations><#operation><#emitJSDoc> <#operations><#operation><#emitJSDoc>
@ -31,6 +30,7 @@ export default class <&classname> extends ApiClient {
* @param {<&vendorExtensions.x-jsdoc-type>} <&paramName> <&description></required></allParams><#hasOptionalParams> * @param {<&vendorExtensions.x-jsdoc-type>} <&paramName> <&description></required></allParams><#hasOptionalParams>
* @param {Object} opts Optional parameters<#allParams><^required> * @param {Object} opts Optional parameters<#allParams><^required>
* @param {<&vendorExtensions.x-jsdoc-type>} opts.<&paramName> <&description><#defaultValue> (default to <&.>)</defaultValue></required></allParams></hasOptionalParams> * @param {<&vendorExtensions.x-jsdoc-type>} opts.<&paramName> <&description><#defaultValue> (default to <&.>)</defaultValue></required></allParams></hasOptionalParams>
* @param requestInit Dynamic configuration. @see {@link https://github.com/apollographql/apollo-server/pull/1277}
<=| |=>* @return {Promise|#returnType|<|&vendorExtensions.x-jsdoc-type|>|/returnType|}|=< >=| <=| |=>* @return {Promise|#returnType|<|&vendorExtensions.x-jsdoc-type|>|/returnType|}|=< >=|
*/ */
</emitJSDoc> async <operationId>(<vendorExtensions.x-codegen-arg-list>) { </emitJSDoc> async <operationId>(<vendorExtensions.x-codegen-arg-list>) {
@ -80,7 +80,7 @@ export default class <&classname> extends ApiClient {
return this.callApi( return this.callApi(
'<&path>', '<httpMethod>', '<&path>', '<httpMethod>',
pathParams, queryParams, headerParams, formParams, postBody, pathParams, queryParams, headerParams, formParams, postBody,
authNames, contentTypes, accepts, returnType authNames, contentTypes, accepts, returnType, requestInit
); );
} }
</operation></operations> </operation></operations>

View File

@ -1,7 +1,13 @@
{{>licenseInfo}} {{>licenseInfo}}
(function(root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD.
define(['expect.js', process.cwd()+'/src/{{#invokerPackage}}{{.}}/{{/invokerPackage}}index'], factory);
} else if (typeof module === 'object' && module.exports) {
// CommonJS-like environments that support module.exports, like Node. // CommonJS-like environments that support module.exports, like Node.
factory(require('expect.js'), require(process.cwd()+'/src/{{#invokerPackage}}{{.}}/{{/invokerPackage}}index')); factory(require('expect.js'), require(process.cwd()+'/src/{{#invokerPackage}}{{.}}/{{/invokerPackage}}index'));
}
}(this, function(expect, {{moduleName}}) {
'use strict'; 'use strict';
var instance; var instance;
@ -42,3 +48,5 @@ describe('{{classname}}', function() {
{{/operation}} {{/operation}}
{{/operations}} {{/operations}}
}); });
}));

View File

@ -3,8 +3,10 @@
"version": "{{{projectVersion}}}", "version": "{{{projectVersion}}}",
"description": "{{{projectDescription}}}", "description": "{{{projectDescription}}}",
"license": "{{licenseName}}", "license": "{{licenseName}}",
"main": "src/index.js", "main": "dist{{#invokerPackage}}/{{.}}{{/invokerPackage}}/index.js",
"scripts": { "scripts": {
"build": "babel src -d dist",
"prepare": "npm run build",
"test": "mocha --require @babel/register --recursive" "test": "mocha --require @babel/register --recursive"
}, },
"browser": { "browser": {
@ -16,14 +18,35 @@
}, },
{{/npmRepository}} {{/npmRepository}}
"dependencies": { "dependencies": {
"apollo-datasource-rest": "^0.7.0" "@babel/cli": "^7.0.0",
"apollo-datasource-rest": "^3.6.1",
"superagent": "^5.3.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.0.0",
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/plugin-proposal-decorators": "^7.0.0",
"@babel/plugin-proposal-do-expressions": "^7.0.0",
"@babel/plugin-proposal-export-default-from": "^7.0.0",
"@babel/plugin-proposal-export-namespace-from": "^7.0.0",
"@babel/plugin-proposal-function-bind": "^7.0.0",
"@babel/plugin-proposal-function-sent": "^7.0.0",
"@babel/plugin-proposal-json-strings": "^7.0.0",
"@babel/plugin-proposal-logical-assignment-operators": "^7.0.0",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0",
"@babel/plugin-proposal-numeric-separator": "^7.0.0",
"@babel/plugin-proposal-optional-chaining": "^7.0.0",
"@babel/plugin-proposal-pipeline-operator": "^7.0.0",
"@babel/plugin-proposal-throw-expressions": "^7.0.0",
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
"@babel/plugin-syntax-import-meta": "^7.0.0",
"@babel/preset-env": "^7.0.0",
"@babel/register": "^7.0.0",
"expect.js": "^0.3.1", "expect.js": "^0.3.1",
"mocha": "^5.2.0", "mocha": "^8.0.1",
"sinon": "^7.2.0" "sinon": "^7.2.0"
}, },
"files": [ "files": [
"src" "dist"
] ]
} }