diff --git a/bin/configs/typescript-koa-server.yaml b/bin/configs/typescript-koa-server.yaml new file mode 100644 index 00000000000..7267befdbd7 --- /dev/null +++ b/bin/configs/typescript-koa-server.yaml @@ -0,0 +1,7 @@ +generatorName: typescript-koa-server +outputDir: samples/server/petstore/typescript-koa-server +inputSpec: modules/openapi-generator/src/test/resources/3_0/typescript-koa-server/petstore.yaml +templateDir: modules/openapi-generator/src/main/resources/typescript-koa-server +additionalProperties: + ngVersion: 15.0.3 + supportsES6: true diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptKoaServerCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptKoaServerCodegen.java new file mode 100644 index 00000000000..c024399e8d9 --- /dev/null +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptKoaServerCodegen.java @@ -0,0 +1,695 @@ +/* + * Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech) + * Copyright 2018 SmartBear Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openapitools.codegen.languages; + +import io.swagger.v3.oas.models.media.Schema; +import org.openapitools.codegen.*; +import org.openapitools.codegen.meta.features.DocumentationFeature; +import org.openapitools.codegen.meta.features.GlobalFeature; +import org.openapitools.codegen.model.ModelMap; +import org.openapitools.codegen.model.ModelsMap; +import org.openapitools.codegen.model.OperationMap; +import org.openapitools.codegen.model.OperationsMap; +import org.openapitools.codegen.utils.ModelUtils; +import org.openapitools.codegen.utils.SemVer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.apache.commons.lang3.StringUtils.capitalize; +import static org.openapitools.codegen.utils.CamelizeOption.LOWERCASE_FIRST_LETTER; +import static org.openapitools.codegen.utils.StringUtils.*; + +public class TypeScriptKoaServerCodegen extends AbstractTypeScriptClientCodegen { + private final Logger LOGGER = LoggerFactory.getLogger(TypeScriptKoaServerCodegen.class); + + private static String CLASS_NAME_PREFIX_PATTERN = "^[a-zA-Z0-9]*$"; + private static String CLASS_NAME_SUFFIX_PATTERN = "^[a-zA-Z0-9]*$"; + private static String FILE_NAME_SUFFIX_PATTERN = "^[a-zA-Z0-9.-]*$"; + + public static enum QUERY_PARAM_OBJECT_FORMAT_TYPE {dot, json, key} + + public static enum PROVIDED_IN_LEVEL {none, root, any, platform} + + private static final String DEFAULT_IMPORT_PREFIX = "./"; + private static final String DEFAULT_MODEL_IMPORT_DIRECTORY_PREFIX = "../"; + + public static final String NPM_REPOSITORY = "npmRepository"; + public static final String WITH_INTERFACES = "withInterfaces"; + public static final String USE_SINGLE_REQUEST_PARAMETER = "useSingleRequestParameter"; + public static final String TAGGED_UNIONS = "taggedUnions"; + public static final String NG_VERSION = "ngVersion"; + public static final String PROVIDED_IN = "providedIn"; + public static final String ENFORCE_GENERIC_MODULE_WITH_PROVIDERS = "enforceGenericModuleWithProviders"; + public static final String HTTP_CONTEXT_IN_OPTIONS = "httpContextInOptions"; + public static final String API_MODULE_PREFIX = "apiModulePrefix"; + public static final String CONFIGURATION_PREFIX = "configurationPrefix"; + public static final String SERVICE_SUFFIX = "serviceSuffix"; + public static final String SERVICE_FILE_SUFFIX = "serviceFileSuffix"; + public static final String MODEL_SUFFIX = "modelSuffix"; + public static final String MODEL_FILE_SUFFIX = "modelFileSuffix"; + public static final String FILE_NAMING = "fileNaming"; + public static final String STRING_ENUMS = "stringEnums"; + public static final String STRING_ENUMS_DESC = "Generate string enums instead of objects for enum values."; + public static final String QUERY_PARAM_OBJECT_FORMAT = "queryParamObjectFormat"; + + protected String ngVersion = "15.0.3"; + protected String npmRepository = null; + private boolean useSingleRequestParameter = false; + protected String serviceSuffix = "Service"; + protected String serviceFileSuffix = ".service"; + protected String modelSuffix = ""; + protected String modelFileSuffix = ""; + protected String fileNaming = "camelCase"; + protected Boolean stringEnums = false; + protected QUERY_PARAM_OBJECT_FORMAT_TYPE queryParamObjectFormat = QUERY_PARAM_OBJECT_FORMAT_TYPE.dot; + protected PROVIDED_IN_LEVEL providedIn = PROVIDED_IN_LEVEL.root; + + private boolean taggedUnions = false; + + public TypeScriptKoaServerCodegen() { + super(); + + modifyFeatureSet(features -> features + .includeDocumentationFeatures(DocumentationFeature.Readme) + .includeGlobalFeatures(GlobalFeature.ParameterStyling) + ); + + this.outputFolder = "generated-code/typescript-koa"; + + supportsMultipleInheritance = true; + + embeddedTemplateDir = templateDir = "typescript-koa"; + modelTemplateFiles.put("model.mustache", ".ts"); + apiTemplateFiles.put("api.service.mustache", ".ts"); + languageSpecificPrimitives.add("Blob"); + typeMapping.put("file", "Blob"); + apiPackage = "api"; + modelPackage = "model"; + + this.cliOptions.add(new CliOption(NPM_REPOSITORY, + "Use this property to set an url your private npmRepo in the package.json")); + this.cliOptions.add(CliOption.newBoolean(WITH_INTERFACES, + "Setting this property to true will generate interfaces next to the default class implementations.", + false)); + this.cliOptions.add(CliOption.newBoolean(USE_SINGLE_REQUEST_PARAMETER, + "Setting this property to true will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter.", + false)); + this.cliOptions.add(CliOption.newBoolean(TAGGED_UNIONS, + "Use discriminators to create tagged unions instead of extending interfaces.", + this.taggedUnions)); + CliOption providedInCliOpt = new CliOption(PROVIDED_IN, + "Use this property to provide Injectables in wanted level.").defaultValue("root"); + Map providedInOptions = new HashMap<>(); + providedInOptions.put(PROVIDED_IN_LEVEL.none.toString(), "No providedIn)"); + providedInOptions.put(PROVIDED_IN_LEVEL.root.toString(), "The application-level injector in most apps."); + providedInOptions.put(PROVIDED_IN_LEVEL.platform.toString(), "A special singleton platform injector shared by all applications on the page."); + providedInOptions.put(PROVIDED_IN_LEVEL.any.toString(), "Provides a unique instance in each lazy loaded module while all eagerly loaded modules share one instance."); + providedInCliOpt.setEnum(providedInOptions); + this.cliOptions.add(providedInCliOpt); + this.cliOptions.add(new CliOption(NG_VERSION, "The version of Angular. (At least 9.0.0)").defaultValue(this.ngVersion)); + this.cliOptions.add(new CliOption(API_MODULE_PREFIX, "The prefix of the generated ApiModule.")); + this.cliOptions.add(new CliOption(CONFIGURATION_PREFIX, "The prefix of the generated Configuration.")); + this.cliOptions.add(new CliOption(SERVICE_SUFFIX, "The suffix of the generated service.").defaultValue(this.serviceSuffix)); + this.cliOptions.add(new CliOption(SERVICE_FILE_SUFFIX, "The suffix of the file of the generated service (service.ts).").defaultValue(this.serviceFileSuffix)); + this.cliOptions.add(new CliOption(MODEL_SUFFIX, "The suffix of the generated model.")); + this.cliOptions.add(new CliOption(MODEL_FILE_SUFFIX, "The suffix of the file of the generated model (model.ts).")); + this.cliOptions.add(new CliOption(FILE_NAMING, "Naming convention for the output files: 'camelCase', 'kebab-case'.").defaultValue(this.fileNaming)); + this.cliOptions.add(new CliOption(STRING_ENUMS, STRING_ENUMS_DESC).defaultValue(String.valueOf(this.stringEnums))); + this.cliOptions.add(new CliOption(QUERY_PARAM_OBJECT_FORMAT, "The format for query param objects: 'dot', 'json', 'key'.").defaultValue(this.queryParamObjectFormat.name())); + } + + @Override + protected void addAdditionPropertiesToCodeGenModel(CodegenModel codegenModel, Schema schema) { + codegenModel.additionalPropertiesType = getTypeDeclaration(getAdditionalProperties(schema)); + addImport(codegenModel, codegenModel.additionalPropertiesType); + } + + @Override + public String getName() { + return "typescript-koa-server"; + } + + @Override + public String getHelp() { + return "Generates a TypeScript Koa (2.x) server."; + } + + @Override + public void processOpts() { + super.processOpts(); + + supportingFiles.add(new SupportingFile("env.example.mustache", "", ".env.example")); + supportingFiles.add(new SupportingFile("jest.config.js.mustache", "", ".jest.config.js")); + supportingFiles.add(new SupportingFile("app.ts.mustache", "", "app.ts")); + supportingFiles.add(new SupportingFile("build.js.mustache", "", "build.js")); + supportingFiles.add(new SupportingFile("docker-compose.mustache", "", "docker-compose.yml")); + supportingFiles.add(new SupportingFile("nodemon.mustache", "", "nodemon.json")); + supportingFiles.add(new SupportingFile("package.mustache", "", "package.json")); + supportingFiles.add(new SupportingFile("tsconfig.mustache", "", "tsconfig.json")); + + supportingFiles.add(new SupportingFile("models.mustache", modelPackage().replace('.', File.separatorChar), "models.ts")); + supportingFiles.add(new SupportingFile("apis.mustache", apiPackage().replace('.', File.separatorChar), "api.ts")); + supportingFiles.add(new SupportingFile("index.mustache", getIndexDirectory(), "index.ts")); + supportingFiles.add(new SupportingFile("api.module.mustache", getIndexDirectory(), "api.module.ts")); + supportingFiles.add(new SupportingFile("configuration.mustache", getIndexDirectory(), "configuration.ts")); + supportingFiles.add(new SupportingFile("variables.mustache", getIndexDirectory(), "variables.ts")); + supportingFiles.add(new SupportingFile("encoder.mustache", getIndexDirectory(), "encoder.ts")); + supportingFiles.add(new SupportingFile("param.mustache", getIndexDirectory(), "param.ts")); + supportingFiles.add(new SupportingFile("gitignore", "", ".gitignore")); + supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh")); + supportingFiles.add(new SupportingFile("README.mustache", getIndexDirectory(), "README.md")); + + supportingFiles.add(new SupportingFile("package.mustache", getIndexDirectory(), "package.json")); + supportingFiles.add(new SupportingFile("tsconfig.mustache", getIndexDirectory(), "tsconfig.json")); + + // determine NG version + SemVer ngVersion; + if (additionalProperties.containsKey(NG_VERSION)) { + ngVersion = new SemVer(additionalProperties.get(NG_VERSION).toString()); + } else { + ngVersion = new SemVer(this.ngVersion); + LOGGER.info("generating code for Angular {} ...", ngVersion); + LOGGER.info(" (you can select the angular version by setting the additionalProperties (--additional-properties in CLI) ngVersion)"); + } + + if (!ngVersion.atLeast("9.0.0")) { + throw new IllegalArgumentException("Invalid ngVersion: " + ngVersion + ". Only Angular v9+ is supported."); + } + + if (additionalProperties.containsKey(STRING_ENUMS)) { + setStringEnums(Boolean.parseBoolean(additionalProperties.get(STRING_ENUMS).toString())); + additionalProperties.put("stringEnums", getStringEnums()); + if (getStringEnums()) { + classEnumSeparator = ""; + } + } + + if (additionalProperties.containsKey(WITH_INTERFACES)) { + boolean withInterfaces = Boolean.parseBoolean(additionalProperties.get(WITH_INTERFACES).toString()); + if (withInterfaces) { + apiTemplateFiles.put("apiInterface.mustache", "Interface.ts"); + } + } + + if (additionalProperties.containsKey(USE_SINGLE_REQUEST_PARAMETER)) { + this.setUseSingleRequestParameter(convertPropertyToBoolean(USE_SINGLE_REQUEST_PARAMETER)); + } + writePropertyBack(USE_SINGLE_REQUEST_PARAMETER, getUseSingleRequestParameter()); + + if (additionalProperties.containsKey(TAGGED_UNIONS)) { + taggedUnions = Boolean.parseBoolean(additionalProperties.get(TAGGED_UNIONS).toString()); + } + + if (additionalProperties.containsKey(PROVIDED_IN)) { + setProvidedIn(additionalProperties.get(PROVIDED_IN).toString()); + } + additionalProperties.put("providedIn", providedIn); + additionalProperties.put("isProvidedInNone", getIsProvidedInNone()); + + additionalProperties.put(ENFORCE_GENERIC_MODULE_WITH_PROVIDERS, true); + + if (ngVersion.atLeast("12.0.0")) { + additionalProperties.put(HTTP_CONTEXT_IN_OPTIONS, true); + } + + additionalProperties.put(NG_VERSION, ngVersion); + + if (additionalProperties.containsKey(API_MODULE_PREFIX)) { + String apiModulePrefix = additionalProperties.get(API_MODULE_PREFIX).toString(); + validateClassPrefixArgument("ApiModule", apiModulePrefix); + + additionalProperties.put("apiModuleClassName", apiModulePrefix + "ApiModule"); + } else { + additionalProperties.put("apiModuleClassName", "ApiModule"); + } + if (additionalProperties.containsKey(CONFIGURATION_PREFIX)) { + String configurationPrefix = additionalProperties.get(CONFIGURATION_PREFIX).toString(); + validateClassPrefixArgument("Configuration", configurationPrefix); + + additionalProperties.put("configurationClassName", configurationPrefix + "Configuration"); + additionalProperties.put("configurationParametersInterfaceName", configurationPrefix + "ConfigurationParameters"); + } else { + additionalProperties.put("configurationClassName", "Configuration"); + additionalProperties.put("configurationParametersInterfaceName", "ConfigurationParameters"); + } + if (additionalProperties.containsKey(SERVICE_SUFFIX)) { + serviceSuffix = additionalProperties.get(SERVICE_SUFFIX).toString(); + validateClassSuffixArgument("Service", serviceSuffix); + } + if (additionalProperties.containsKey(SERVICE_FILE_SUFFIX)) { + serviceFileSuffix = additionalProperties.get(SERVICE_FILE_SUFFIX).toString(); + validateFileSuffixArgument("Service", serviceFileSuffix); + } + if (additionalProperties.containsKey(MODEL_SUFFIX)) { + modelSuffix = additionalProperties.get(MODEL_SUFFIX).toString(); + validateClassSuffixArgument("Model", modelSuffix); + } + if (additionalProperties.containsKey(MODEL_FILE_SUFFIX)) { + modelFileSuffix = additionalProperties.get(MODEL_FILE_SUFFIX).toString(); + validateFileSuffixArgument("Model", modelFileSuffix); + } + if (additionalProperties.containsKey(FILE_NAMING)) { + this.setFileNaming(additionalProperties.get(FILE_NAMING).toString()); + } + + if (additionalProperties.containsKey(QUERY_PARAM_OBJECT_FORMAT)) { + setQueryParamObjectFormat((String) additionalProperties.get(QUERY_PARAM_OBJECT_FORMAT)); + } + additionalProperties.put("isQueryParamObjectFormatDot", getQueryParamObjectFormatDot()); + additionalProperties.put("isQueryParamObjectFormatJson", getQueryParamObjectFormatJson()); + additionalProperties.put("isQueryParamObjectFormatKey", getQueryParamObjectFormatKey()); + + } + + private String getIndexDirectory() { + String indexPackage = modelPackage.substring(0, Math.max(0, modelPackage.lastIndexOf('.'))); + return indexPackage.replace('.', File.separatorChar); + } + + public void setStringEnums(boolean value) { + stringEnums = value; + } + + public Boolean getStringEnums() { + return stringEnums; + } + + public boolean getQueryParamObjectFormatDot() { + return QUERY_PARAM_OBJECT_FORMAT_TYPE.dot.equals(queryParamObjectFormat); + } + + public boolean getQueryParamObjectFormatJson() { + return QUERY_PARAM_OBJECT_FORMAT_TYPE.json.equals(queryParamObjectFormat); + } + + public boolean getQueryParamObjectFormatKey() { + return QUERY_PARAM_OBJECT_FORMAT_TYPE.key.equals(queryParamObjectFormat); + } + + @Override + public boolean isDataTypeFile(final String dataType) { + return "Blob".equals(dataType); + } + + @Override + public String getTypeDeclaration(Schema p) { + if (ModelUtils.isFileSchema(p)) { + return "Blob"; + } else { + return super.getTypeDeclaration(p); + } + } + + + private String applyLocalTypeMapping(String type) { + if (typeMapping.containsKey(type)) { + type = typeMapping.get(type); + } + return type; + } + + @Override + public void postProcessParameter(CodegenParameter parameter) { + super.postProcessParameter(parameter); + parameter.dataType = applyLocalTypeMapping(parameter.dataType); + } + + @Override + public OperationsMap postProcessOperationsWithModels(OperationsMap operations, List allModels) { + OperationMap objs = operations.getOperations(); + + // Add filename information for api imports + objs.put("apiFilename", getApiFilenameFromClassname(objs.getClassname())); + + List ops = objs.getOperation(); + boolean hasSomeFormParams = false; + boolean hasSomeEncodableParams = false; + for (CodegenOperation op : ops) { + if (op.getHasFormParams()) { + hasSomeFormParams = true; + } + op.httpMethod = op.httpMethod.toLowerCase(Locale.ENGLISH); + + + // Prep a string buffer where we're going to set up our new version of the string. + StringBuilder pathBuffer = new StringBuilder(); + ParameterExpander paramExpander = new ParameterExpander(op, this::toParamName); + int insideCurly = 0; + + // Iterate through existing string, one character at a time. + for (int i = 0; i < op.path.length(); i++) { + switch (op.path.charAt(i)) { + case '{': + // We entered curly braces, so track that. + insideCurly++; + break; + case '}': + // We exited curly braces, so track that. + insideCurly--; + + pathBuffer.append(paramExpander.buildPathEntry()); + hasSomeEncodableParams = true; + break; + default: + char nextChar = op.path.charAt(i); + if (insideCurly > 0) { + paramExpander.appendToParameterName(nextChar); + } else { + pathBuffer.append(nextChar); + } + break; + } + } + + // Overwrite path to TypeScript template string, after applying everything we just did. + op.path = pathBuffer.toString(); + } + + operations.put("hasSomeFormParams", hasSomeFormParams); + operations.put("hasSomeEncodableParams", hasSomeEncodableParams); + + // Add additional filename information for model imports in the services + List> imports = operations.getImports(); + for (Map im : imports) { + // This property is not used in the templates any more, subject for removal + im.put("filename", im.get("import")); + im.put("classname", im.get("classname")); + } + + return operations; + } + + @Override + public ModelsMap postProcessModels(ModelsMap objs) { + ModelsMap result = super.postProcessModels(objs); + return postProcessModelsEnum(result); + } + + @Override + public Map postProcessAllModels(Map objs) { + Map result = super.postProcessAllModels(objs); + for (ModelsMap entry : result.values()) { + for (ModelMap mo : entry.getModels()) { + CodegenModel cm = mo.getModel(); + if (taggedUnions) { + mo.put(TAGGED_UNIONS, true); + if (cm.discriminator != null && cm.children != null) { + for (CodegenModel child : cm.children) { + cm.imports.add(child.classname); + setChildDiscriminatorValue(cm, child); + } + } + + // with tagged union, a child model doesn't extend the parent (all properties are just copied over) + // it means we don't need to import that parent any more + if (cm.parent != null) { + cm.imports.remove(cm.parent); + + // however, it's possible that the child model contains a recursive reference to the parent + // in order to support this case, we update the list of imports from properties once again + for (CodegenProperty cp : cm.allVars) { + addImportsForPropertyType(cm, cp); + } + removeSelfReferenceImports(cm); + + } + } + // Add additional filename information for imports + Set parsedImports = parseImports(cm); + mo.put("tsImports", toTsImports(cm, parsedImports)); + } + } + return result; + } + + private void setChildDiscriminatorValue(CodegenModel parent, CodegenModel child) { + if (child.vendorExtensions.isEmpty() || + !child.vendorExtensions.containsKey("x-discriminator-value") + ) { + for (CodegenProperty prop : child.allVars) { + if (prop.baseName.equals(parent.discriminator.getPropertyName())) { + + for (CodegenDiscriminator.MappedModel mappedModel : parent.discriminator.getMappedModels()) { + if (mappedModel.getModelName().equals(child.classname)) { + prop.discriminatorValue = mappedModel.getMappingName(); + } + } + } + } + } + } + + /** + * Parse imports + */ + private Set parseImports(CodegenModel cm) { + Set newImports = new HashSet<>(); + if (cm.imports.size() > 0) { + for (String name : cm.imports) { + if (name.indexOf(" | ") >= 0) { + String[] parts = name.split(" \\| "); + Collections.addAll(newImports, parts); + } else { + newImports.add(name); + } + } + } + return newImports; + } + + private List> toTsImports(CodegenModel cm, Set imports) { + List> tsImports = new ArrayList<>(); + for (String im : imports) { + if (!im.equals(cm.classname)) { + HashMap tsImport = new HashMap<>(); + // TVG: This is used as class name in the import statements of the model file + tsImport.put("classname", im); + tsImport.put("filename", toModelFilename(removeModelPrefixSuffix(im))); + tsImports.add(tsImport); + } + } + return tsImports; + } + + @Override + public String toApiName(String name) { + if (name.length() == 0) { + return "DefaultService"; + } + return camelize(name) + serviceSuffix; + } + + @Override + public String toApiFilename(String name) { + if (name.length() == 0) { + return "default.service"; + } + return this.convertUsingFileNamingConvention(name) + serviceFileSuffix; + } + + @Override + public String toApiImport(String name) { + if (importMapping.containsKey(name)) { + return importMapping.get(name); + } + return apiPackage() + "/" + toApiFilename(name); + } + + @Override + public String toModelFilename(String name) { + if (importMapping.containsKey(name)) { + return importMapping.get(name); + } + return DEFAULT_IMPORT_PREFIX + this.convertUsingFileNamingConvention(super.toModelFilename(name)) + modelFileSuffix; + } + + @Override + public String toModelImport(String name) { + if (importMapping.containsKey(name)) { + return importMapping.get(name); + } + return DEFAULT_MODEL_IMPORT_DIRECTORY_PREFIX + modelPackage() + "/" + toModelFilename(name).substring(DEFAULT_IMPORT_PREFIX.length()); + } + + public String getNpmRepository() { + return npmRepository; + } + + public void setNpmRepository(String npmRepository) { + this.npmRepository = npmRepository; + } + + private boolean getUseSingleRequestParameter() { + return useSingleRequestParameter; + } + + private void setUseSingleRequestParameter(boolean useSingleRequestParameter) { + this.useSingleRequestParameter = useSingleRequestParameter; + } + + private String getApiFilenameFromClassname(String classname) { + String name = classname.substring(0, classname.length() - serviceSuffix.length()); + return toApiFilename(name); + } + + @Override + public String toModelName(String name) { + name = addSuffix(name, modelSuffix); + return super.toModelName(name); + } + + public String removeModelPrefixSuffix(String name) { + String result = name; + if (modelSuffix.length() > 0 && result.endsWith(modelSuffix)) { + result = result.substring(0, result.length() - modelSuffix.length()); + } + String prefix = capitalize(this.modelNamePrefix); + String suffix = capitalize(this.modelNameSuffix); + if (prefix.length() > 0 && result.startsWith(prefix)) { + result = result.substring(prefix.length()); + } + if (suffix.length() > 0 && result.endsWith(suffix)) { + result = result.substring(0, result.length() - suffix.length()); + } + + return result; + } + + /** + * Validates that the given string value only contains '-', '.' and alpha numeric characters. + * Throws an IllegalArgumentException, if the string contains any other characters. + * + * @param argument The name of the argument being validated. This is only used for displaying an error message. + * @param value The value that is being validated. + */ + private void validateFileSuffixArgument(String argument, String value) { + if (!value.matches(FILE_NAME_SUFFIX_PATTERN)) { + throw new IllegalArgumentException( + String.format(Locale.ROOT, "%s file suffix only allows '.', '-' and alphanumeric characters.", argument) + ); + } + } + + /** + * Validates that the given string value only contains alpha numeric characters. + * Throws an IllegalArgumentException, if the string contains any other characters. + * + * @param argument The name of the argument being validated. This is only used for displaying an error message. + * @param value The value that is being validated. + */ + private void validateClassPrefixArgument(String argument, String value) { + if (!value.matches(CLASS_NAME_PREFIX_PATTERN)) { + throw new IllegalArgumentException( + String.format(Locale.ROOT, "%s class prefix only allows alphanumeric characters.", argument) + ); + } + } + + /** + * Validates that the given string value only contains alpha numeric characters. + * Throws an IllegalArgumentException, if the string contains any other characters. + * + * @param argument The name of the argument being validated. This is only used for displaying an error message. + * @param value The value that is being validated. + */ + private void validateClassSuffixArgument(String argument, String value) { + if (!value.matches(CLASS_NAME_SUFFIX_PATTERN)) { + throw new IllegalArgumentException( + String.format(Locale.ROOT, "%s class suffix only allows alphanumeric characters.", argument) + ); + } + } + + /** + * Set the query param object format. + * + * @param format the query param object format to use + */ + public void setQueryParamObjectFormat(String format) { + try { + queryParamObjectFormat = QUERY_PARAM_OBJECT_FORMAT_TYPE.valueOf(format); + } catch (IllegalArgumentException e) { + String values = Stream.of(QUERY_PARAM_OBJECT_FORMAT_TYPE.values()) + .map(value -> "'" + value.name() + "'") + .collect(Collectors.joining(", ")); + + String msg = String.format(Locale.ROOT, "Invalid query param object format '%s'. Must be one of %s.", format, values); + throw new IllegalArgumentException(msg); + } + } + + /** + * Set the file naming type. + * + * @param fileNaming the file naming to use + */ + private void setFileNaming(String fileNaming) { + if ("camelCase".equals(fileNaming) || "kebab-case".equals(fileNaming)) { + this.fileNaming = fileNaming; + } else { + throw new IllegalArgumentException("Invalid file naming '" + + fileNaming + "'. Must be 'camelCase' or 'kebab-case'"); + } + } + + /** + * Converts the original name according to the current fileNaming strategy. + * + * @param originalName the original name to transform + * @return the transformed name + */ + private String convertUsingFileNamingConvention(String originalName) { + String name = this.removeModelPrefixSuffix(originalName); + if ("kebab-case".equals(fileNaming)) { + name = dashize(underscore(name)); + } else { + name = camelize(name, LOWERCASE_FIRST_LETTER); + } + return name; + } + + /** + * Set the Injectable level + * + * @param level the wanted level + */ + public void setProvidedIn(String level) { + try { + providedIn = PROVIDED_IN_LEVEL.valueOf(level); + } catch (IllegalArgumentException e) { + String values = Stream.of(PROVIDED_IN_LEVEL.values()) + .map(value -> "'" + value.name() + "'") + .collect(Collectors.joining(", ")); + + String msg = String.format(Locale.ROOT, "Invalid providedIn level '%s'. Must be one of %s.", level, values); + throw new IllegalArgumentException(msg); + } + } + + /** + * + */ + private boolean getIsProvidedInNone() { + return PROVIDED_IN_LEVEL.none.equals(providedIn); + } +} diff --git a/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig b/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig index b5bc56f2f8d..fc83fb96dbd 100644 --- a/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig +++ b/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig @@ -133,6 +133,7 @@ org.openapitools.codegen.languages.TypeScriptAxiosClientCodegen org.openapitools.codegen.languages.TypeScriptFetchClientCodegen org.openapitools.codegen.languages.TypeScriptInversifyClientCodegen org.openapitools.codegen.languages.TypeScriptJqueryClientCodegen +org.openapitools.codegen.languages.TypeScriptKoaServerCodegen org.openapitools.codegen.languages.TypeScriptNestjsClientCodegen org.openapitools.codegen.languages.TypeScriptNodeClientCodegen org.openapitools.codegen.languages.TypeScriptReduxQueryClientCodegen diff --git a/modules/openapi-generator/src/main/resources/typescript-koa-server/README.mustache b/modules/openapi-generator/src/main/resources/typescript-koa-server/README.mustache new file mode 100644 index 00000000000..3a65b9117ef --- /dev/null +++ b/modules/openapi-generator/src/main/resources/typescript-koa-server/README.mustache @@ -0,0 +1,226 @@ +## {{npmName}}@{{npmVersion}} + +### Building + +To install the required dependencies and to build the typescript sources run: +``` +npm install +npm run build +``` + +### publishing + +First build the package then run ```npm publish dist``` (don't forget to specify the `dist` folder!) + +### consuming + +Navigate to the folder of your consuming project and run one of next commands. + +_published:_ + +``` +npm install {{npmName}}@{{npmVersion}} --save +``` + +_without publishing (not recommended):_ + +``` +npm install PATH_TO_GENERATED_PACKAGE/dist.tgz --save +``` + +_It's important to take the tgz file, otherwise you'll get trouble with links on windows_ + +_using `npm link`:_ + +In PATH_TO_GENERATED_PACKAGE/dist: +``` +npm link +``` + +In your project: +``` +npm link {{npmName}} +``` + +__Note for Windows users:__ The Angular CLI has troubles to use linked npm packages. +Please refer to this issue https://github.com/angular/angular-cli/issues/8284 for a solution / workaround. +Published packages are not effected by this issue. + + +#### General usage + +In your Angular project: + + +``` +// without configuring providers +import { {{apiModuleClassName}} } from '{{npmName}}'; +import { HttpClientModule } from '@angular/common/http'; + +@NgModule({ + imports: [ + {{apiModuleClassName}}, + // make sure to import the HttpClientModule in the AppModule only, + // see https://github.com/angular/angular/issues/20575 + HttpClientModule + ], + declarations: [ AppComponent ], + providers: [], + bootstrap: [ AppComponent ] +}) +export class AppModule {} +``` + +``` +// configuring providers +import { {{apiModuleClassName}}, {{configurationClassName}}, {{configurationParametersInterfaceName}} } from '{{npmName}}'; + +export function apiConfigFactory (): {{configurationClassName}} { + const params: {{configurationParametersInterfaceName}} = { + // set configuration parameters here. + } + return new {{configurationClassName}}(params); +} + +@NgModule({ + imports: [ {{apiModuleClassName}}.forRoot(apiConfigFactory) ], + declarations: [ AppComponent ], + providers: [], + bootstrap: [ AppComponent ] +}) +export class AppModule {} +``` + +``` +// configuring providers with an authentication service that manages your access tokens +import { {{apiModuleClassName}}, {{configurationClassName}} } from '{{npmName}}'; + +@NgModule({ + imports: [ {{apiModuleClassName}} ], + declarations: [ AppComponent ], + providers: [ + { + provide: {{configurationClassName}}, + useFactory: (authService: AuthService) => new {{configurationClassName}}( + { + basePath: environment.apiUrl, + accessToken: authService.getAccessToken.bind(authService) + } + ), + deps: [AuthService], + multi: false + } + ], + bootstrap: [ AppComponent ] +}) +export class AppModule {} +``` + +``` +import { DefaultApi } from '{{npmName}}'; + +export class AppComponent { + constructor(private apiGateway: DefaultApi) { } +} +``` + +Note: The {{apiModuleClassName}} is restricted to being instantiated once app wide. +This is to ensure that all services are treated as singletons. + +#### Using multiple OpenAPI files / APIs / {{apiModuleClassName}}s +In order to use multiple `{{apiModuleClassName}}s` generated from different OpenAPI files, +you can create an alias name when importing the modules +in order to avoid naming conflicts: +``` +import { {{apiModuleClassName}} } from 'my-api-path'; +import { {{apiModuleClassName}} as OtherApiModule } from 'my-other-api-path'; +import { HttpClientModule } from '@angular/common/http'; + +@NgModule({ + imports: [ + {{apiModuleClassName}}, + OtherApiModule, + // make sure to import the HttpClientModule in the AppModule only, + // see https://github.com/angular/angular/issues/20575 + HttpClientModule + ] +}) +export class AppModule { + +} +``` + + +### Set service base path +If different than the generated base path, during app bootstrap, you can provide the base path to your service. + +``` +import { BASE_PATH } from '{{npmName}}'; + +bootstrap(AppComponent, [ + { provide: BASE_PATH, useValue: 'https://your-web-service.com' }, +]); +``` +or + +``` +import { BASE_PATH } from '{{npmName}}'; + +@NgModule({ + imports: [], + declarations: [ AppComponent ], + providers: [ provide: BASE_PATH, useValue: 'https://your-web-service.com' ], + bootstrap: [ AppComponent ] +}) +export class AppModule {} +``` + + +#### Using @angular/cli +First extend your `src/environments/*.ts` files by adding the corresponding base path: + +``` +export const environment = { + production: false, + API_BASE_PATH: 'http://127.0.0.1:8080' +}; +``` + +In the src/app/app.module.ts: +``` +import { BASE_PATH } from '{{npmName}}'; +import { environment } from '../environments/environment'; + +@NgModule({ + declarations: [ + AppComponent + ], + imports: [ ], + providers: [{ provide: BASE_PATH, useValue: environment.API_BASE_PATH }], + bootstrap: [ AppComponent ] +}) +export class AppModule { } +``` + +### Customizing path parameter encoding + +Without further customization, only [path-parameters][parameter-locations-url] of [style][style-values-url] 'simple' +and Dates for format 'date-time' are encoded correctly. + +Other styles (e.g. "matrix") are not that easy to encode +and thus are best delegated to other libraries (e.g.: [@honoluluhenk/http-param-expander]). + +To implement your own parameter encoding (or call another library), +pass an arrow-function or method-reference to the `encodeParam` property of the Configuration-object +(see [General Usage](#general-usage) above). + +Example value for use in your Configuration-Provider: +```typescript +new Configuration({ + encodeParam: (param: Param) => myFancyParamEncoder(param), +}) +``` + +[parameter-locations-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-locations +[style-values-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#style-values +[@honoluluhenk/http-param-expander]: https://www.npmjs.com/package/@honoluluhenk/http-param-expander diff --git a/modules/openapi-generator/src/main/resources/typescript-koa-server/api.module.mustache b/modules/openapi-generator/src/main/resources/typescript-koa-server/api.module.mustache new file mode 100644 index 00000000000..428af5e48b8 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/typescript-koa-server/api.module.mustache @@ -0,0 +1,37 @@ +import { NgModule, ModuleWithProviders, SkipSelf, Optional } from '@angular/core'; +import { {{configurationClassName}} } from './configuration'; +import { HttpClient } from '@angular/common/http'; + +{{#apiInfo}} +{{#apis}} +import { {{classname}} } from './{{importPath}}'; +{{/apis}} +{{/apiInfo}} + +@NgModule({ + imports: [], + declarations: [], + exports: [], + providers: [{{#isProvidedInNone}} + {{#apiInfo}}{{#apis}}{{classname}}{{^-last}}, + {{/-last}}{{/apis}}{{/apiInfo}} {{/isProvidedInNone}}] +}) +export class {{apiModuleClassName}} { + public static forRoot(configurationFactory: () => {{configurationClassName}}): ModuleWithProviders{{#enforceGenericModuleWithProviders}}<{{apiModuleClassName}}>{{/enforceGenericModuleWithProviders}} { + return { + ngModule: {{apiModuleClassName}}, + providers: [ { provide: {{configurationClassName}}, useFactory: configurationFactory } ] + }; + } + + constructor( @Optional() @SkipSelf() parentModule: {{apiModuleClassName}}, + @Optional() http: HttpClient) { + if (parentModule) { + throw new Error('{{apiModuleClassName}} is already loaded. Import in your base AppModule only.'); + } + if (!http) { + throw new Error('You need to import the HttpClientModule in your AppModule! \n' + + 'See also https://github.com/angular/angular/issues/20575'); + } + } +} diff --git a/modules/openapi-generator/src/main/resources/typescript-koa-server/api.service.mustache b/modules/openapi-generator/src/main/resources/typescript-koa-server/api.service.mustache new file mode 100644 index 00000000000..bd59162b7bb --- /dev/null +++ b/modules/openapi-generator/src/main/resources/typescript-koa-server/api.service.mustache @@ -0,0 +1,404 @@ +{{>licenseInfo}} +/* tslint:disable:no-unused-variable member-ordering */ + +import { Inject, Injectable, Optional } from '@angular/core'; +import { HttpClient, HttpHeaders, HttpParams, + HttpResponse, HttpEvent, HttpParameterCodec{{#httpContextInOptions}}, HttpContext {{/httpContextInOptions}} + } from '@angular/common/http'; +import { CustomHttpParameterCodec } from '../encoder'; +import { Observable } from 'rxjs'; + +{{#imports}} +// @ts-ignore +import { {{ classname }} } from '{{ filename }}'; +{{/imports}} + +// @ts-ignore +import { BASE_PATH, COLLECTION_FORMATS } from '../variables'; +import { {{configurationClassName}} } from '../configuration'; +{{#withInterfaces}} +import { + {{classname}}Interface{{#useSingleRequestParameter}}{{#operations}}{{#operation}}{{#allParams.0}}, + {{#prefixParameterInterfaces}}{{classname}}{{/prefixParameterInterfaces}}{{operationIdCamelCase}}RequestParams{{/allParams.0}}{{/operation}}{{/operations}}{{/useSingleRequestParameter}} +} from './{{classFilename}}Interface'; +{{/withInterfaces}} + +{{#operations}} + +{{^withInterfaces}} +{{#useSingleRequestParameter}} +{{#operation}} +{{#allParams.0}} +export interface {{#prefixParameterInterfaces}}{{classname}}{{/prefixParameterInterfaces}}{{operationIdCamelCase}}RequestParams { +{{#allParams}} + {{#description}}/** {{.}} */ + {{/description}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}{{#isNullable}} | null{{/isNullable}}; +{{/allParams}} +} + +{{/allParams.0}} +{{/operation}} +{{/useSingleRequestParameter}} +{{/withInterfaces}} + +{{#description}} +/** + * {{&description}} + */ +{{/description}} +{{#isProvidedInNone}} +@Injectable() +{{/isProvidedInNone}} +{{^isProvidedInNone}} +@Injectable({ + providedIn: '{{providedIn}}' +}) +{{/isProvidedInNone}} +{{#withInterfaces}} +export class {{classname}} implements {{classname}}Interface { +{{/withInterfaces}} +{{^withInterfaces}} +export class {{classname}} { +{{/withInterfaces}} + + protected basePath = '{{{basePath}}}'; + public defaultHeaders = new HttpHeaders(); + public configuration = new {{configurationClassName}}(); + public encoder: HttpParameterCodec; + + constructor(protected httpClient: HttpClient, @Optional()@Inject(BASE_PATH) basePath: string|string[], @Optional() configuration: {{configurationClassName}}) { + if (configuration) { + this.configuration = configuration; + } + if (typeof this.configuration.basePath !== 'string') { + if (Array.isArray(basePath) && basePath.length > 0) { + basePath = basePath[0]; + } + + if (typeof basePath !== 'string') { + basePath = this.basePath; + } + this.configuration.basePath = basePath; + } + this.encoder = this.configuration.encoder || new CustomHttpParameterCodec(); + } + +{{#hasSomeFormParams}} + /** + * @param consumes string[] mime-types + * @return true: consumes contains 'multipart/form-data', false: otherwise + */ + private canConsumeForm(consumes: string[]): boolean { + const form = 'multipart/form-data'; + for (const consume of consumes) { + if (form === consume) { + return true; + } + } + return false; + } +{{/hasSomeFormParams}} + + // @ts-ignore + private addToHttpParams(httpParams: HttpParams, value: any, key?: string): HttpParams { + {{#isQueryParamObjectFormatJson}} + httpParams = this.addToHttpParamsRecursive(httpParams, value, key); + {{/isQueryParamObjectFormatJson}} + {{^isQueryParamObjectFormatJson}} + if (typeof value === "object" && value instanceof Date === false) { + httpParams = this.addToHttpParamsRecursive(httpParams, value); + } else { + httpParams = this.addToHttpParamsRecursive(httpParams, value, key); + } + {{/isQueryParamObjectFormatJson}} + return httpParams; + } + + private addToHttpParamsRecursive(httpParams: HttpParams, value?: any, key?: string): HttpParams { + if (value == null) { + return httpParams; + } + + if (typeof value === "object") { + {{#isQueryParamObjectFormatJson}} + if (key != null) { + httpParams = httpParams.append(key, JSON.stringify(value)); + } else { + throw Error("key may not be null if value is a QueryParamObject"); + } + {{/isQueryParamObjectFormatJson}} + {{^isQueryParamObjectFormatJson}} + if (Array.isArray(value)) { + (value as any[]).forEach( elem => httpParams = this.addToHttpParamsRecursive(httpParams, elem, key)); + } else if (value instanceof Date) { + if (key != null) { + httpParams = httpParams.append(key, (value as Date).toISOString(){{^isDateTime}}.substr(0, 10){{/isDateTime}}); + } else { + throw Error("key may not be null if value is Date"); + } + } else { + Object.keys(value).forEach( k => httpParams = this.addToHttpParamsRecursive( + httpParams, value[k], key != null ? `${key}{{#isQueryParamObjectFormatDot}}.{{/isQueryParamObjectFormatDot}}{{#isQueryParamObjectFormatKey}}[{{/isQueryParamObjectFormatKey}}${k}{{#isQueryParamObjectFormatKey}}]{{/isQueryParamObjectFormatKey}}` : k)); + } + {{/isQueryParamObjectFormatJson}} + } else if (key != null) { + httpParams = httpParams.append(key, value); + } else { + throw Error("key may not be null if value is not object or array"); + } + return httpParams; + } + +{{#operation}} + /** +{{#summary}} + * {{.}} +{{/summary}} +{{#notes}} + * {{.}} +{{/notes}} + {{^useSingleRequestParameter}} + {{#allParams}} + * @param {{paramName}} {{description}} + {{/allParams}} + {{/useSingleRequestParameter}} + {{#useSingleRequestParameter}} + {{#allParams.0}} + * @param requestParameters + {{/allParams.0}} + {{/useSingleRequestParameter}} + * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. + * @param reportProgress flag to report request and response progress. + {{#isDeprecated}} + * @deprecated + {{/isDeprecated}} + */ + public {{nickname}}({{^useSingleRequestParameter}}{{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}, {{/allParams}}{{/useSingleRequestParameter}}{{#useSingleRequestParameter}}{{#allParams.0}}requestParameters: {{#prefixParameterInterfaces}}{{classname}}{{/prefixParameterInterfaces}}{{operationIdCamelCase}}RequestParams, {{/allParams.0}}{{/useSingleRequestParameter}}observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: {{#produces}}'{{mediaType}}'{{^-last}} | {{/-last}}{{/produces}}{{^produces}}undefined{{/produces}},{{#httpContextInOptions}} context?: HttpContext{{/httpContextInOptions}}}): Observable<{{#returnType}}{{{returnType}}}{{#isResponseTypeFile}}|undefined{{/isResponseTypeFile}}{{/returnType}}{{^returnType}}any{{/returnType}}>; + public {{nickname}}({{^useSingleRequestParameter}}{{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}, {{/allParams}}{{/useSingleRequestParameter}}{{#useSingleRequestParameter}}{{#allParams.0}}requestParameters: {{#prefixParameterInterfaces}}{{classname}}{{/prefixParameterInterfaces}}{{operationIdCamelCase}}RequestParams, {{/allParams.0}}{{/useSingleRequestParameter}}observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: {{#produces}}'{{mediaType}}'{{^-last}} | {{/-last}}{{/produces}}{{^produces}}undefined{{/produces}},{{#httpContextInOptions}} context?: HttpContext{{/httpContextInOptions}}}): Observable>; + public {{nickname}}({{^useSingleRequestParameter}}{{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}, {{/allParams}}{{/useSingleRequestParameter}}{{#useSingleRequestParameter}}{{#allParams.0}}requestParameters: {{#prefixParameterInterfaces}}{{classname}}{{/prefixParameterInterfaces}}{{operationIdCamelCase}}RequestParams, {{/allParams.0}}{{/useSingleRequestParameter}}observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: {{#produces}}'{{mediaType}}'{{^-last}} | {{/-last}}{{/produces}}{{^produces}}undefined{{/produces}},{{#httpContextInOptions}} context?: HttpContext{{/httpContextInOptions}}}): Observable>; + public {{nickname}}({{^useSingleRequestParameter}}{{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}, {{/allParams}}{{/useSingleRequestParameter}}{{#useSingleRequestParameter}}{{#allParams.0}}requestParameters: {{#prefixParameterInterfaces}}{{classname}}{{/prefixParameterInterfaces}}{{operationIdCamelCase}}RequestParams, {{/allParams.0}}{{/useSingleRequestParameter}}observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: {{#produces}}'{{mediaType}}'{{^-last}} | {{/-last}}{{/produces}}{{^produces}}undefined{{/produces}},{{#httpContextInOptions}} context?: HttpContext{{/httpContextInOptions}}}): Observable { +{{#allParams}} +{{#useSingleRequestParameter}} + const {{paramName}} = requestParameters.{{paramName}}; +{{/useSingleRequestParameter}} +{{#required}} + if ({{paramName}} === null || {{paramName}} === undefined) { + throw new Error('Required parameter {{paramName}} was null or undefined when calling {{nickname}}.'); + } +{{/required}} +{{/allParams}} + +{{#hasQueryParamsOrAuth}} + let localVarQueryParameters = new HttpParams({encoder: this.encoder}); +{{#queryParams}} + {{#isArray}} + if ({{paramName}}) { + {{#isQueryParamObjectFormatJson}} + localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, + {{paramName}}, '{{baseName}}'); + {{/isQueryParamObjectFormatJson}} + {{^isQueryParamObjectFormatJson}} + {{#isCollectionFormatMulti}} + {{paramName}}.forEach((element) => { + localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, + element, '{{baseName}}'); + }) + {{/isCollectionFormatMulti}} + {{^isCollectionFormatMulti}} + localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, + [...{{paramName}}].join(COLLECTION_FORMATS['{{collectionFormat}}']), '{{baseName}}'); + {{/isCollectionFormatMulti}} + {{/isQueryParamObjectFormatJson}} + } + {{/isArray}} + {{^isArray}} + if ({{paramName}} !== undefined && {{paramName}} !== null) { + localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, + {{paramName}}, '{{baseName}}'); + } + {{/isArray}} +{{/queryParams}} + +{{/hasQueryParamsOrAuth}} + let localVarHeaders = this.defaultHeaders; +{{#headerParams}} + {{#isArray}} + if ({{paramName}}) { + localVarHeaders = localVarHeaders.set('{{baseName}}', [...{{paramName}}].join(COLLECTION_FORMATS['{{collectionFormat}}'])); + } + {{/isArray}} + {{^isArray}} + if ({{paramName}} !== undefined && {{paramName}} !== null) { + localVarHeaders = localVarHeaders.set('{{baseName}}', String({{paramName}})); + } + {{/isArray}} +{{/headerParams}} + +{{#authMethods}} +{{#-first}} + let localVarCredential: string | undefined; +{{/-first}} + // authentication ({{name}}) required + localVarCredential = this.configuration.lookupCredential('{{name}}'); + if (localVarCredential) { +{{#isApiKey}} + {{#isKeyInHeader}} + localVarHeaders = localVarHeaders.set('{{keyParamName}}', localVarCredential); + {{/isKeyInHeader}} + {{#isKeyInQuery}} + localVarQueryParameters = localVarQueryParameters.set('{{keyParamName}}', localVarCredential); + {{/isKeyInQuery}} +{{/isApiKey}} +{{#isBasic}} + {{#isBasicBasic}} + localVarHeaders = localVarHeaders.set('Authorization', 'Basic ' + localVarCredential); + {{/isBasicBasic}} + {{#isBasicBearer}} + localVarHeaders = localVarHeaders.set('Authorization', 'Bearer ' + localVarCredential); + {{/isBasicBearer}} +{{/isBasic}} +{{#isOAuth}} + localVarHeaders = localVarHeaders.set('Authorization', 'Bearer ' + localVarCredential); +{{/isOAuth}} + } + +{{/authMethods}} + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + {{#produces}} + '{{{mediaType}}}'{{^-last}},{{/-last}} + {{/produces}} + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + +{{#httpContextInOptions}} + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } +{{/httpContextInOptions}} + +{{#bodyParam}} +{{- duplicated below, don't forget to change}} + // to determine the Content-Type header + const consumes: string[] = [ + {{#consumes}} + '{{{mediaType}}}'{{^-last}},{{/-last}} + {{/consumes}} + ]; +{{/bodyParam}} +{{#hasFormParams}} +{{^bodyParam}} + // to determine the Content-Type header + const consumes: string[] = [ + {{#consumes}} + '{{{mediaType}}}'{{^-last}},{{/-last}} + {{/consumes}} + ]; +{{/bodyParam}} +{{/hasFormParams}} +{{#bodyParam}} + const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes); + if (httpContentTypeSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Content-Type', httpContentTypeSelected); + } +{{/bodyParam}} + +{{#hasFormParams}} + const canConsumeForm = this.canConsumeForm(consumes); + + let localVarFormParams: { append(param: string, value: any): any; }; + let localVarUseForm = false; + let localVarConvertFormParamsToString = false; +{{#formParams}} +{{#isFile}} + // use FormData to transmit files using content-type "multipart/form-data" + // see https://stackoverflow.com/questions/4007969/application-x-www-form-urlencoded-or-multipart-form-data + localVarUseForm = canConsumeForm; +{{/isFile}} +{{/formParams}} + if (localVarUseForm) { + localVarFormParams = new FormData(); + } else { + localVarFormParams = new HttpParams({encoder: this.encoder}); + } + +{{#formParams}} + {{#isArray}} + if ({{paramName}}) { + {{#isCollectionFormatMulti}} + {{paramName}}.forEach((element) => { + localVarFormParams = localVarFormParams.append('{{baseName}}', element) as any || localVarFormParams; + }) + {{/isCollectionFormatMulti}} + {{^isCollectionFormatMulti}} + if (localVarUseForm) { + {{paramName}}.forEach((element) => { + localVarFormParams = localVarFormParams.append('{{baseName}}', element) as any || localVarFormParams; + }) + } else { + localVarFormParams = localVarFormParams.append('{{baseName}}', [...{{paramName}}].join(COLLECTION_FORMATS['{{collectionFormat}}'])) as any || localVarFormParams; + } + {{/isCollectionFormatMulti}} + } + {{/isArray}} + {{^isArray}} + if ({{paramName}} !== undefined) { + localVarFormParams = localVarFormParams.append('{{baseName}}', {{^isModel}}{{paramName}}{{/isModel}}{{#isModel}}localVarUseForm ? new Blob([JSON.stringify({{paramName}})], {type: 'application/json'}) : {{paramName}}{{/isModel}}) as any || localVarFormParams; + } + {{/isArray}} +{{/formParams}} + +{{/hasFormParams}} + {{^isResponseFile}} + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + {{/isResponseFile}} + let localVarPath = `{{{path}}}`; + return this.httpClient.request{{^isResponseFile}}<{{#returnType}}{{{returnType}}}{{#isResponseTypeFile}}|undefined{{/isResponseTypeFile}}{{/returnType}}{{^returnType}}any{{/returnType}}>{{/isResponseFile}}('{{httpMethod}}', `${this.configuration.basePath}${localVarPath}`, + { + {{#httpContextInOptions}} + context: localVarHttpContext, + {{/httpContextInOptions}} + {{#bodyParam}} + body: {{paramName}}, + {{/bodyParam}} + {{^bodyParam}} + {{#hasFormParams}} + body: localVarConvertFormParamsToString ? localVarFormParams.toString() : localVarFormParams, + {{/hasFormParams}} + {{/bodyParam}} + {{#hasQueryParamsOrAuth}} + params: localVarQueryParameters, + {{/hasQueryParamsOrAuth}} + {{#isResponseFile}} + responseType: "blob", + {{/isResponseFile}} + {{^isResponseFile}} + responseType: responseType_, + {{/isResponseFile}} + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); + } + +{{/operation}}} +{{/operations}} diff --git a/modules/openapi-generator/src/main/resources/typescript-koa-server/apiInterface.mustache b/modules/openapi-generator/src/main/resources/typescript-koa-server/apiInterface.mustache new file mode 100644 index 00000000000..3a2124949da --- /dev/null +++ b/modules/openapi-generator/src/main/resources/typescript-koa-server/apiInterface.mustache @@ -0,0 +1,51 @@ +{{>licenseInfo}} +import { HttpHeaders } from '@angular/common/http'; + +import { Observable } from 'rxjs'; + +{{#imports}} +import { {{classname}} } from '../model/models'; +{{/imports}} + + +import { {{configurationClassName}} } from '../configuration'; + +{{#operations}} + +{{#useSingleRequestParameter}} +{{#operation}} +{{#allParams.0}} +export interface {{#prefixParameterInterfaces}}{{classname}}{{/prefixParameterInterfaces}}{{operationIdCamelCase}}RequestParams { +{{#allParams}} + {{paramName}}{{^required}}?{{/required}}: {{{dataType}}}{{#isNullable}} | null{{/isNullable}}; +{{/allParams}} +} + +{{/allParams.0}} +{{/operation}} +{{/useSingleRequestParameter}} + +{{#description}} + /** + * {{&description}} + */ +{{/description}} +export interface {{classname}}Interface { + defaultHeaders: HttpHeaders; + configuration: {{configurationClassName}}; + +{{#operation}} + /** + * {{summary}} + * {{notes}} + {{^useSingleRequestParameter}} + {{#allParams}}* @param {{paramName}} {{description}} + {{/allParams}}{{/useSingleRequestParameter}}{{#useSingleRequestParameter}}{{#allParams.0}}* @param requestParameters + {{/allParams.0}}{{/useSingleRequestParameter}}{{#isDeprecated}} + * @deprecated + {{/isDeprecated}}*/ + {{nickname}}({{^useSingleRequestParameter}}{{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}, {{/allParams}}{{/useSingleRequestParameter}}{{#useSingleRequestParameter}}{{#allParams.0}}requestParameters: {{#prefixParameterInterfaces}}{{classname}}{{/prefixParameterInterfaces}}{{operationIdCamelCase}}RequestParams, {{/allParams.0}}{{/useSingleRequestParameter}}extraHttpRequestParams?: any): Observable<{{{returnType}}}{{^returnType}}{}{{/returnType}}>; + +{{/operation}} +} +{{/operations}} diff --git a/modules/openapi-generator/src/main/resources/typescript-koa-server/apis.mustache b/modules/openapi-generator/src/main/resources/typescript-koa-server/apis.mustache new file mode 100644 index 00000000000..ad8785cf8cd --- /dev/null +++ b/modules/openapi-generator/src/main/resources/typescript-koa-server/apis.mustache @@ -0,0 +1,12 @@ +{{#apiInfo}} +{{#apis}} +{{#operations}} +export * from './{{ classFilename }}'; +import { {{ classname }} } from './{{ classFilename }}'; +{{/operations}} +{{#withInterfaces}} +export * from './{{ classFilename }}Interface'; +{{/withInterfaces}} +{{/apis}} +export const APIS = [{{#apis}}{{#operations}}{{ classname }}{{/operations}}{{^-last}}, {{/-last}}{{/apis}}]; +{{/apiInfo}} diff --git a/modules/openapi-generator/src/main/resources/typescript-koa-server/app.ts.mustache b/modules/openapi-generator/src/main/resources/typescript-koa-server/app.ts.mustache new file mode 100644 index 00000000000..a1005874c98 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/typescript-koa-server/app.ts.mustache @@ -0,0 +1,17 @@ +import { Server } from 'http' +import { print } from 'configs/utils' +import CONSTANTS from 'configs/constants' +import createServer from 'configs/application' +import { bootstrapAfter } from 'configs/bootstrap' + +module.exports = (async (): Promise => { + try { + const app = await createServer() + return app.listen(CONSTANTS.PORT, () => { + print.log(`server listening on ${CONSTANTS.PORT}, in ${CONSTANTS.ENV_LABEL} mode.`) + bootstrapAfter() + }) + } catch (e) { + console.log(e) + } +})() diff --git a/modules/openapi-generator/src/main/resources/typescript-koa-server/build.js.mustache b/modules/openapi-generator/src/main/resources/typescript-koa-server/build.js.mustache new file mode 100644 index 00000000000..46cf590d004 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/typescript-koa-server/build.js.mustache @@ -0,0 +1,19 @@ +const { nodeExternalsPlugin } = require('esbuild-node-externals') + +require('esbuild') + .build({ + entryPoints: ['app.ts'], + bundle: true, + outfile: 'dist/index.js', + platform: 'node', + plugins: [ + nodeExternalsPlugin({ + dependencies: false, + }), + ], + external: ['cors', 'kcors'], + }) + .catch(err => { + console.log(err) + process.exit(1) + }) diff --git a/modules/openapi-generator/src/main/resources/typescript-koa-server/configuration.mustache b/modules/openapi-generator/src/main/resources/typescript-koa-server/configuration.mustache new file mode 100644 index 00000000000..39f73f8e2a5 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/typescript-koa-server/configuration.mustache @@ -0,0 +1,205 @@ +import { HttpParameterCodec } from '@angular/common/http'; +import { Param } from './param'; + +export interface {{configurationParametersInterfaceName}} { + /** + * @deprecated Since 5.0. Use credentials instead + */ + apiKeys?: {[ key: string ]: string}; + username?: string; + password?: string; + /** + * @deprecated Since 5.0. Use credentials instead + */ + accessToken?: string | (() => string); + basePath?: string; + withCredentials?: boolean; + /** + * Takes care of encoding query- and form-parameters. + */ + encoder?: HttpParameterCodec; + /** + * Override the default method for encoding path parameters in various + * styles. + *

+ * See {@link README.md} for more details + *

+ */ + encodeParam?: (param: Param) => string; + /** + * The keys are the names in the securitySchemes section of the OpenAPI + * document. They should map to the value used for authentication + * minus any standard prefixes such as 'Basic' or 'Bearer'. + */ + credentials?: {[ key: string ]: string | (() => string | undefined)}; +} + +export class {{configurationClassName}} { + /** + * @deprecated Since 5.0. Use credentials instead + */ + apiKeys?: {[ key: string ]: string}; + username?: string; + password?: string; + /** + * @deprecated Since 5.0. Use credentials instead + */ + accessToken?: string | (() => string); + basePath?: string; + withCredentials?: boolean; + /** + * Takes care of encoding query- and form-parameters. + */ + encoder?: HttpParameterCodec; + /** + * Encoding of various path parameter + * styles. + *

+ * See {@link README.md} for more details + *

+ */ + encodeParam: (param: Param) => string; + /** + * The keys are the names in the securitySchemes section of the OpenAPI + * document. They should map to the value used for authentication + * minus any standard prefixes such as 'Basic' or 'Bearer'. + */ + credentials: {[ key: string ]: string | (() => string | undefined)}; + + constructor(configurationParameters: {{configurationParametersInterfaceName}} = {}) { + this.apiKeys = configurationParameters.apiKeys; + this.username = configurationParameters.username; + this.password = configurationParameters.password; + this.accessToken = configurationParameters.accessToken; + this.basePath = configurationParameters.basePath; + this.withCredentials = configurationParameters.withCredentials; + this.encoder = configurationParameters.encoder; + if (configurationParameters.encodeParam) { + this.encodeParam = configurationParameters.encodeParam; + } + else { + this.encodeParam = param => this.defaultEncodeParam(param); + } + if (configurationParameters.credentials) { + this.credentials = configurationParameters.credentials; + } + else { + this.credentials = {}; + } +{{#authMethods}} + + // init default {{name}} credential + if (!this.credentials['{{name}}']) { +{{#isApiKey}} + this.credentials['{{name}}'] = () => { + {{! Fallback behaviour may be removed for 5.0 release. See #5062 }} + if (this.apiKeys === null || this.apiKeys === undefined) { + return undefined; + } else { + return this.apiKeys['{{name}}'] || this.apiKeys['{{keyParamName}}']; + } + }; +{{/isApiKey}} +{{#isBasic}} + {{#isBasicBasic}} + this.credentials['{{name}}'] = () => { + return (this.username || this.password) + ? btoa(this.username + ':' + this.password) + : undefined; + }; + {{/isBasicBasic}} + {{#isBasicBearer}} + this.credentials['{{name}}'] = () => { + return typeof this.accessToken === 'function' + ? this.accessToken() + : this.accessToken; + }; + {{/isBasicBearer}} +{{/isBasic}} +{{#isOAuth}} + this.credentials['{{name}}'] = () => { + return typeof this.accessToken === 'function' + ? this.accessToken() + : this.accessToken; + }; +{{/isOAuth}} + } +{{/authMethods}} + } + + /** + * Select the correct content-type to use for a request. + * Uses {@link {{configurationClassName}}#isJsonMime} to determine the correct content-type. + * If no content type is found return the first found type if the contentTypes is not empty + * @param contentTypes - the array of content types that are available for selection + * @returns the selected content-type or undefined if no selection could be made. + */ + public selectHeaderContentType (contentTypes: string[]): string | undefined { + if (contentTypes.length === 0) { + return undefined; + } + + const type = contentTypes.find((x: string) => this.isJsonMime(x)); + if (type === undefined) { + return contentTypes[0]; + } + return type; + } + + /** + * Select the correct accept content-type to use for a request. + * Uses {@link {{configurationClassName}}#isJsonMime} to determine the correct accept content-type. + * If no content type is found return the first found type if the contentTypes is not empty + * @param accepts - the array of content types that are available for selection. + * @returns the selected content-type or undefined if no selection could be made. + */ + public selectHeaderAccept(accepts: string[]): string | undefined { + if (accepts.length === 0) { + return undefined; + } + + const type = accepts.find((x: string) => this.isJsonMime(x)); + if (type === undefined) { + return accepts[0]; + } + return type; + } + + /** + * Check if the given MIME is a JSON MIME. + * JSON MIME examples: + * application/json + * application/json; charset=UTF8 + * APPLICATION/JSON + * application/vnd.company+json + * @param mime - MIME (Multipurpose Internet Mail Extensions) + * @return True if the given MIME is JSON, false otherwise. + */ + public isJsonMime(mime: string): boolean { + const jsonMime: RegExp = new RegExp('^(application\/json|[^;/ \t]+\/[^;/ \t]+[+]json)[ \t]*(;.*)?$', 'i'); + return mime !== null && (jsonMime.test(mime) || mime.toLowerCase() === 'application/json-patch+json'); + } + + public lookupCredential(key: string): string | undefined { + const value = this.credentials[key]; + return typeof value === 'function' + ? value() + : value; + } + + private defaultEncodeParam(param: Param): string { + // This implementation exists as fallback for missing configuration + // and for backwards compatibility to older typescript-angular generator versions. + // It only works for the 'simple' parameter style. + // Date-handling only works for the 'date-time' format. + // All other styles and Date-formats are probably handled incorrectly. + // + // But: if that's all you need (i.e.: the most common use-case): no need for customization! + + const value = param.dataFormat === 'date-time' && param.value instanceof Date + ? (param.value as Date).toISOString() + : param.value; + + return encodeURIComponent(String(value)); + } +} diff --git a/modules/openapi-generator/src/main/resources/typescript-koa-server/docker-compose.mustache b/modules/openapi-generator/src/main/resources/typescript-koa-server/docker-compose.mustache new file mode 100644 index 00000000000..7f4274b4a93 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/typescript-koa-server/docker-compose.mustache @@ -0,0 +1,18 @@ +version: '3.3' + +services: + restapi.postgres: + container_name: koa-ts + image: postgres:13 + volumes: + - postgres:/var/lib/postgres + restart: always + ports: + - ${POSTGRES_PORT}:${POSTGRES_PORT} + env_file: + - ./.env + labels: + com.startupteam.description: "postgres container for koa-ts" + +volumes: + postgres: {} diff --git a/modules/openapi-generator/src/main/resources/typescript-koa-server/encoder.mustache b/modules/openapi-generator/src/main/resources/typescript-koa-server/encoder.mustache new file mode 100644 index 00000000000..138c4d5cf2c --- /dev/null +++ b/modules/openapi-generator/src/main/resources/typescript-koa-server/encoder.mustache @@ -0,0 +1,20 @@ +import { HttpParameterCodec } from '@angular/common/http'; + +/** + * Custom HttpParameterCodec + * Workaround for https://github.com/angular/angular/issues/18261 + */ +export class CustomHttpParameterCodec implements HttpParameterCodec { + encodeKey(k: string): string { + return encodeURIComponent(k); + } + encodeValue(v: string): string { + return encodeURIComponent(v); + } + decodeKey(k: string): string { + return decodeURIComponent(k); + } + decodeValue(v: string): string { + return decodeURIComponent(v); + } +} diff --git a/modules/openapi-generator/src/main/resources/typescript-koa-server/env.example.mustache b/modules/openapi-generator/src/main/resources/typescript-koa-server/env.example.mustache new file mode 100644 index 00000000000..6226e11d9d5 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/typescript-koa-server/env.example.mustache @@ -0,0 +1,6 @@ +ENV=development +POSTGRES_USER=root +POSTGRES_PASSWORD=rootpassword +POSTGRES_DB=dev +POSTGRES_PORT=5432 +DATABASE_URL='postgresql://root:rootpassword@localhost:5432/dev?schema=public' diff --git a/modules/openapi-generator/src/main/resources/typescript-koa-server/git_push.sh.mustache b/modules/openapi-generator/src/main/resources/typescript-koa-server/git_push.sh.mustache new file mode 100755 index 00000000000..0e3776ae6dd --- /dev/null +++ b/modules/openapi-generator/src/main/resources/typescript-koa-server/git_push.sh.mustache @@ -0,0 +1,57 @@ +#!/bin/sh +# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/ +# +# Usage example: /bin/sh ./git_push.sh wing328 openapi-petstore-perl "minor update" "gitlab.com" + +git_user_id=$1 +git_repo_id=$2 +release_note=$3 +git_host=$4 + +if [ "$git_host" = "" ]; then + git_host="{{{gitHost}}}" + echo "[INFO] No command line input provided. Set \$git_host to $git_host" +fi + +if [ "$git_user_id" = "" ]; then + git_user_id="{{{gitUserId}}}" + echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" +fi + +if [ "$git_repo_id" = "" ]; then + git_repo_id="{{{gitRepoId}}}" + echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" +fi + +if [ "$release_note" = "" ]; then + release_note="{{{releaseNote}}}" + echo "[INFO] No command line input provided. Set \$release_note to $release_note" +fi + +# Initialize the local directory as a Git repository +git init + +# Adds the files in the local repository and stages them for commit. +git add . + +# Commits the tracked changes and prepares them to be pushed to a remote repository. +git commit -m "$release_note" + +# Sets the new remote +git_remote=$(git remote) +if [ "$git_remote" = "" ]; then # git remote not defined + + if [ "$GIT_TOKEN" = "" ]; then + echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." + git remote add origin https://${git_host}/${git_user_id}/${git_repo_id}.git + else + git remote add origin https://${git_user_id}:"${GIT_TOKEN}"@${git_host}/${git_user_id}/${git_repo_id}.git + fi + +fi + +git pull origin master + +# Pushes (Forces) the changes in the local repository up to the remote repository +echo "Git pushing to https://${git_host}/${git_user_id}/${git_repo_id}.git" +git push origin master 2>&1 | grep -v 'To https' diff --git a/modules/openapi-generator/src/main/resources/typescript-koa-server/gitignore b/modules/openapi-generator/src/main/resources/typescript-koa-server/gitignore new file mode 100644 index 00000000000..149b5765472 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/typescript-koa-server/gitignore @@ -0,0 +1,4 @@ +wwwroot/*.js +node_modules +typings +dist diff --git a/modules/openapi-generator/src/main/resources/typescript-koa-server/index.mustache b/modules/openapi-generator/src/main/resources/typescript-koa-server/index.mustache new file mode 100644 index 00000000000..104dd3d21e3 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/typescript-koa-server/index.mustache @@ -0,0 +1,6 @@ +export * from './api/api'; +export * from './model/models'; +export * from './variables'; +export * from './configuration'; +export * from './api.module'; +export * from './param'; diff --git a/modules/openapi-generator/src/main/resources/typescript-koa-server/jest.config.js.mustache b/modules/openapi-generator/src/main/resources/typescript-koa-server/jest.config.js.mustache new file mode 100644 index 00000000000..d6a9f64efb5 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/typescript-koa-server/jest.config.js.mustache @@ -0,0 +1,18 @@ +module.exports = { + verbose: true, + testEnvironment: 'node', + moduleFileExtensions: ['ts', 'js'], + testPathIgnorePatterns: ['/dist/'], + transform: { + '^.+\\.[t|j]s?$': ['ts-jest'], + }, + transformIgnorePatterns: ['/node_modules/'], + testRegex: '.*\\.test\\.(j|t)s?$', + moduleNameMapper: { + 'tests/(.*)$': '/tests/$1', + 'configs/(.*)$': '/configs/$1', + 'app/(.*)$': '/app/$1', + server: '/app.ts', + // app: '/app.ts', + }, +} diff --git a/modules/openapi-generator/src/main/resources/typescript-koa-server/licenseInfo.mustache b/modules/openapi-generator/src/main/resources/typescript-koa-server/licenseInfo.mustache new file mode 100644 index 00000000000..16ba21d203d --- /dev/null +++ b/modules/openapi-generator/src/main/resources/typescript-koa-server/licenseInfo.mustache @@ -0,0 +1,11 @@ +/** + * {{{appName}}} + * {{{appDescription}}} + * + * {{#version}}The version of the OpenAPI document: {{{.}}}{{/version}} + * {{#infoEmail}}Contact: {{{.}}}{{/infoEmail}} + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/typescript-koa-server/model.mustache b/modules/openapi-generator/src/main/resources/typescript-koa-server/model.mustache new file mode 100644 index 00000000000..fb2f624d518 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/typescript-koa-server/model.mustache @@ -0,0 +1,16 @@ +{{>licenseInfo}} +{{#models}} +{{#model}} +{{#tsImports}} +import { {{classname}} } from '{{filename}}'; +{{/tsImports}} + + +{{#description}} +/** + * {{{.}}} + */ +{{/description}} +{{#isEnum}}{{>modelEnum}}{{/isEnum}}{{^isEnum}}{{#isAlias}}{{>modelAlias}}{{/isAlias}}{{^isAlias}}{{#taggedUnions}}{{>modelTaggedUnion}}{{/taggedUnions}}{{^taggedUnions}}{{#oneOf}}{{#-first}}{{>modelOneOf}}{{/-first}}{{/oneOf}}{{^oneOf}}{{>modelGeneric}}{{/oneOf}}{{/taggedUnions}}{{/isAlias}}{{/isEnum}} +{{/model}} +{{/models}} diff --git a/modules/openapi-generator/src/main/resources/typescript-koa-server/modelAlias.mustache b/modules/openapi-generator/src/main/resources/typescript-koa-server/modelAlias.mustache new file mode 100644 index 00000000000..c1c6bf7a5da --- /dev/null +++ b/modules/openapi-generator/src/main/resources/typescript-koa-server/modelAlias.mustache @@ -0,0 +1 @@ +export type {{classname}} = {{dataType}}; \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/typescript-koa-server/modelEnum.mustache b/modules/openapi-generator/src/main/resources/typescript-koa-server/modelEnum.mustache new file mode 100644 index 00000000000..7a7d2299e16 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/typescript-koa-server/modelEnum.mustache @@ -0,0 +1,20 @@ +{{#stringEnums}} +export enum {{classname}} { +{{#allowableValues}} +{{#enumVars}} + {{name}} = {{{value}}}{{^-last}},{{/-last}} +{{/enumVars}} +{{/allowableValues}} +} +{{/stringEnums}} +{{^stringEnums}} +export type {{classname}} = {{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}} | {{/-last}}{{/enumVars}}{{/allowableValues}}; + +export const {{classname}} = { +{{#allowableValues}} +{{#enumVars}} + {{name}}: {{{value}}} as {{classname}}{{^-last}},{{/-last}} +{{/enumVars}} +{{/allowableValues}} +}; +{{/stringEnums}} diff --git a/modules/openapi-generator/src/main/resources/typescript-koa-server/modelGeneric.mustache b/modules/openapi-generator/src/main/resources/typescript-koa-server/modelGeneric.mustache new file mode 100644 index 00000000000..43207b65e30 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/typescript-koa-server/modelGeneric.mustache @@ -0,0 +1,10 @@ +export interface {{classname}}{{#allParents}}{{#-first}} extends {{/-first}}{{{.}}}{{^-last}}, {{/-last}}{{/allParents}} { {{>modelGenericAdditionalProperties}} +{{#vars}} + {{#description}} + /** + * {{{.}}} + */ + {{/description}} + {{#isReadOnly}}readonly {{/isReadOnly}}{{{name}}}{{^required}}?{{/required}}: {{#isEnum}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{#isNullable}} | null{{/isNullable}}; +{{/vars}} +}{{>modelGenericEnums}} diff --git a/modules/openapi-generator/src/main/resources/typescript-koa-server/modelGenericAdditionalProperties.mustache b/modules/openapi-generator/src/main/resources/typescript-koa-server/modelGenericAdditionalProperties.mustache new file mode 100644 index 00000000000..e6499ce9d63 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/typescript-koa-server/modelGenericAdditionalProperties.mustache @@ -0,0 +1,5 @@ +{{#additionalPropertiesType}} + + [key: string]: {{{additionalPropertiesType}}}{{#hasVars}} | any{{/hasVars}}; + +{{/additionalPropertiesType}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/typescript-koa-server/modelGenericEnums.mustache b/modules/openapi-generator/src/main/resources/typescript-koa-server/modelGenericEnums.mustache new file mode 100644 index 00000000000..a824e55ec53 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/typescript-koa-server/modelGenericEnums.mustache @@ -0,0 +1,30 @@ +{{#hasEnums}} + +{{^stringEnums}} +export namespace {{classname}} { +{{/stringEnums}} +{{#vars}} + {{#isEnum}} +{{#stringEnums}} +export enum {{classname}}{{enumName}} { +{{#allowableValues}} +{{#enumVars}} + {{name}} = {{{value}}}{{^-last}},{{/-last}} +{{/enumVars}} +{{/allowableValues}} +}; +{{/stringEnums}} +{{^stringEnums}} + export type {{enumName}} = {{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}} | {{/-last}}{{/enumVars}}{{/allowableValues}}; + export const {{enumName}} = { + {{#allowableValues}} + {{#enumVars}} + {{name}}: {{{value}}} as {{enumName}}{{^-last}},{{/-last}} + {{/enumVars}} + {{/allowableValues}} + }; +{{/stringEnums}} + {{/isEnum}} +{{/vars}} +{{^stringEnums}}}{{/stringEnums}} +{{/hasEnums}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/typescript-koa-server/modelOneOf.mustache b/modules/openapi-generator/src/main/resources/typescript-koa-server/modelOneOf.mustache new file mode 100644 index 00000000000..f6f30e029a7 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/typescript-koa-server/modelOneOf.mustache @@ -0,0 +1,14 @@ +{{#hasImports}} +import { + {{#imports}} + {{{.}}}, + {{/imports}} +} from './'; + +{{/hasImports}} +/** + * @type {{classname}}{{#description}} + * {{{.}}}{{/description}} + * @export + */ +export type {{classname}} = {{#oneOf}}{{{.}}}{{^-last}} | {{/-last}}{{/oneOf}}; diff --git a/modules/openapi-generator/src/main/resources/typescript-koa-server/modelTaggedUnion.mustache b/modules/openapi-generator/src/main/resources/typescript-koa-server/modelTaggedUnion.mustache new file mode 100644 index 00000000000..24a9c0f0b60 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/typescript-koa-server/modelTaggedUnion.mustache @@ -0,0 +1,21 @@ +{{#discriminator}} +export type {{classname}} = {{#children}}{{^-first}} | {{/-first}}{{classname}}{{/children}}; +{{/discriminator}} +{{^discriminator}} +{{#parent}} +export interface {{classname}} { {{>modelGenericAdditionalProperties}} +{{#allVars}} + {{#description}} + /** + * {{{.}}} + */ + {{/description}} + {{name}}{{^required}}?{{/required}}: {{#discriminatorValue}}'{{.}}'{{/discriminatorValue}}{{^discriminatorValue}}{{#isEnum}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{/discriminatorValue}}{{#isNullable}} | null{{/isNullable}}; +{{/allVars}} +} +{{>modelGenericEnums}} +{{/parent}} +{{^parent}} +{{>modelGeneric}} +{{/parent}} +{{/discriminator}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/typescript-koa-server/models.mustache b/modules/openapi-generator/src/main/resources/typescript-koa-server/models.mustache new file mode 100644 index 00000000000..995ffee1621 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/typescript-koa-server/models.mustache @@ -0,0 +1,5 @@ +{{#models}} +{{#model}} +export * from '{{{ classFilename }}}'; +{{/model}} +{{/models}} diff --git a/modules/openapi-generator/src/main/resources/typescript-koa-server/ng-package.mustache b/modules/openapi-generator/src/main/resources/typescript-koa-server/ng-package.mustache new file mode 100644 index 00000000000..3b17900dc9c --- /dev/null +++ b/modules/openapi-generator/src/main/resources/typescript-koa-server/ng-package.mustache @@ -0,0 +1,6 @@ +{ + "$schema": "./node_modules/ng-packagr/ng-package.schema.json", + "lib": { + "entryFile": "index.ts" + } +} diff --git a/modules/openapi-generator/src/main/resources/typescript-koa-server/nodemon.mustache b/modules/openapi-generator/src/main/resources/typescript-koa-server/nodemon.mustache new file mode 100644 index 00000000000..a67801ba23c --- /dev/null +++ b/modules/openapi-generator/src/main/resources/typescript-koa-server/nodemon.mustache @@ -0,0 +1,22 @@ +{ + "verbose": false, + "debug": false, + "exec": "ts-node -r tsconfig-paths/register ./app.ts", + "ignore": [ + "mochawesome-report", + "node_modules", + "./test", + "**/*.d.ts", + "*.test.ts", + "*.spec.ts", + "fixtures/*", + "test/**/*", + "docs/*" + ], + "events": { + "restart": "" + }, + "watch": ["./app", "./configs", "./app.ts"], + "ext": "ts", + "inspect": true +} diff --git a/modules/openapi-generator/src/main/resources/typescript-koa-server/package.mustache b/modules/openapi-generator/src/main/resources/typescript-koa-server/package.mustache new file mode 100644 index 00000000000..fdf70989b36 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/typescript-koa-server/package.mustache @@ -0,0 +1,98 @@ +{ + "name": "{{{npmName}}}", + "version": "{{{npmVersion}}}", + "description": "OpenAPI client for {{{npmName}}}", + "author": "OpenAPI-Generator Contributors", + "repository": { + "type": "git", + "url": "https://{{gitHost}}/{{gitUserId}}/{{gitRepoId}}.git" + }, + "keywords": [ + "openapi-client", + "openapi-generator" + ], + "license": "Unlicense", + "scripts": { + "build": "ng-packagr -p ng-package.json" + }, + "peerDependencies": { + "@angular/core": "^{{ngVersion}}", + "rxjs": "^{{rxjsVersion}}" + }, + "devDependencies": { + "@angular/common": "^{{ngVersion}}", + "@angular/compiler": "^{{ngVersion}}", + "@angular/compiler-cli": "^{{ngVersion}}", + "@angular/core": "^{{ngVersion}}", + "@angular/platform-browser": "^{{ngVersion}}", + "ng-packagr": "^{{ngPackagrVersion}}", + "reflect-metadata": "^0.1.3", + "rxjs": "^{{rxjsVersion}}",{{#tsickleVersion}} + "tsickle": "^{{tsickleVersion}}",{{/tsickleVersion}} + "typescript": "{{{tsVersion}}}", + "zone.js": "^{{zonejsVersion}}" + }{{#npmRepository}}, + "publishConfig": { + "registry": "{{{npmRepository}}}" + } +{{/npmRepository}} +} + +{ + "name": "{{{npmName}}}", + "version": "{{{npmVersion}}}", + "license": "Unlicense", + "main": "app.ts", + "scripts": { + "dev": "export NODE_ENV=development; ts-node-dev -r tsconfig-paths/register app.ts", + "dev:db": "docker compose -f docker-compose.yml up -d", + "prettier": "prettier --write '**/*.{js,ts}'", + "test": "jest --config .jest.config.js --no-cache --detectOpenHandles", + "prod:build": "node ./build.js", + "prod:start": "prisma generate && prisma migrate deploy && export NODE_ENV=production; node ./dist/index.js" + }, + "repository": { + "type": "git", + "url": "https://{{gitHost}}/{{gitUserId}}/{{gitRepoId}}.git" + }, + "keywords": [ + "koa", + "openapi-server", + "openapi-generator" + ], + "engines": { + "node": ">= 14.x" + }, + "prettier": "@geist-ui/prettier-config", + "devDependencies": { + "@geist-ui/prettier-config": "^1.0.1", + "@types/jest": "^25.2.2", + "@types/koa": "^2.13.4", + "@types/koa-bodyparser": "^4.3.5", + "@types/node": "^17.0.8", + "esbuild": "^0.14.11", + "esbuild-node-externals": "^1.4.1", + "jest": "^26.6.3", + "prettier": "^2.5.1", + "prisma": "^4.6.1", + "supertest": "^4.0.2", + "ts-jest": "^26.5.3", + "ts-node-dev": "^1.1.8", + "tsconfig-paths": "^3.12.0", + "typescript": "^4.5.4" + }, + "dependencies": { + "@prisma/client": "^4.6.1", + "class-transformer": "^0.5.1", + "class-validator": "^0.13.2", + "dotenv": "^12.0.3", + "koa": "^2.13.4", + "koa-bodyparser": "^4.3.0", + "koa-logger": "^3.2.1", + "koa-multer": "^1.0.2", + "koa-router": "^10.1.1", + "reflect-metadata": "^0.1.13", + "routing-controllers": "^0.9.0", + "typedi": "^0.10.0" + } +} diff --git a/modules/openapi-generator/src/main/resources/typescript-koa-server/param.mustache b/modules/openapi-generator/src/main/resources/typescript-koa-server/param.mustache new file mode 100644 index 00000000000..78a2d20a643 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/typescript-koa-server/param.mustache @@ -0,0 +1,69 @@ +/** + * Standard parameter styles defined by OpenAPI spec + */ +export type StandardParamStyle = + | 'matrix' + | 'label' + | 'form' + | 'simple' + | 'spaceDelimited' + | 'pipeDelimited' + | 'deepObject' + ; + +/** + * The OpenAPI standard {@link StandardParamStyle}s may be extended by custom styles by the user. + */ +export type ParamStyle = StandardParamStyle | string; + +/** + * Standard parameter locations defined by OpenAPI spec + */ +export type ParamLocation = 'query' | 'header' | 'path' | 'cookie'; + +/** + * Standard types as defined in OpenAPI Specification: Data Types + */ +export type StandardDataType = + | "integer" + | "number" + | "boolean" + | "string" + | "object" + | "array" + ; + +/** + * Standard {@link DataType}s plus your own types/classes. + */ +export type DataType = StandardDataType | string; + +/** + * Standard formats as defined in OpenAPI Specification: Data Types + */ +export type StandardDataFormat = + | "int32" + | "int64" + | "float" + | "double" + | "byte" + | "binary" + | "date" + | "date-time" + | "password" + ; + +export type DataFormat = StandardDataFormat | string; + +/** + * The parameter to encode. + */ +export interface Param { + name: string; + value: unknown; + in: ParamLocation; + style: ParamStyle, + explode: boolean; + dataType: DataType; + dataFormat: DataFormat | undefined; +} diff --git a/modules/openapi-generator/src/main/resources/typescript-koa-server/tsconfig.mustache b/modules/openapi-generator/src/main/resources/typescript-koa-server/tsconfig.mustache new file mode 100644 index 00000000000..796e6879737 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/typescript-koa-server/tsconfig.mustache @@ -0,0 +1,39 @@ +{ + "compilerOptions": { + "allowJs": true, + "moduleResolution": "Node", + "module": "commonjs", + "outDir": "./dist", + "lib": ["ESNext"], + "removeComments": true, + "skipLibCheck": true, + "noImplicitAny": false, + "esModuleInterop": true, + "preserveConstEnums": true, + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "typeRoots": [ + "node_modules/@types", + "typings" + ], + "baseUrl": ".", + "paths": { + "configs/*": ["./configs/*"], + "app": ["app"] + }, + }, + "compileOnSave": false, + "include": [ + "app/**/*", + "configs/**/*", + "**/*.ts", + "**/*.tsx" + ], + "files": [ + "app.ts", + ], + "exclude": [ + "node_modules", + "dist" + ] +} diff --git a/modules/openapi-generator/src/main/resources/typescript-koa-server/variables.mustache b/modules/openapi-generator/src/main/resources/typescript-koa-server/variables.mustache new file mode 100644 index 00000000000..6fe58549f39 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/typescript-koa-server/variables.mustache @@ -0,0 +1,9 @@ +import { InjectionToken } from '@angular/core'; + +export const BASE_PATH = new InjectionToken('basePath'); +export const COLLECTION_FORMATS = { + 'csv': ',', + 'tsv': ' ', + 'ssv': ' ', + 'pipes': '|' +} diff --git a/modules/openapi-generator/src/test/resources/3_0/typescript-koa-server/petstore.yaml b/modules/openapi-generator/src/test/resources/3_0/typescript-koa-server/petstore.yaml new file mode 100644 index 00000000000..0971c554414 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/typescript-koa-server/petstore.yaml @@ -0,0 +1,738 @@ +openapi: 3.0.0 +servers: + - url: 'http://petstore.swagger.io/v2' +info: + description: >- + This is a sample server Petstore server. For this sample, you can use the api key + `special-key` to test the authorization filters. + version: 1.0.0 + title: OpenAPI Petstore + license: + name: Apache-2.0 + url: 'https://www.apache.org/licenses/LICENSE-2.0.html' +tags: + - name: pet + description: Everything about your Pets + - name: store + description: Access to Petstore orders + - name: user + description: Operations about user +paths: + /pet: + post: + tags: + - pet + summary: Add a new pet to the store + description: '' + operationId: addPet + responses: + '200': + description: successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/Pet' + application/json: + schema: + $ref: '#/components/schemas/Pet' + '405': + description: Invalid input + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + requestBody: + $ref: '#/components/requestBodies/Pet' + put: + tags: + - pet + summary: Update an existing pet + description: '' + operationId: updatePet + responses: + '200': + description: successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/Pet' + application/json: + schema: + $ref: '#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + '405': + description: Validation exception + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + requestBody: + $ref: '#/components/requestBodies/Pet' + /pet/findByStatus: + get: + tags: + - pet + summary: Finds Pets by status + description: Multiple status values can be provided with comma separated strings + operationId: findPetsByStatus + parameters: + - name: status + in: query + description: Status values that need to be considered for filter + required: true + style: form + explode: false + deprecated: true + schema: + type: array + items: + type: string + enum: + - available + - pending + - sold + default: available + responses: + '200': + description: successful operation + content: + application/xml: + schema: + type: array + items: + $ref: '#/components/schemas/Pet' + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Pet' + '400': + description: Invalid status value + security: + - petstore_auth: + - 'read:pets' + /pet/findByTags: + get: + tags: + - pet + summary: Finds Pets by tags + description: >- + Multiple tags can be provided with comma separated strings. Use tag1, + tag2, tag3 for testing. + operationId: findPetsByTags + parameters: + - name: tags + in: query + description: Tags to filter by + required: true + style: form + explode: false + schema: + type: array + items: + type: string + responses: + '200': + description: successful operation + content: + application/xml: + schema: + type: array + items: + $ref: '#/components/schemas/Pet' + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Pet' + '400': + description: Invalid tag value + security: + - petstore_auth: + - 'read:pets' + deprecated: true + '/pet/{petId}': + get: + tags: + - pet + summary: Find pet by ID + description: Returns a single pet + operationId: getPetById + parameters: + - name: petId + in: path + description: ID of pet to return + required: true + schema: + type: integer + format: int64 + responses: + '200': + description: successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/Pet' + application/json: + schema: + $ref: '#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + security: + - api_key: [] + post: + tags: + - pet + summary: Updates a pet in the store with form data + description: '' + operationId: updatePetWithForm + parameters: + - name: petId + in: path + description: ID of pet that needs to be updated + required: true + schema: + type: integer + format: int64 + responses: + '405': + description: Invalid input + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + requestBody: + content: + application/x-www-form-urlencoded: + schema: + type: object + properties: + name: + description: Updated name of the pet + type: string + status: + description: Updated status of the pet + type: string + delete: + tags: + - pet + summary: Deletes a pet + description: '' + operationId: deletePet + parameters: + - name: api_key + in: header + required: false + schema: + type: string + - name: petId + in: path + description: Pet id to delete + required: true + schema: + type: integer + format: int64 + responses: + '400': + description: Invalid pet value + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + '/pet/{petId}/uploadImage': + post: + tags: + - pet + summary: uploads an image + description: '' + operationId: uploadFile + parameters: + - name: petId + in: path + description: ID of pet to update + required: true + schema: + type: integer + format: int64 + responses: + '200': + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + requestBody: + content: + multipart/form-data: + schema: + type: object + properties: + additionalMetadata: + description: Additional data to pass to server + type: string + file: + description: file to upload + type: string + format: binary + /store/inventory: + get: + tags: + - store + summary: Returns pet inventories by status + description: Returns a map of status codes to quantities + operationId: getInventory + responses: + '200': + description: successful operation + content: + application/json: + schema: + type: object + additionalProperties: + type: integer + format: int32 + security: + - api_key: [] + /store/order: + post: + tags: + - store + summary: Place an order for a pet + description: '' + operationId: placeOrder + responses: + '200': + description: successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/Order' + application/json: + schema: + $ref: '#/components/schemas/Order' + '400': + description: Invalid Order + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/Order' + description: order placed for purchasing the pet + required: true + '/store/order/{orderId}': + get: + tags: + - store + summary: Find purchase order by ID + description: >- + For valid response try integer IDs with value <= 5 or > 10. Other values + will generate exceptions + operationId: getOrderById + parameters: + - name: orderId + in: path + description: ID of pet that needs to be fetched + required: true + schema: + type: integer + format: int64 + minimum: 1 + maximum: 5 + responses: + '200': + description: successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/Order' + application/json: + schema: + $ref: '#/components/schemas/Order' + '400': + description: Invalid ID supplied + '404': + description: Order not found + delete: + tags: + - store + summary: Delete purchase order by ID + description: >- + For valid response try integer IDs with value < 1000. Anything above + 1000 or nonintegers will generate API errors + operationId: deleteOrder + parameters: + - name: orderId + in: path + description: ID of the order that needs to be deleted + required: true + schema: + type: string + responses: + '400': + description: Invalid ID supplied + '404': + description: Order not found + /user: + post: + tags: + - user + summary: Create user + description: This can only be done by the logged in user. + operationId: createUser + responses: + default: + description: successful operation + security: + - api_key: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/User' + description: Created user object + required: true + /user/createWithArray: + post: + tags: + - user + summary: Creates list of users with given input array + description: '' + operationId: createUsersWithArrayInput + responses: + default: + description: successful operation + security: + - api_key: [] + requestBody: + $ref: '#/components/requestBodies/UserArray' + /user/createWithList: + post: + tags: + - user + summary: Creates list of users with given input array + description: '' + operationId: createUsersWithListInput + responses: + default: + description: successful operation + security: + - api_key: [] + requestBody: + $ref: '#/components/requestBodies/UserArray' + /user/login: + get: + tags: + - user + summary: Logs user into the system + description: '' + operationId: loginUser + parameters: + - name: username + in: query + description: The user name for login + required: true + schema: + type: string + pattern: '^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$' + - name: password + in: query + description: The password for login in clear text + required: true + schema: + type: string + responses: + '200': + description: successful operation + headers: + Set-Cookie: + description: >- + Cookie authentication key for use with the `api_key` + apiKey authentication. + schema: + type: string + example: AUTH_KEY=abcde12345; Path=/; HttpOnly + X-Rate-Limit: + description: calls per hour allowed by the user + schema: + type: integer + format: int32 + X-Expires-After: + description: date in UTC when token expires + schema: + type: string + format: date-time + content: + application/xml: + schema: + type: string + application/json: + schema: + type: string + '400': + description: Invalid username/password supplied + /user/logout: + get: + tags: + - user + summary: Logs out current logged in user session + description: '' + operationId: logoutUser + responses: + default: + description: successful operation + security: + - api_key: [] + '/user/{username}': + get: + tags: + - user + summary: Get user by user name + description: '' + operationId: getUserByName + parameters: + - name: username + in: path + description: The name that needs to be fetched. Use user1 for testing. + required: true + schema: + type: string + responses: + '200': + description: successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/User' + application/json: + schema: + $ref: '#/components/schemas/User' + '400': + description: Invalid username supplied + '404': + description: User not found + put: + tags: + - user + summary: Updated user + description: This can only be done by the logged in user. + operationId: updateUser + parameters: + - name: username + in: path + description: name that need to be deleted + required: true + schema: + type: string + responses: + '400': + description: Invalid user supplied + '404': + description: User not found + security: + - api_key: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/User' + description: Updated user object + required: true + delete: + tags: + - user + summary: Delete user + description: This can only be done by the logged in user. + operationId: deleteUser + parameters: + - name: username + in: path + description: The name that needs to be deleted + required: true + schema: + type: string + responses: + '400': + description: Invalid username supplied + '404': + description: User not found + security: + - api_key: [] +externalDocs: + description: Find out more about Swagger + url: 'http://swagger.io' +components: + requestBodies: + UserArray: + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/User' + description: List of user object + required: true + Pet: + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + application/xml: + schema: + $ref: '#/components/schemas/Pet' + description: Pet object that needs to be added to the store + required: true + securitySchemes: + petstore_auth: + type: oauth2 + flows: + implicit: + authorizationUrl: 'http://petstore.swagger.io/api/oauth/dialog' + scopes: + 'write:pets': modify pets in your account + 'read:pets': read your pets + api_key: + type: apiKey + name: api_key + in: header + schemas: + Order: + title: Pet Order + description: An order for a pets from the pet store + type: object + properties: + id: + type: integer + format: int64 + petId: + type: integer + format: int64 + quantity: + type: integer + format: int32 + shipDate: + type: string + format: date-time + status: + type: string + description: Order Status + enum: + - placed + - approved + - delivered + complete: + type: boolean + default: false + xml: + name: Order + Category: + title: Pet category + description: A category for a pet + type: object + properties: + id: + type: integer + format: int64 + name: + type: string + pattern: '^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$' + xml: + name: Category + User: + title: a User + description: A User who is purchasing from the pet store + type: object + properties: + id: + type: integer + format: int64 + username: + type: string + firstName: + type: string + lastName: + type: string + email: + type: string + password: + type: string + phone: + type: string + userStatus: + type: integer + format: int32 + description: User Status + xml: + name: User + Tag: + title: Pet Tag + description: A tag for a pet + type: object + properties: + id: + type: integer + format: int64 + name: + type: string + xml: + name: Tag + Pet: + title: a Pet + description: A pet for sale in the pet store + type: object + required: + - name + - photoUrls + properties: + id: + type: integer + format: int64 + category: + $ref: '#/components/schemas/Category' + name: + type: string + example: doggie + photoUrls: + type: array + xml: + name: photoUrl + wrapped: true + items: + type: string + tags: + type: array + xml: + name: tag + wrapped: true + items: + $ref: '#/components/schemas/Tag' + status: + type: string + description: pet status in the store + deprecated: true + enum: + - available + - pending + - sold + xml: + name: Pet + ApiResponse: + title: An uploaded response + description: Describes the result of uploading an image resource + type: object + properties: + code: + type: integer + format: int32 + type: + type: string + message: + type: string diff --git a/samples/server/petstore/typescript-koa-server/.gitignore b/samples/server/petstore/typescript-koa-server/.gitignore new file mode 100644 index 00000000000..149b5765472 --- /dev/null +++ b/samples/server/petstore/typescript-koa-server/.gitignore @@ -0,0 +1,4 @@ +wwwroot/*.js +node_modules +typings +dist diff --git a/samples/server/petstore/typescript-koa-server/.openapi-generator-ignore b/samples/server/petstore/typescript-koa-server/.openapi-generator-ignore new file mode 100644 index 00000000000..7484ee590a3 --- /dev/null +++ b/samples/server/petstore/typescript-koa-server/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/server/petstore/typescript-koa-server/.openapi-generator/FILES b/samples/server/petstore/typescript-koa-server/.openapi-generator/FILES new file mode 100644 index 00000000000..6e213a61aa6 --- /dev/null +++ b/samples/server/petstore/typescript-koa-server/.openapi-generator/FILES @@ -0,0 +1,20 @@ +.gitignore +README.md +api.module.ts +api/api.ts +api/pet.service.ts +api/store.service.ts +api/user.service.ts +configuration.ts +encoder.ts +git_push.sh +index.ts +model/apiResponse.ts +model/category.ts +model/models.ts +model/order.ts +model/pet.ts +model/tag.ts +model/user.ts +param.ts +variables.ts diff --git a/samples/server/petstore/typescript-koa-server/.openapi-generator/VERSION b/samples/server/petstore/typescript-koa-server/.openapi-generator/VERSION new file mode 100644 index 00000000000..d6b4ec4aa78 --- /dev/null +++ b/samples/server/petstore/typescript-koa-server/.openapi-generator/VERSION @@ -0,0 +1 @@ +6.3.0-SNAPSHOT \ No newline at end of file diff --git a/samples/server/petstore/typescript-koa-server/README.md b/samples/server/petstore/typescript-koa-server/README.md new file mode 100644 index 00000000000..de16f95a8bd --- /dev/null +++ b/samples/server/petstore/typescript-koa-server/README.md @@ -0,0 +1,226 @@ +## @ + +### Building + +To install the required dependencies and to build the typescript sources run: +``` +npm install +npm run build +``` + +### publishing + +First build the package then run ```npm publish dist``` (don't forget to specify the `dist` folder!) + +### consuming + +Navigate to the folder of your consuming project and run one of next commands. + +_published:_ + +``` +npm install @ --save +``` + +_without publishing (not recommended):_ + +``` +npm install PATH_TO_GENERATED_PACKAGE/dist.tgz --save +``` + +_It's important to take the tgz file, otherwise you'll get trouble with links on windows_ + +_using `npm link`:_ + +In PATH_TO_GENERATED_PACKAGE/dist: +``` +npm link +``` + +In your project: +``` +npm link +``` + +__Note for Windows users:__ The Angular CLI has troubles to use linked npm packages. +Please refer to this issue https://github.com/angular/angular-cli/issues/8284 for a solution / workaround. +Published packages are not effected by this issue. + + +#### General usage + +In your Angular project: + + +``` +// without configuring providers +import { ApiModule } from ''; +import { HttpClientModule } from '@angular/common/http'; + +@NgModule({ + imports: [ + ApiModule, + // make sure to import the HttpClientModule in the AppModule only, + // see https://github.com/angular/angular/issues/20575 + HttpClientModule + ], + declarations: [ AppComponent ], + providers: [], + bootstrap: [ AppComponent ] +}) +export class AppModule {} +``` + +``` +// configuring providers +import { ApiModule, Configuration, ConfigurationParameters } from ''; + +export function apiConfigFactory (): Configuration { + const params: ConfigurationParameters = { + // set configuration parameters here. + } + return new Configuration(params); +} + +@NgModule({ + imports: [ ApiModule.forRoot(apiConfigFactory) ], + declarations: [ AppComponent ], + providers: [], + bootstrap: [ AppComponent ] +}) +export class AppModule {} +``` + +``` +// configuring providers with an authentication service that manages your access tokens +import { ApiModule, Configuration } from ''; + +@NgModule({ + imports: [ ApiModule ], + declarations: [ AppComponent ], + providers: [ + { + provide: Configuration, + useFactory: (authService: AuthService) => new Configuration( + { + basePath: environment.apiUrl, + accessToken: authService.getAccessToken.bind(authService) + } + ), + deps: [AuthService], + multi: false + } + ], + bootstrap: [ AppComponent ] +}) +export class AppModule {} +``` + +``` +import { DefaultApi } from ''; + +export class AppComponent { + constructor(private apiGateway: DefaultApi) { } +} +``` + +Note: The ApiModule is restricted to being instantiated once app wide. +This is to ensure that all services are treated as singletons. + +#### Using multiple OpenAPI files / APIs / ApiModules +In order to use multiple `ApiModules` generated from different OpenAPI files, +you can create an alias name when importing the modules +in order to avoid naming conflicts: +``` +import { ApiModule } from 'my-api-path'; +import { ApiModule as OtherApiModule } from 'my-other-api-path'; +import { HttpClientModule } from '@angular/common/http'; + +@NgModule({ + imports: [ + ApiModule, + OtherApiModule, + // make sure to import the HttpClientModule in the AppModule only, + // see https://github.com/angular/angular/issues/20575 + HttpClientModule + ] +}) +export class AppModule { + +} +``` + + +### Set service base path +If different than the generated base path, during app bootstrap, you can provide the base path to your service. + +``` +import { BASE_PATH } from ''; + +bootstrap(AppComponent, [ + { provide: BASE_PATH, useValue: 'https://your-web-service.com' }, +]); +``` +or + +``` +import { BASE_PATH } from ''; + +@NgModule({ + imports: [], + declarations: [ AppComponent ], + providers: [ provide: BASE_PATH, useValue: 'https://your-web-service.com' ], + bootstrap: [ AppComponent ] +}) +export class AppModule {} +``` + + +#### Using @angular/cli +First extend your `src/environments/*.ts` files by adding the corresponding base path: + +``` +export const environment = { + production: false, + API_BASE_PATH: 'http://127.0.0.1:8080' +}; +``` + +In the src/app/app.module.ts: +``` +import { BASE_PATH } from ''; +import { environment } from '../environments/environment'; + +@NgModule({ + declarations: [ + AppComponent + ], + imports: [ ], + providers: [{ provide: BASE_PATH, useValue: environment.API_BASE_PATH }], + bootstrap: [ AppComponent ] +}) +export class AppModule { } +``` + +### Customizing path parameter encoding + +Without further customization, only [path-parameters][parameter-locations-url] of [style][style-values-url] 'simple' +and Dates for format 'date-time' are encoded correctly. + +Other styles (e.g. "matrix") are not that easy to encode +and thus are best delegated to other libraries (e.g.: [@honoluluhenk/http-param-expander]). + +To implement your own parameter encoding (or call another library), +pass an arrow-function or method-reference to the `encodeParam` property of the Configuration-object +(see [General Usage](#general-usage) above). + +Example value for use in your Configuration-Provider: +```typescript +new Configuration({ + encodeParam: (param: Param) => myFancyParamEncoder(param), +}) +``` + +[parameter-locations-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-locations +[style-values-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#style-values +[@honoluluhenk/http-param-expander]: https://www.npmjs.com/package/@honoluluhenk/http-param-expander diff --git a/samples/server/petstore/typescript-koa-server/api.module.ts b/samples/server/petstore/typescript-koa-server/api.module.ts new file mode 100644 index 00000000000..2afb8f64e92 --- /dev/null +++ b/samples/server/petstore/typescript-koa-server/api.module.ts @@ -0,0 +1,33 @@ +import { NgModule, ModuleWithProviders, SkipSelf, Optional } from '@angular/core'; +import { Configuration } from './configuration'; +import { HttpClient } from '@angular/common/http'; + +import { PetService } from './api/pet.service'; +import { StoreService } from './api/store.service'; +import { UserService } from './api/user.service'; + +@NgModule({ + imports: [], + declarations: [], + exports: [], + providers: [] +}) +export class ApiModule { + public static forRoot(configurationFactory: () => Configuration): ModuleWithProviders { + return { + ngModule: ApiModule, + providers: [ { provide: Configuration, useFactory: configurationFactory } ] + }; + } + + constructor( @Optional() @SkipSelf() parentModule: ApiModule, + @Optional() http: HttpClient) { + if (parentModule) { + throw new Error('ApiModule is already loaded. Import in your base AppModule only.'); + } + if (!http) { + throw new Error('You need to import the HttpClientModule in your AppModule! \n' + + 'See also https://github.com/angular/angular/issues/20575'); + } + } +} diff --git a/samples/server/petstore/typescript-koa-server/api/api.ts b/samples/server/petstore/typescript-koa-server/api/api.ts new file mode 100644 index 00000000000..8e44b64083d --- /dev/null +++ b/samples/server/petstore/typescript-koa-server/api/api.ts @@ -0,0 +1,7 @@ +export * from './pet.service'; +import { PetService } from './pet.service'; +export * from './store.service'; +import { StoreService } from './store.service'; +export * from './user.service'; +import { UserService } from './user.service'; +export const APIS = [PetService, StoreService, UserService]; diff --git a/samples/server/petstore/typescript-koa-server/api/pet.service.ts b/samples/server/petstore/typescript-koa-server/api/pet.service.ts new file mode 100644 index 00000000000..c27a2e8f8e2 --- /dev/null +++ b/samples/server/petstore/typescript-koa-server/api/pet.service.ts @@ -0,0 +1,734 @@ +/** + * OpenAPI Petstore + * This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ +/* tslint:disable:no-unused-variable member-ordering */ + +import { Inject, Injectable, Optional } from '@angular/core'; +import { HttpClient, HttpHeaders, HttpParams, + HttpResponse, HttpEvent, HttpParameterCodec, HttpContext + } from '@angular/common/http'; +import { CustomHttpParameterCodec } from '../encoder'; +import { Observable } from 'rxjs'; + +// @ts-ignore +import { ApiResponse } from '../model/apiResponse'; +// @ts-ignore +import { Pet } from '../model/pet'; + +// @ts-ignore +import { BASE_PATH, COLLECTION_FORMATS } from '../variables'; +import { Configuration } from '../configuration'; + + + +@Injectable({ + providedIn: 'root' +}) +export class PetService { + + protected basePath = 'http://petstore.swagger.io/v2'; + public defaultHeaders = new HttpHeaders(); + public configuration = new Configuration(); + public encoder: HttpParameterCodec; + + constructor(protected httpClient: HttpClient, @Optional()@Inject(BASE_PATH) basePath: string|string[], @Optional() configuration: Configuration) { + if (configuration) { + this.configuration = configuration; + } + if (typeof this.configuration.basePath !== 'string') { + if (Array.isArray(basePath) && basePath.length > 0) { + basePath = basePath[0]; + } + + if (typeof basePath !== 'string') { + basePath = this.basePath; + } + this.configuration.basePath = basePath; + } + this.encoder = this.configuration.encoder || new CustomHttpParameterCodec(); + } + + /** + * @param consumes string[] mime-types + * @return true: consumes contains 'multipart/form-data', false: otherwise + */ + private canConsumeForm(consumes: string[]): boolean { + const form = 'multipart/form-data'; + for (const consume of consumes) { + if (form === consume) { + return true; + } + } + return false; + } + + // @ts-ignore + private addToHttpParams(httpParams: HttpParams, value: any, key?: string): HttpParams { + if (typeof value === "object" && value instanceof Date === false) { + httpParams = this.addToHttpParamsRecursive(httpParams, value); + } else { + httpParams = this.addToHttpParamsRecursive(httpParams, value, key); + } + return httpParams; + } + + private addToHttpParamsRecursive(httpParams: HttpParams, value?: any, key?: string): HttpParams { + if (value == null) { + return httpParams; + } + + if (typeof value === "object") { + if (Array.isArray(value)) { + (value as any[]).forEach( elem => httpParams = this.addToHttpParamsRecursive(httpParams, elem, key)); + } else if (value instanceof Date) { + if (key != null) { + httpParams = httpParams.append(key, (value as Date).toISOString().substr(0, 10)); + } else { + throw Error("key may not be null if value is Date"); + } + } else { + Object.keys(value).forEach( k => httpParams = this.addToHttpParamsRecursive( + httpParams, value[k], key != null ? `${key}.${k}` : k)); + } + } else if (key != null) { + httpParams = httpParams.append(key, value); + } else { + throw Error("key may not be null if value is not object or array"); + } + return httpParams; + } + + /** + * Add a new pet to the store + * + * @param pet Pet object that needs to be added to the store + * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. + * @param reportProgress flag to report request and response progress. + */ + public addPet(pet: Pet, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable; + public addPet(pet: Pet, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; + public addPet(pet: Pet, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; + public addPet(pet: Pet, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable { + if (pet === null || pet === undefined) { + throw new Error('Required parameter pet was null or undefined when calling addPet.'); + } + + let localVarHeaders = this.defaultHeaders; + + let localVarCredential: string | undefined; + // authentication (petstore_auth) required + localVarCredential = this.configuration.lookupCredential('petstore_auth'); + if (localVarCredential) { + localVarHeaders = localVarHeaders.set('Authorization', 'Bearer ' + localVarCredential); + } + + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + 'application/xml', + 'application/json' + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + + // to determine the Content-Type header + const consumes: string[] = [ + 'application/json', + 'application/xml' + ]; + const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes); + if (httpContentTypeSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Content-Type', httpContentTypeSelected); + } + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/pet`; + return this.httpClient.request('post', `${this.configuration.basePath}${localVarPath}`, + { + context: localVarHttpContext, + body: pet, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); + } + + /** + * Deletes a pet + * + * @param petId Pet id to delete + * @param apiKey + * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. + * @param reportProgress flag to report request and response progress. + */ + public deletePet(petId: number, apiKey?: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; + public deletePet(petId: number, apiKey?: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public deletePet(petId: number, apiKey?: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public deletePet(petId: number, apiKey?: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { + if (petId === null || petId === undefined) { + throw new Error('Required parameter petId was null or undefined when calling deletePet.'); + } + + let localVarHeaders = this.defaultHeaders; + if (apiKey !== undefined && apiKey !== null) { + localVarHeaders = localVarHeaders.set('api_key', String(apiKey)); + } + + let localVarCredential: string | undefined; + // authentication (petstore_auth) required + localVarCredential = this.configuration.lookupCredential('petstore_auth'); + if (localVarCredential) { + localVarHeaders = localVarHeaders.set('Authorization', 'Bearer ' + localVarCredential); + } + + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; + return this.httpClient.request('delete', `${this.configuration.basePath}${localVarPath}`, + { + context: localVarHttpContext, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); + } + + /** + * Finds Pets by status + * Multiple status values can be provided with comma separated strings + * @param status Status values that need to be considered for filter + * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. + * @param reportProgress flag to report request and response progress. + */ + public findPetsByStatus(status: Array<'available' | 'pending' | 'sold'>, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; + public findPetsByStatus(status: Array<'available' | 'pending' | 'sold'>, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>>; + public findPetsByStatus(status: Array<'available' | 'pending' | 'sold'>, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>>; + public findPetsByStatus(status: Array<'available' | 'pending' | 'sold'>, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable { + if (status === null || status === undefined) { + throw new Error('Required parameter status was null or undefined when calling findPetsByStatus.'); + } + + let localVarQueryParameters = new HttpParams({encoder: this.encoder}); + if (status) { + localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, + [...status].join(COLLECTION_FORMATS['csv']), 'status'); + } + + let localVarHeaders = this.defaultHeaders; + + let localVarCredential: string | undefined; + // authentication (petstore_auth) required + localVarCredential = this.configuration.lookupCredential('petstore_auth'); + if (localVarCredential) { + localVarHeaders = localVarHeaders.set('Authorization', 'Bearer ' + localVarCredential); + } + + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + 'application/xml', + 'application/json' + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/pet/findByStatus`; + return this.httpClient.request>('get', `${this.configuration.basePath}${localVarPath}`, + { + context: localVarHttpContext, + params: localVarQueryParameters, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); + } + + /** + * Finds Pets by tags + * Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing. + * @param tags Tags to filter by + * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. + * @param reportProgress flag to report request and response progress. + * @deprecated + */ + public findPetsByTags(tags: Array, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; + public findPetsByTags(tags: Array, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>>; + public findPetsByTags(tags: Array, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>>; + public findPetsByTags(tags: Array, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable { + if (tags === null || tags === undefined) { + throw new Error('Required parameter tags was null or undefined when calling findPetsByTags.'); + } + + let localVarQueryParameters = new HttpParams({encoder: this.encoder}); + if (tags) { + localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, + [...tags].join(COLLECTION_FORMATS['csv']), 'tags'); + } + + let localVarHeaders = this.defaultHeaders; + + let localVarCredential: string | undefined; + // authentication (petstore_auth) required + localVarCredential = this.configuration.lookupCredential('petstore_auth'); + if (localVarCredential) { + localVarHeaders = localVarHeaders.set('Authorization', 'Bearer ' + localVarCredential); + } + + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + 'application/xml', + 'application/json' + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/pet/findByTags`; + return this.httpClient.request>('get', `${this.configuration.basePath}${localVarPath}`, + { + context: localVarHttpContext, + params: localVarQueryParameters, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); + } + + /** + * Find pet by ID + * Returns a single pet + * @param petId ID of pet to return + * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. + * @param reportProgress flag to report request and response progress. + */ + public getPetById(petId: number, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable; + public getPetById(petId: number, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; + public getPetById(petId: number, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; + public getPetById(petId: number, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable { + if (petId === null || petId === undefined) { + throw new Error('Required parameter petId was null or undefined when calling getPetById.'); + } + + let localVarHeaders = this.defaultHeaders; + + let localVarCredential: string | undefined; + // authentication (api_key) required + localVarCredential = this.configuration.lookupCredential('api_key'); + if (localVarCredential) { + localVarHeaders = localVarHeaders.set('api_key', localVarCredential); + } + + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + 'application/xml', + 'application/json' + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; + return this.httpClient.request('get', `${this.configuration.basePath}${localVarPath}`, + { + context: localVarHttpContext, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); + } + + /** + * Update an existing pet + * + * @param pet Pet object that needs to be added to the store + * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. + * @param reportProgress flag to report request and response progress. + */ + public updatePet(pet: Pet, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable; + public updatePet(pet: Pet, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; + public updatePet(pet: Pet, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; + public updatePet(pet: Pet, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable { + if (pet === null || pet === undefined) { + throw new Error('Required parameter pet was null or undefined when calling updatePet.'); + } + + let localVarHeaders = this.defaultHeaders; + + let localVarCredential: string | undefined; + // authentication (petstore_auth) required + localVarCredential = this.configuration.lookupCredential('petstore_auth'); + if (localVarCredential) { + localVarHeaders = localVarHeaders.set('Authorization', 'Bearer ' + localVarCredential); + } + + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + 'application/xml', + 'application/json' + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + + // to determine the Content-Type header + const consumes: string[] = [ + 'application/json', + 'application/xml' + ]; + const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes); + if (httpContentTypeSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Content-Type', httpContentTypeSelected); + } + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/pet`; + return this.httpClient.request('put', `${this.configuration.basePath}${localVarPath}`, + { + context: localVarHttpContext, + body: pet, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); + } + + /** + * Updates a pet in the store with form data + * + * @param petId ID of pet that needs to be updated + * @param name Updated name of the pet + * @param status Updated status of the pet + * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. + * @param reportProgress flag to report request and response progress. + */ + public updatePetWithForm(petId: number, name?: string, status?: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; + public updatePetWithForm(petId: number, name?: string, status?: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public updatePetWithForm(petId: number, name?: string, status?: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public updatePetWithForm(petId: number, name?: string, status?: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { + if (petId === null || petId === undefined) { + throw new Error('Required parameter petId was null or undefined when calling updatePetWithForm.'); + } + + let localVarHeaders = this.defaultHeaders; + + let localVarCredential: string | undefined; + // authentication (petstore_auth) required + localVarCredential = this.configuration.lookupCredential('petstore_auth'); + if (localVarCredential) { + localVarHeaders = localVarHeaders.set('Authorization', 'Bearer ' + localVarCredential); + } + + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + // to determine the Content-Type header + const consumes: string[] = [ + 'application/x-www-form-urlencoded' + ]; + + const canConsumeForm = this.canConsumeForm(consumes); + + let localVarFormParams: { append(param: string, value: any): any; }; + let localVarUseForm = false; + let localVarConvertFormParamsToString = false; + if (localVarUseForm) { + localVarFormParams = new FormData(); + } else { + localVarFormParams = new HttpParams({encoder: this.encoder}); + } + + if (name !== undefined) { + localVarFormParams = localVarFormParams.append('name', name) as any || localVarFormParams; + } + if (status !== undefined) { + localVarFormParams = localVarFormParams.append('status', status) as any || localVarFormParams; + } + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; + return this.httpClient.request('post', `${this.configuration.basePath}${localVarPath}`, + { + context: localVarHttpContext, + body: localVarConvertFormParamsToString ? localVarFormParams.toString() : localVarFormParams, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); + } + + /** + * uploads an image + * + * @param petId ID of pet to update + * @param additionalMetadata Additional data to pass to server + * @param file file to upload + * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. + * @param reportProgress flag to report request and response progress. + */ + public uploadFile(petId: number, additionalMetadata?: string, file?: Blob, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable; + public uploadFile(petId: number, additionalMetadata?: string, file?: Blob, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>; + public uploadFile(petId: number, additionalMetadata?: string, file?: Blob, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>; + public uploadFile(petId: number, additionalMetadata?: string, file?: Blob, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable { + if (petId === null || petId === undefined) { + throw new Error('Required parameter petId was null or undefined when calling uploadFile.'); + } + + let localVarHeaders = this.defaultHeaders; + + let localVarCredential: string | undefined; + // authentication (petstore_auth) required + localVarCredential = this.configuration.lookupCredential('petstore_auth'); + if (localVarCredential) { + localVarHeaders = localVarHeaders.set('Authorization', 'Bearer ' + localVarCredential); + } + + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + 'application/json' + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + // to determine the Content-Type header + const consumes: string[] = [ + 'multipart/form-data' + ]; + + const canConsumeForm = this.canConsumeForm(consumes); + + let localVarFormParams: { append(param: string, value: any): any; }; + let localVarUseForm = false; + let localVarConvertFormParamsToString = false; + // use FormData to transmit files using content-type "multipart/form-data" + // see https://stackoverflow.com/questions/4007969/application-x-www-form-urlencoded-or-multipart-form-data + localVarUseForm = canConsumeForm; + if (localVarUseForm) { + localVarFormParams = new FormData(); + } else { + localVarFormParams = new HttpParams({encoder: this.encoder}); + } + + if (additionalMetadata !== undefined) { + localVarFormParams = localVarFormParams.append('additionalMetadata', additionalMetadata) as any || localVarFormParams; + } + if (file !== undefined) { + localVarFormParams = localVarFormParams.append('file', file) as any || localVarFormParams; + } + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}/uploadImage`; + return this.httpClient.request('post', `${this.configuration.basePath}${localVarPath}`, + { + context: localVarHttpContext, + body: localVarConvertFormParamsToString ? localVarFormParams.toString() : localVarFormParams, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); + } + +} diff --git a/samples/server/petstore/typescript-koa-server/api/store.service.ts b/samples/server/petstore/typescript-koa-server/api/store.service.ts new file mode 100644 index 00000000000..47b3c284654 --- /dev/null +++ b/samples/server/petstore/typescript-koa-server/api/store.service.ts @@ -0,0 +1,344 @@ +/** + * OpenAPI Petstore + * This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ +/* tslint:disable:no-unused-variable member-ordering */ + +import { Inject, Injectable, Optional } from '@angular/core'; +import { HttpClient, HttpHeaders, HttpParams, + HttpResponse, HttpEvent, HttpParameterCodec, HttpContext + } from '@angular/common/http'; +import { CustomHttpParameterCodec } from '../encoder'; +import { Observable } from 'rxjs'; + +// @ts-ignore +import { Order } from '../model/order'; + +// @ts-ignore +import { BASE_PATH, COLLECTION_FORMATS } from '../variables'; +import { Configuration } from '../configuration'; + + + +@Injectable({ + providedIn: 'root' +}) +export class StoreService { + + protected basePath = 'http://petstore.swagger.io/v2'; + public defaultHeaders = new HttpHeaders(); + public configuration = new Configuration(); + public encoder: HttpParameterCodec; + + constructor(protected httpClient: HttpClient, @Optional()@Inject(BASE_PATH) basePath: string|string[], @Optional() configuration: Configuration) { + if (configuration) { + this.configuration = configuration; + } + if (typeof this.configuration.basePath !== 'string') { + if (Array.isArray(basePath) && basePath.length > 0) { + basePath = basePath[0]; + } + + if (typeof basePath !== 'string') { + basePath = this.basePath; + } + this.configuration.basePath = basePath; + } + this.encoder = this.configuration.encoder || new CustomHttpParameterCodec(); + } + + + // @ts-ignore + private addToHttpParams(httpParams: HttpParams, value: any, key?: string): HttpParams { + if (typeof value === "object" && value instanceof Date === false) { + httpParams = this.addToHttpParamsRecursive(httpParams, value); + } else { + httpParams = this.addToHttpParamsRecursive(httpParams, value, key); + } + return httpParams; + } + + private addToHttpParamsRecursive(httpParams: HttpParams, value?: any, key?: string): HttpParams { + if (value == null) { + return httpParams; + } + + if (typeof value === "object") { + if (Array.isArray(value)) { + (value as any[]).forEach( elem => httpParams = this.addToHttpParamsRecursive(httpParams, elem, key)); + } else if (value instanceof Date) { + if (key != null) { + httpParams = httpParams.append(key, (value as Date).toISOString().substr(0, 10)); + } else { + throw Error("key may not be null if value is Date"); + } + } else { + Object.keys(value).forEach( k => httpParams = this.addToHttpParamsRecursive( + httpParams, value[k], key != null ? `${key}.${k}` : k)); + } + } else if (key != null) { + httpParams = httpParams.append(key, value); + } else { + throw Error("key may not be null if value is not object or array"); + } + return httpParams; + } + + /** + * Delete purchase order by ID + * For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors + * @param orderId ID of the order that needs to be deleted + * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. + * @param reportProgress flag to report request and response progress. + */ + public deleteOrder(orderId: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; + public deleteOrder(orderId: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public deleteOrder(orderId: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public deleteOrder(orderId: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { + if (orderId === null || orderId === undefined) { + throw new Error('Required parameter orderId was null or undefined when calling deleteOrder.'); + } + + let localVarHeaders = this.defaultHeaders; + + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/store/order/${this.configuration.encodeParam({name: "orderId", value: orderId, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; + return this.httpClient.request('delete', `${this.configuration.basePath}${localVarPath}`, + { + context: localVarHttpContext, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); + } + + /** + * Returns pet inventories by status + * Returns a map of status codes to quantities + * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. + * @param reportProgress flag to report request and response progress. + */ + public getInventory(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<{ [key: string]: number; }>; + public getInventory(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>; + public getInventory(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>; + public getInventory(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable { + + let localVarHeaders = this.defaultHeaders; + + let localVarCredential: string | undefined; + // authentication (api_key) required + localVarCredential = this.configuration.lookupCredential('api_key'); + if (localVarCredential) { + localVarHeaders = localVarHeaders.set('api_key', localVarCredential); + } + + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + 'application/json' + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/store/inventory`; + return this.httpClient.request<{ [key: string]: number; }>('get', `${this.configuration.basePath}${localVarPath}`, + { + context: localVarHttpContext, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); + } + + /** + * Find purchase order by ID + * For valid response try integer IDs with value <= 5 or > 10. Other values will generate exceptions + * @param orderId ID of pet that needs to be fetched + * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. + * @param reportProgress flag to report request and response progress. + */ + public getOrderById(orderId: number, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable; + public getOrderById(orderId: number, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; + public getOrderById(orderId: number, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; + public getOrderById(orderId: number, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable { + if (orderId === null || orderId === undefined) { + throw new Error('Required parameter orderId was null or undefined when calling getOrderById.'); + } + + let localVarHeaders = this.defaultHeaders; + + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + 'application/xml', + 'application/json' + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/store/order/${this.configuration.encodeParam({name: "orderId", value: orderId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; + return this.httpClient.request('get', `${this.configuration.basePath}${localVarPath}`, + { + context: localVarHttpContext, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); + } + + /** + * Place an order for a pet + * + * @param order order placed for purchasing the pet + * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. + * @param reportProgress flag to report request and response progress. + */ + public placeOrder(order: Order, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable; + public placeOrder(order: Order, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; + public placeOrder(order: Order, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; + public placeOrder(order: Order, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable { + if (order === null || order === undefined) { + throw new Error('Required parameter order was null or undefined when calling placeOrder.'); + } + + let localVarHeaders = this.defaultHeaders; + + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + 'application/xml', + 'application/json' + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + + // to determine the Content-Type header + const consumes: string[] = [ + 'application/json' + ]; + const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes); + if (httpContentTypeSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Content-Type', httpContentTypeSelected); + } + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/store/order`; + return this.httpClient.request('post', `${this.configuration.basePath}${localVarPath}`, + { + context: localVarHttpContext, + body: order, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); + } + +} diff --git a/samples/server/petstore/typescript-koa-server/api/user.service.ts b/samples/server/petstore/typescript-koa-server/api/user.service.ts new file mode 100644 index 00000000000..62cbf7b6e8d --- /dev/null +++ b/samples/server/petstore/typescript-koa-server/api/user.service.ts @@ -0,0 +1,659 @@ +/** + * OpenAPI Petstore + * This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ +/* tslint:disable:no-unused-variable member-ordering */ + +import { Inject, Injectable, Optional } from '@angular/core'; +import { HttpClient, HttpHeaders, HttpParams, + HttpResponse, HttpEvent, HttpParameterCodec, HttpContext + } from '@angular/common/http'; +import { CustomHttpParameterCodec } from '../encoder'; +import { Observable } from 'rxjs'; + +// @ts-ignore +import { User } from '../model/user'; + +// @ts-ignore +import { BASE_PATH, COLLECTION_FORMATS } from '../variables'; +import { Configuration } from '../configuration'; + + + +@Injectable({ + providedIn: 'root' +}) +export class UserService { + + protected basePath = 'http://petstore.swagger.io/v2'; + public defaultHeaders = new HttpHeaders(); + public configuration = new Configuration(); + public encoder: HttpParameterCodec; + + constructor(protected httpClient: HttpClient, @Optional()@Inject(BASE_PATH) basePath: string|string[], @Optional() configuration: Configuration) { + if (configuration) { + this.configuration = configuration; + } + if (typeof this.configuration.basePath !== 'string') { + if (Array.isArray(basePath) && basePath.length > 0) { + basePath = basePath[0]; + } + + if (typeof basePath !== 'string') { + basePath = this.basePath; + } + this.configuration.basePath = basePath; + } + this.encoder = this.configuration.encoder || new CustomHttpParameterCodec(); + } + + + // @ts-ignore + private addToHttpParams(httpParams: HttpParams, value: any, key?: string): HttpParams { + if (typeof value === "object" && value instanceof Date === false) { + httpParams = this.addToHttpParamsRecursive(httpParams, value); + } else { + httpParams = this.addToHttpParamsRecursive(httpParams, value, key); + } + return httpParams; + } + + private addToHttpParamsRecursive(httpParams: HttpParams, value?: any, key?: string): HttpParams { + if (value == null) { + return httpParams; + } + + if (typeof value === "object") { + if (Array.isArray(value)) { + (value as any[]).forEach( elem => httpParams = this.addToHttpParamsRecursive(httpParams, elem, key)); + } else if (value instanceof Date) { + if (key != null) { + httpParams = httpParams.append(key, (value as Date).toISOString().substr(0, 10)); + } else { + throw Error("key may not be null if value is Date"); + } + } else { + Object.keys(value).forEach( k => httpParams = this.addToHttpParamsRecursive( + httpParams, value[k], key != null ? `${key}.${k}` : k)); + } + } else if (key != null) { + httpParams = httpParams.append(key, value); + } else { + throw Error("key may not be null if value is not object or array"); + } + return httpParams; + } + + /** + * Create user + * This can only be done by the logged in user. + * @param user Created user object + * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. + * @param reportProgress flag to report request and response progress. + */ + public createUser(user: User, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; + public createUser(user: User, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public createUser(user: User, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public createUser(user: User, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { + if (user === null || user === undefined) { + throw new Error('Required parameter user was null or undefined when calling createUser.'); + } + + let localVarHeaders = this.defaultHeaders; + + let localVarCredential: string | undefined; + // authentication (api_key) required + localVarCredential = this.configuration.lookupCredential('api_key'); + if (localVarCredential) { + localVarHeaders = localVarHeaders.set('api_key', localVarCredential); + } + + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + + // to determine the Content-Type header + const consumes: string[] = [ + 'application/json' + ]; + const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes); + if (httpContentTypeSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Content-Type', httpContentTypeSelected); + } + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/user`; + return this.httpClient.request('post', `${this.configuration.basePath}${localVarPath}`, + { + context: localVarHttpContext, + body: user, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); + } + + /** + * Creates list of users with given input array + * + * @param user List of user object + * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. + * @param reportProgress flag to report request and response progress. + */ + public createUsersWithArrayInput(user: Array, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; + public createUsersWithArrayInput(user: Array, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public createUsersWithArrayInput(user: Array, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public createUsersWithArrayInput(user: Array, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { + if (user === null || user === undefined) { + throw new Error('Required parameter user was null or undefined when calling createUsersWithArrayInput.'); + } + + let localVarHeaders = this.defaultHeaders; + + let localVarCredential: string | undefined; + // authentication (api_key) required + localVarCredential = this.configuration.lookupCredential('api_key'); + if (localVarCredential) { + localVarHeaders = localVarHeaders.set('api_key', localVarCredential); + } + + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + + // to determine the Content-Type header + const consumes: string[] = [ + 'application/json' + ]; + const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes); + if (httpContentTypeSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Content-Type', httpContentTypeSelected); + } + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/user/createWithArray`; + return this.httpClient.request('post', `${this.configuration.basePath}${localVarPath}`, + { + context: localVarHttpContext, + body: user, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); + } + + /** + * Creates list of users with given input array + * + * @param user List of user object + * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. + * @param reportProgress flag to report request and response progress. + */ + public createUsersWithListInput(user: Array, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; + public createUsersWithListInput(user: Array, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public createUsersWithListInput(user: Array, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public createUsersWithListInput(user: Array, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { + if (user === null || user === undefined) { + throw new Error('Required parameter user was null or undefined when calling createUsersWithListInput.'); + } + + let localVarHeaders = this.defaultHeaders; + + let localVarCredential: string | undefined; + // authentication (api_key) required + localVarCredential = this.configuration.lookupCredential('api_key'); + if (localVarCredential) { + localVarHeaders = localVarHeaders.set('api_key', localVarCredential); + } + + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + + // to determine the Content-Type header + const consumes: string[] = [ + 'application/json' + ]; + const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes); + if (httpContentTypeSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Content-Type', httpContentTypeSelected); + } + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/user/createWithList`; + return this.httpClient.request('post', `${this.configuration.basePath}${localVarPath}`, + { + context: localVarHttpContext, + body: user, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); + } + + /** + * Delete user + * This can only be done by the logged in user. + * @param username The name that needs to be deleted + * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. + * @param reportProgress flag to report request and response progress. + */ + public deleteUser(username: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; + public deleteUser(username: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public deleteUser(username: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public deleteUser(username: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { + if (username === null || username === undefined) { + throw new Error('Required parameter username was null or undefined when calling deleteUser.'); + } + + let localVarHeaders = this.defaultHeaders; + + let localVarCredential: string | undefined; + // authentication (api_key) required + localVarCredential = this.configuration.lookupCredential('api_key'); + if (localVarCredential) { + localVarHeaders = localVarHeaders.set('api_key', localVarCredential); + } + + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/user/${this.configuration.encodeParam({name: "username", value: username, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; + return this.httpClient.request('delete', `${this.configuration.basePath}${localVarPath}`, + { + context: localVarHttpContext, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); + } + + /** + * Get user by user name + * + * @param username The name that needs to be fetched. Use user1 for testing. + * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. + * @param reportProgress flag to report request and response progress. + */ + public getUserByName(username: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable; + public getUserByName(username: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; + public getUserByName(username: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; + public getUserByName(username: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable { + if (username === null || username === undefined) { + throw new Error('Required parameter username was null or undefined when calling getUserByName.'); + } + + let localVarHeaders = this.defaultHeaders; + + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + 'application/xml', + 'application/json' + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/user/${this.configuration.encodeParam({name: "username", value: username, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; + return this.httpClient.request('get', `${this.configuration.basePath}${localVarPath}`, + { + context: localVarHttpContext, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); + } + + /** + * Logs user into the system + * + * @param username The user name for login + * @param password The password for login in clear text + * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. + * @param reportProgress flag to report request and response progress. + */ + public loginUser(username: string, password: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable; + public loginUser(username: string, password: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; + public loginUser(username: string, password: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; + public loginUser(username: string, password: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable { + if (username === null || username === undefined) { + throw new Error('Required parameter username was null or undefined when calling loginUser.'); + } + if (password === null || password === undefined) { + throw new Error('Required parameter password was null or undefined when calling loginUser.'); + } + + let localVarQueryParameters = new HttpParams({encoder: this.encoder}); + if (username !== undefined && username !== null) { + localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, + username, 'username'); + } + if (password !== undefined && password !== null) { + localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, + password, 'password'); + } + + let localVarHeaders = this.defaultHeaders; + + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + 'application/xml', + 'application/json' + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/user/login`; + return this.httpClient.request('get', `${this.configuration.basePath}${localVarPath}`, + { + context: localVarHttpContext, + params: localVarQueryParameters, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); + } + + /** + * Logs out current logged in user session + * + * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. + * @param reportProgress flag to report request and response progress. + */ + public logoutUser(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; + public logoutUser(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public logoutUser(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public logoutUser(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { + + let localVarHeaders = this.defaultHeaders; + + let localVarCredential: string | undefined; + // authentication (api_key) required + localVarCredential = this.configuration.lookupCredential('api_key'); + if (localVarCredential) { + localVarHeaders = localVarHeaders.set('api_key', localVarCredential); + } + + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/user/logout`; + return this.httpClient.request('get', `${this.configuration.basePath}${localVarPath}`, + { + context: localVarHttpContext, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); + } + + /** + * Updated user + * This can only be done by the logged in user. + * @param username name that need to be deleted + * @param user Updated user object + * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. + * @param reportProgress flag to report request and response progress. + */ + public updateUser(username: string, user: User, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; + public updateUser(username: string, user: User, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public updateUser(username: string, user: User, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public updateUser(username: string, user: User, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { + if (username === null || username === undefined) { + throw new Error('Required parameter username was null or undefined when calling updateUser.'); + } + if (user === null || user === undefined) { + throw new Error('Required parameter user was null or undefined when calling updateUser.'); + } + + let localVarHeaders = this.defaultHeaders; + + let localVarCredential: string | undefined; + // authentication (api_key) required + localVarCredential = this.configuration.lookupCredential('api_key'); + if (localVarCredential) { + localVarHeaders = localVarHeaders.set('api_key', localVarCredential); + } + + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + + // to determine the Content-Type header + const consumes: string[] = [ + 'application/json' + ]; + const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes); + if (httpContentTypeSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Content-Type', httpContentTypeSelected); + } + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/user/${this.configuration.encodeParam({name: "username", value: username, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; + return this.httpClient.request('put', `${this.configuration.basePath}${localVarPath}`, + { + context: localVarHttpContext, + body: user, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); + } + +} diff --git a/samples/server/petstore/typescript-koa-server/configuration.ts b/samples/server/petstore/typescript-koa-server/configuration.ts new file mode 100644 index 00000000000..c119def95af --- /dev/null +++ b/samples/server/petstore/typescript-koa-server/configuration.ts @@ -0,0 +1,186 @@ +import { HttpParameterCodec } from '@angular/common/http'; +import { Param } from './param'; + +export interface ConfigurationParameters { + /** + * @deprecated Since 5.0. Use credentials instead + */ + apiKeys?: {[ key: string ]: string}; + username?: string; + password?: string; + /** + * @deprecated Since 5.0. Use credentials instead + */ + accessToken?: string | (() => string); + basePath?: string; + withCredentials?: boolean; + /** + * Takes care of encoding query- and form-parameters. + */ + encoder?: HttpParameterCodec; + /** + * Override the default method for encoding path parameters in various + * styles. + *

+ * See {@link README.md} for more details + *

+ */ + encodeParam?: (param: Param) => string; + /** + * The keys are the names in the securitySchemes section of the OpenAPI + * document. They should map to the value used for authentication + * minus any standard prefixes such as 'Basic' or 'Bearer'. + */ + credentials?: {[ key: string ]: string | (() => string | undefined)}; +} + +export class Configuration { + /** + * @deprecated Since 5.0. Use credentials instead + */ + apiKeys?: {[ key: string ]: string}; + username?: string; + password?: string; + /** + * @deprecated Since 5.0. Use credentials instead + */ + accessToken?: string | (() => string); + basePath?: string; + withCredentials?: boolean; + /** + * Takes care of encoding query- and form-parameters. + */ + encoder?: HttpParameterCodec; + /** + * Encoding of various path parameter + * styles. + *

+ * See {@link README.md} for more details + *

+ */ + encodeParam: (param: Param) => string; + /** + * The keys are the names in the securitySchemes section of the OpenAPI + * document. They should map to the value used for authentication + * minus any standard prefixes such as 'Basic' or 'Bearer'. + */ + credentials: {[ key: string ]: string | (() => string | undefined)}; + + constructor(configurationParameters: ConfigurationParameters = {}) { + this.apiKeys = configurationParameters.apiKeys; + this.username = configurationParameters.username; + this.password = configurationParameters.password; + this.accessToken = configurationParameters.accessToken; + this.basePath = configurationParameters.basePath; + this.withCredentials = configurationParameters.withCredentials; + this.encoder = configurationParameters.encoder; + if (configurationParameters.encodeParam) { + this.encodeParam = configurationParameters.encodeParam; + } + else { + this.encodeParam = param => this.defaultEncodeParam(param); + } + if (configurationParameters.credentials) { + this.credentials = configurationParameters.credentials; + } + else { + this.credentials = {}; + } + + // init default api_key credential + if (!this.credentials['api_key']) { + this.credentials['api_key'] = () => { + if (this.apiKeys === null || this.apiKeys === undefined) { + return undefined; + } else { + return this.apiKeys['api_key'] || this.apiKeys['api_key']; + } + }; + } + + // init default petstore_auth credential + if (!this.credentials['petstore_auth']) { + this.credentials['petstore_auth'] = () => { + return typeof this.accessToken === 'function' + ? this.accessToken() + : this.accessToken; + }; + } + } + + /** + * Select the correct content-type to use for a request. + * Uses {@link Configuration#isJsonMime} to determine the correct content-type. + * If no content type is found return the first found type if the contentTypes is not empty + * @param contentTypes - the array of content types that are available for selection + * @returns the selected content-type or undefined if no selection could be made. + */ + public selectHeaderContentType (contentTypes: string[]): string | undefined { + if (contentTypes.length === 0) { + return undefined; + } + + const type = contentTypes.find((x: string) => this.isJsonMime(x)); + if (type === undefined) { + return contentTypes[0]; + } + return type; + } + + /** + * Select the correct accept content-type to use for a request. + * Uses {@link Configuration#isJsonMime} to determine the correct accept content-type. + * If no content type is found return the first found type if the contentTypes is not empty + * @param accepts - the array of content types that are available for selection. + * @returns the selected content-type or undefined if no selection could be made. + */ + public selectHeaderAccept(accepts: string[]): string | undefined { + if (accepts.length === 0) { + return undefined; + } + + const type = accepts.find((x: string) => this.isJsonMime(x)); + if (type === undefined) { + return accepts[0]; + } + return type; + } + + /** + * Check if the given MIME is a JSON MIME. + * JSON MIME examples: + * application/json + * application/json; charset=UTF8 + * APPLICATION/JSON + * application/vnd.company+json + * @param mime - MIME (Multipurpose Internet Mail Extensions) + * @return True if the given MIME is JSON, false otherwise. + */ + public isJsonMime(mime: string): boolean { + const jsonMime: RegExp = new RegExp('^(application\/json|[^;/ \t]+\/[^;/ \t]+[+]json)[ \t]*(;.*)?$', 'i'); + return mime !== null && (jsonMime.test(mime) || mime.toLowerCase() === 'application/json-patch+json'); + } + + public lookupCredential(key: string): string | undefined { + const value = this.credentials[key]; + return typeof value === 'function' + ? value() + : value; + } + + private defaultEncodeParam(param: Param): string { + // This implementation exists as fallback for missing configuration + // and for backwards compatibility to older typescript-angular generator versions. + // It only works for the 'simple' parameter style. + // Date-handling only works for the 'date-time' format. + // All other styles and Date-formats are probably handled incorrectly. + // + // But: if that's all you need (i.e.: the most common use-case): no need for customization! + + const value = param.dataFormat === 'date-time' && param.value instanceof Date + ? (param.value as Date).toISOString() + : param.value; + + return encodeURIComponent(String(value)); + } +} diff --git a/samples/server/petstore/typescript-koa-server/encoder.ts b/samples/server/petstore/typescript-koa-server/encoder.ts new file mode 100644 index 00000000000..138c4d5cf2c --- /dev/null +++ b/samples/server/petstore/typescript-koa-server/encoder.ts @@ -0,0 +1,20 @@ +import { HttpParameterCodec } from '@angular/common/http'; + +/** + * Custom HttpParameterCodec + * Workaround for https://github.com/angular/angular/issues/18261 + */ +export class CustomHttpParameterCodec implements HttpParameterCodec { + encodeKey(k: string): string { + return encodeURIComponent(k); + } + encodeValue(v: string): string { + return encodeURIComponent(v); + } + decodeKey(k: string): string { + return decodeURIComponent(k); + } + decodeValue(v: string): string { + return decodeURIComponent(v); + } +} diff --git a/samples/server/petstore/typescript-koa-server/git_push.sh b/samples/server/petstore/typescript-koa-server/git_push.sh new file mode 100644 index 00000000000..f53a75d4fab --- /dev/null +++ b/samples/server/petstore/typescript-koa-server/git_push.sh @@ -0,0 +1,57 @@ +#!/bin/sh +# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/ +# +# Usage example: /bin/sh ./git_push.sh wing328 openapi-petstore-perl "minor update" "gitlab.com" + +git_user_id=$1 +git_repo_id=$2 +release_note=$3 +git_host=$4 + +if [ "$git_host" = "" ]; then + git_host="github.com" + echo "[INFO] No command line input provided. Set \$git_host to $git_host" +fi + +if [ "$git_user_id" = "" ]; then + git_user_id="GIT_USER_ID" + echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" +fi + +if [ "$git_repo_id" = "" ]; then + git_repo_id="GIT_REPO_ID" + echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" +fi + +if [ "$release_note" = "" ]; then + release_note="Minor update" + echo "[INFO] No command line input provided. Set \$release_note to $release_note" +fi + +# Initialize the local directory as a Git repository +git init + +# Adds the files in the local repository and stages them for commit. +git add . + +# Commits the tracked changes and prepares them to be pushed to a remote repository. +git commit -m "$release_note" + +# Sets the new remote +git_remote=$(git remote) +if [ "$git_remote" = "" ]; then # git remote not defined + + if [ "$GIT_TOKEN" = "" ]; then + echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." + git remote add origin https://${git_host}/${git_user_id}/${git_repo_id}.git + else + git remote add origin https://${git_user_id}:"${GIT_TOKEN}"@${git_host}/${git_user_id}/${git_repo_id}.git + fi + +fi + +git pull origin master + +# Pushes (Forces) the changes in the local repository up to the remote repository +echo "Git pushing to https://${git_host}/${git_user_id}/${git_repo_id}.git" +git push origin master 2>&1 | grep -v 'To https' diff --git a/samples/server/petstore/typescript-koa-server/index.ts b/samples/server/petstore/typescript-koa-server/index.ts new file mode 100644 index 00000000000..104dd3d21e3 --- /dev/null +++ b/samples/server/petstore/typescript-koa-server/index.ts @@ -0,0 +1,6 @@ +export * from './api/api'; +export * from './model/models'; +export * from './variables'; +export * from './configuration'; +export * from './api.module'; +export * from './param'; diff --git a/samples/server/petstore/typescript-koa-server/model/apiResponse.ts b/samples/server/petstore/typescript-koa-server/model/apiResponse.ts new file mode 100644 index 00000000000..682ba478921 --- /dev/null +++ b/samples/server/petstore/typescript-koa-server/model/apiResponse.ts @@ -0,0 +1,22 @@ +/** + * OpenAPI Petstore + * This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** + * Describes the result of uploading an image resource + */ +export interface ApiResponse { + code?: number; + type?: string; + message?: string; +} + diff --git a/samples/server/petstore/typescript-koa-server/model/category.ts b/samples/server/petstore/typescript-koa-server/model/category.ts new file mode 100644 index 00000000000..b988b6827a0 --- /dev/null +++ b/samples/server/petstore/typescript-koa-server/model/category.ts @@ -0,0 +1,21 @@ +/** + * OpenAPI Petstore + * This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** + * A category for a pet + */ +export interface Category { + id?: number; + name?: string; +} + diff --git a/samples/server/petstore/typescript-koa-server/model/models.ts b/samples/server/petstore/typescript-koa-server/model/models.ts new file mode 100644 index 00000000000..8607c5dabd0 --- /dev/null +++ b/samples/server/petstore/typescript-koa-server/model/models.ts @@ -0,0 +1,6 @@ +export * from './apiResponse'; +export * from './category'; +export * from './order'; +export * from './pet'; +export * from './tag'; +export * from './user'; diff --git a/samples/server/petstore/typescript-koa-server/model/order.ts b/samples/server/petstore/typescript-koa-server/model/order.ts new file mode 100644 index 00000000000..a29bebe4906 --- /dev/null +++ b/samples/server/petstore/typescript-koa-server/model/order.ts @@ -0,0 +1,37 @@ +/** + * OpenAPI Petstore + * This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** + * An order for a pets from the pet store + */ +export interface Order { + id?: number; + petId?: number; + quantity?: number; + shipDate?: string; + /** + * Order Status + */ + status?: Order.StatusEnum; + complete?: boolean; +} +export namespace Order { + export type StatusEnum = 'placed' | 'approved' | 'delivered'; + export const StatusEnum = { + Placed: 'placed' as StatusEnum, + Approved: 'approved' as StatusEnum, + Delivered: 'delivered' as StatusEnum + }; +} + + diff --git a/samples/server/petstore/typescript-koa-server/model/pet.ts b/samples/server/petstore/typescript-koa-server/model/pet.ts new file mode 100644 index 00000000000..e0404395f91 --- /dev/null +++ b/samples/server/petstore/typescript-koa-server/model/pet.ts @@ -0,0 +1,39 @@ +/** + * OpenAPI Petstore + * This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ +import { Category } from './category'; +import { Tag } from './tag'; + + +/** + * A pet for sale in the pet store + */ +export interface Pet { + id?: number; + category?: Category; + name: string; + photoUrls: Array; + tags?: Array; + /** + * pet status in the store + */ + status?: Pet.StatusEnum; +} +export namespace Pet { + export type StatusEnum = 'available' | 'pending' | 'sold'; + export const StatusEnum = { + Available: 'available' as StatusEnum, + Pending: 'pending' as StatusEnum, + Sold: 'sold' as StatusEnum + }; +} + + diff --git a/samples/server/petstore/typescript-koa-server/model/tag.ts b/samples/server/petstore/typescript-koa-server/model/tag.ts new file mode 100644 index 00000000000..b6ff210e8df --- /dev/null +++ b/samples/server/petstore/typescript-koa-server/model/tag.ts @@ -0,0 +1,21 @@ +/** + * OpenAPI Petstore + * This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** + * A tag for a pet + */ +export interface Tag { + id?: number; + name?: string; +} + diff --git a/samples/server/petstore/typescript-koa-server/model/user.ts b/samples/server/petstore/typescript-koa-server/model/user.ts new file mode 100644 index 00000000000..fce51005300 --- /dev/null +++ b/samples/server/petstore/typescript-koa-server/model/user.ts @@ -0,0 +1,30 @@ +/** + * OpenAPI Petstore + * This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** + * A User who is purchasing from the pet store + */ +export interface User { + id?: number; + username?: string; + firstName?: string; + lastName?: string; + email?: string; + password?: string; + phone?: string; + /** + * User Status + */ + userStatus?: number; +} + diff --git a/samples/server/petstore/typescript-koa-server/param.ts b/samples/server/petstore/typescript-koa-server/param.ts new file mode 100644 index 00000000000..78a2d20a643 --- /dev/null +++ b/samples/server/petstore/typescript-koa-server/param.ts @@ -0,0 +1,69 @@ +/** + * Standard parameter styles defined by OpenAPI spec + */ +export type StandardParamStyle = + | 'matrix' + | 'label' + | 'form' + | 'simple' + | 'spaceDelimited' + | 'pipeDelimited' + | 'deepObject' + ; + +/** + * The OpenAPI standard {@link StandardParamStyle}s may be extended by custom styles by the user. + */ +export type ParamStyle = StandardParamStyle | string; + +/** + * Standard parameter locations defined by OpenAPI spec + */ +export type ParamLocation = 'query' | 'header' | 'path' | 'cookie'; + +/** + * Standard types as defined in OpenAPI Specification: Data Types + */ +export type StandardDataType = + | "integer" + | "number" + | "boolean" + | "string" + | "object" + | "array" + ; + +/** + * Standard {@link DataType}s plus your own types/classes. + */ +export type DataType = StandardDataType | string; + +/** + * Standard formats as defined in OpenAPI Specification: Data Types + */ +export type StandardDataFormat = + | "int32" + | "int64" + | "float" + | "double" + | "byte" + | "binary" + | "date" + | "date-time" + | "password" + ; + +export type DataFormat = StandardDataFormat | string; + +/** + * The parameter to encode. + */ +export interface Param { + name: string; + value: unknown; + in: ParamLocation; + style: ParamStyle, + explode: boolean; + dataType: DataType; + dataFormat: DataFormat | undefined; +} diff --git a/samples/server/petstore/typescript-koa-server/variables.ts b/samples/server/petstore/typescript-koa-server/variables.ts new file mode 100644 index 00000000000..6fe58549f39 --- /dev/null +++ b/samples/server/petstore/typescript-koa-server/variables.ts @@ -0,0 +1,9 @@ +import { InjectionToken } from '@angular/core'; + +export const BASE_PATH = new InjectionToken('basePath'); +export const COLLECTION_FORMATS = { + 'csv': ',', + 'tsv': ' ', + 'ssv': ' ', + 'pipes': '|' +}