diff --git a/.travis.yml b/.travis.yml index 68a526cf1b4..e0290b10205 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,6 +24,12 @@ before_install: - docker pull swaggerapi/petstore - docker run -d -e SWAGGER_HOST=http://petstore.swagger.io -e SWAGGER_BASE_PATH=/v2 -p 80:8080 swaggerapi/petstore - docker ps -a + # Add bats test framework and cURL for Bash script integration tests + - sudo add-apt-repository ppa:duggan/bats --yes + - sudo apt-get update -qq + - sudo apt-get install -qq bats + - sudo apt-get install -qq curl + # show host table to confirm petstore.swagger.io is mapped to localhost - cat /etc/hosts diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b187c39192c..83166fa1a53 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -30,6 +30,7 @@ For a list of variables available in the template, please refer to this [page](h ### Style guide Code change should conform to the programming style guide of the respective languages: - Android: https://source.android.com/source/code-style.html +- Bash: https://github.com/bahamas10/bash-style-guide - C#: https://msdn.microsoft.com/en-us/library/vstudio/ff926074.aspx - C++: https://google.github.io/styleguide/cppguide.html - Clojure: https://github.com/bbatsov/clojure-style-guide diff --git a/README.md b/README.md index 82fb0c5c383..e9c68acc931 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ ## Overview This is the swagger codegen project, which allows generation of API client libraries (SDK generation), server stubs and documentation automatically given an [OpenAPI Spec](https://github.com/OAI/OpenAPI-Specification). Currently, the following languages/frameworks are supported: -- **API clients**: **ActionScript**, **C#** (.net 2.0, 4.0 or later), **C++** (cpprest, Qt5, Tizen), **Clojure**, **Dart**, **Go**, **Groovy**, **Haskell**, **Java** (Jersey1.x, Jersey2.x, OkHttp, Retrofit1.x, Retrofit2.x, Feign), **Node.js** (ES5, ES6, AngularJS with Google Closure Compiler annotations) **Objective-C**, **Perl**, **PHP**, **Python**, **Ruby**, **Scala**, **Swift** (2.x, 3.x), **Typescript** (Angular1.x, Angular2.x, Fetch, Node) +- **API clients**: **ActionScript**, **Bash**,**C#** (.net 2.0, 4.0 or later), **C++** (cpprest, Qt5, Tizen), **Clojure**, **Dart**, **Go**, **Groovy**, **Haskell**, **Java** (Jersey1.x, Jersey2.x, OkHttp, Retrofit1.x, Retrofit2.x, Feign), **Node.js** (ES5, ES6, AngularJS with Google Closure Compiler annotations) **Objective-C**, **Perl**, **PHP**, **Python**, **Ruby**, **Scala**, **Swift** (2.x, 3.x), **Typescript** (Angular1.x, Angular2.x, Fetch, Node) - **Server stubs**: **C#** (ASP.NET Core, NancyFx), **Erlang**, **Go**, **Haskell**, **Java** (MSF4J, Spring, Undertow, JAX-RS: CDI, CXF, Inflector, RestEasy), **PHP** (Lumen, Slim, Silex), **Python** (Flask), **NodeJS**, **Ruby** (Sinatra, Rails5), **Scala** (Scalatra) - **API documentation generators**: **HTML**, **Confluence Wiki** - **Others**: **JMeter** @@ -463,6 +463,7 @@ AndroidClientCodegen.java AspNet5ServerCodegen.java AspNetCoreServerCodegen.java AsyncScalaClientCodegen.java +BashClientCodegen.java CSharpClientCodegen.java ClojureClientCodegen.java CsharpDotNet2ClientCodegen.java @@ -891,6 +892,7 @@ Swagger Codegen core team members are contributors who have been making signific Here is a list of template creators: * API Clients: * Akka-Scala: @cchafer + * Bash: @bkryza * C++ REST: @Danielku15 * C# (.NET 2.0): @who * Clojure: @xhh diff --git a/bin/bash-petstore.sh b/bin/bash-petstore.sh new file mode 100755 index 00000000000..9988a1157f2 --- /dev/null +++ b/bin/bash-petstore.sh @@ -0,0 +1,31 @@ +#!/bin/sh + +SCRIPT="$0" + +while [ -h "$SCRIPT" ] ; do + ls=`ls -ld "$SCRIPT"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + SCRIPT="$link" + else + SCRIPT=`dirname "$SCRIPT"`/"$link" + fi +done + +if [ ! -d "${APP_DIR}" ]; then + APP_DIR=`dirname "$SCRIPT"`/.. + APP_DIR=`cd "${APP_DIR}"; pwd` +fi + +executable="./modules/swagger-codegen-cli/target/swagger-codegen-cli.jar" + +if [ ! -f "$executable" ] +then + mvn clean package +fi + +# if you've executed sbt assembly previously it will use that instead. +export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties" +args="$@ generate -t modules/swagger-codegen/src/main/resources/bash -i modules/swagger-codegen/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -l bash -o samples/client/petstore/bash -c modules/swagger-codegen/src/test/resources/2_0/bash-config.json" + +java $JAVA_OPTS -jar $executable $args diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/BashClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/BashClientCodegen.java new file mode 100644 index 00000000000..e96fea31da7 --- /dev/null +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/BashClientCodegen.java @@ -0,0 +1,655 @@ +package io.swagger.codegen.languages; + +import io.swagger.codegen.*; +import io.swagger.models.properties.*; +import io.swagger.models.parameters.*; +import io.swagger.models.Model; +import io.swagger.models.Operation; +import io.swagger.models.Swagger; +import io.swagger.models.properties.ArrayProperty; +import io.swagger.models.properties.MapProperty; +import io.swagger.models.properties.Property; + +import org.apache.commons.lang3.StringEscapeUtils; +import org.apache.commons.lang3.StringUtils; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.*; +import java.io.File; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.core.JsonGenerationException; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.node.ObjectNode; + +public class BashClientCodegen extends DefaultCodegen implements CodegenConfig { + + protected String apiVersion = "1.0.0"; + + protected String curlOptions; + protected boolean processMarkdown = false; + protected String scriptName = "client.sh"; + protected boolean generateBashCompletion = false; + protected boolean generateZshCompletion = false; + protected String hostEnvironmentVariable; + protected String basicAuthEnvironmentVariable; + protected String apiKeyAuthEnvironmentVariable; + + + public static final String CURL_OPTIONS = "curlOptions"; + public static final String PROCESS_MARKDOWN = "processMarkdown"; + public static final String SCRIPT_NAME = "scriptName"; + public static final String + GENERATE_BASH_COMPLETION = "generateBashCompletion"; + public static final String + GENERATE_ZSH_COMPLETION = "generateZshCompletion"; + public static final String + HOST_ENVIRONMENT_VARIABLE_NAME = "hostEnvironmentVariable"; + public static final String + BASIC_AUTH_ENVIRONMENT_VARIABLE_NAME = "basicAuthEnvironmentVariable"; + public static final String + APIKEY_AUTH_ENVIRONMENT_VARIABLE_NAME = "apiKeyAuthEnvironmentVariable"; + + /** + * Configures the type of generator. + * + * @return the CodegenType for this generator + * @see io.swagger.codegen.CodegenType + */ + public CodegenType getTag() { + return CodegenType.CLIENT; + } + + /** + * Configures a friendly name for the generator. This will be used by + * the generator to select the library with the -l flag. + * + * @return the friendly name for the generator + */ + public String getName() { + return "bash"; + } + + /** + * Returns human-friendly help for the generator. Provide the consumer with + * help tips, parameters here + * + * @return A string value for the help message + */ + public String getHelp() { + return "Generates a Bash client script based on cURL."; + } + + public BashClientCodegen() { + super(); + + /** + * Set the output folder here + */ + outputFolder = "generated-code/bash"; + + /** + * No model files. + */ + modelTemplateFiles.clear(); + + + /** + * No API files. + */ + apiTemplateFiles.clear(); + + + /** + * Templates location for client script and bash completion template. + */ + templateDir = "bash"; + + + /** + * Allow the user to force the script to always include certain cURL + * comamnds + */ + cliOptions.add(CliOption.newString(CURL_OPTIONS, "Default cURL options")); + cliOptions.add(CliOption.newBoolean(PROCESS_MARKDOWN, + "Convert all Markdown Markup into terminal formatting")); + cliOptions.add(CliOption.newString(SCRIPT_NAME, + "The name of the script that will be generated "+ + "(e.g. petstore-cli)")); + cliOptions.add(CliOption.newBoolean(GENERATE_BASH_COMPLETION, + "Whether to generate the Bash completion script")); + cliOptions.add(CliOption.newBoolean(GENERATE_ZSH_COMPLETION, + "Whether to generate the Zsh completion script")); + cliOptions.add(CliOption.newString(HOST_ENVIRONMENT_VARIABLE_NAME, + "Name of environment variable where host can be defined "+ + "(e.g. PETSTORE_HOST='http://petstore.swagger.io:8080')")); + cliOptions.add(CliOption.newString(BASIC_AUTH_ENVIRONMENT_VARIABLE_NAME, + "Name of environment variable where username and password " + + + "can be defined (e.g. PETSTORE_CREDS='username:password')")); + cliOptions.add(CliOption.newBoolean(APIKEY_AUTH_ENVIRONMENT_VARIABLE_NAME, + "Name of environment variable where API key " + + + "can be defined (e.g. PETSTORE_APIKEY='kjhasdGASDa5asdASD')")); + + /** + * Bash reserved words. + */ + reservedWords = new HashSet ( + Arrays.asList( + "case", + "do", + "done", + "elif", + "else", + "esac", + "fi", + "for", + "function", + "if", + "in", + "select", + "then", + "time", + "until", + "while") + ); + + typeMapping.clear(); + typeMapping.put("array", "array"); + typeMapping.put("map", "map"); + typeMapping.put("List", "array"); + typeMapping.put("boolean", "boolean"); + typeMapping.put("string", "string"); + typeMapping.put("int", "integer"); + typeMapping.put("float", "float"); + typeMapping.put("number", "integer"); + typeMapping.put("DateTime", "string"); + typeMapping.put("long", "integer"); + typeMapping.put("short", "integer"); + typeMapping.put("char", "string"); + typeMapping.put("double", "float"); + typeMapping.put("object", "map"); + typeMapping.put("integer", "integer"); + typeMapping.put("ByteArray", "string"); + typeMapping.put("binary", "binary"); + + /** + * Additional Properties. These values can be passed to the templates and + * are available in models, apis, and supporting files. + */ + additionalProperties.put("apiVersion", apiVersion); + + /** + * Language Specific Primitives. These types will not trigger imports by + * the client generator + */ + languageSpecificPrimitives = new HashSet(); + } + + + @Override + public void processOpts() { + super.processOpts(); + String curlopts = ""; + + if (additionalProperties.containsKey(CURL_OPTIONS)) { + setCurlOptions(additionalProperties.get(CURL_OPTIONS).toString()); + additionalProperties.put("x-codegen-curl-options", curlopts); + } + + if (additionalProperties.containsKey(PROCESS_MARKDOWN)) { + setProcessMarkdown( + Boolean.parseBoolean( + additionalProperties.get(PROCESS_MARKDOWN).toString())); + } + + if (additionalProperties.containsKey(GENERATE_BASH_COMPLETION)) { + setGenerateBashCompletion( + Boolean.parseBoolean( + additionalProperties.get(GENERATE_BASH_COMPLETION).toString())); + } + + if (additionalProperties.containsKey(GENERATE_ZSH_COMPLETION)) { + setGenerateZshCompletion( + Boolean.parseBoolean( + additionalProperties.get(GENERATE_ZSH_COMPLETION).toString())); + } + + if (additionalProperties.containsKey(SCRIPT_NAME)) { + setScriptName(additionalProperties.get(SCRIPT_NAME).toString()); + } + additionalProperties.put("x-codegen-script-name", scriptName); + + if (additionalProperties.containsKey(HOST_ENVIRONMENT_VARIABLE_NAME)) { + setHostEnvironmentVariable( + additionalProperties.get(HOST_ENVIRONMENT_VARIABLE_NAME).toString()); + additionalProperties.put("x-codegen-host-env", hostEnvironmentVariable); + } + + if (additionalProperties.containsKey(BASIC_AUTH_ENVIRONMENT_VARIABLE_NAME)) { + setBasicAuthEnvironmentVariable( + additionalProperties.get(BASIC_AUTH_ENVIRONMENT_VARIABLE_NAME).toString()); + additionalProperties.put("x-codegen-basicauth-env", basicAuthEnvironmentVariable); + } + + if (additionalProperties.containsKey(APIKEY_AUTH_ENVIRONMENT_VARIABLE_NAME)) { + setApiKeyAuthEnvironmentVariable( + additionalProperties.get(APIKEY_AUTH_ENVIRONMENT_VARIABLE_NAME).toString()); + additionalProperties.put("x-codegen-apikey-env", apiKeyAuthEnvironmentVariable); + } + + supportingFiles.add(new SupportingFile( + "client.mustache", "", scriptName)); + supportingFiles.add(new SupportingFile( + "bash-completion.mustache", "", scriptName+".bash-completion")); + supportingFiles.add(new SupportingFile( + "zsh-completion.mustache", "", "_"+scriptName)); + supportingFiles.add(new SupportingFile( + "README.mustache", "", "README.md")); + } + + public void setCurlOptions(String curlOptions) { + this.curlOptions = curlOptions; + } + + public void setProcessMarkdown(boolean processMarkdown) { + this.processMarkdown = processMarkdown; + } + + public void setScriptName(String scriptName) { + this.scriptName = scriptName; + } + + public void setGenerateBashCompletion(boolean generateBashCompletion) { + this.generateBashCompletion = generateBashCompletion; + } + + public void setGenerateZshCompletion(boolean generateZshCompletion) { + this.generateZshCompletion = generateZshCompletion; + } + + public void setHostEnvironmentVariable(String hostEnvironmentVariable) { + this.hostEnvironmentVariable = hostEnvironmentVariable; + } + + public void setBasicAuthEnvironmentVariable(String + basicAuthEnvironmentVariable) { + this.basicAuthEnvironmentVariable = basicAuthEnvironmentVariable; + } + + public void setApiKeyAuthEnvironmentVariable(String + apiKeyAuthEnvironmentVariable) { + this.apiKeyAuthEnvironmentVariable = apiKeyAuthEnvironmentVariable; + } + + + /** + * Escapes a reserved word as defined in the `reservedWords` array. Handle + * escaping those terms here. This logic is only called if a variable + * matches the reseved words. + * + * @return the escaped term + */ + @Override + public String escapeReservedWord(String name) { + return "_" + name; // add an underscore to the name + } + + /** + * Location to write model files. You can use the modelPackage() as defined + * when the class is instantiated. + */ + public String modelFileFolder() { + return outputFolder; + } + + /** + * Location to write api files. You can use the apiPackage() as defined when + * the class is instantiated. + */ + @Override + public String apiFileFolder() { + return outputFolder; + } + + + /** + * Optional - type declaration. This is a String which is used by the + * templates to instantiate your types. There is typically special handling + * for different property types + * + * @return a string value used as the `dataType` field for model templates, + * `returnType` for api templates + */ + @Override + public String getTypeDeclaration(Property p) { + if(p instanceof ArrayProperty) { + ArrayProperty ap = (ArrayProperty) p; + Property inner = ap.getItems(); + return getSwaggerType(p) + "[" + getTypeDeclaration(inner) + "]"; + } + else if (p instanceof MapProperty) { + MapProperty mp = (MapProperty) p; + Property inner = mp.getAdditionalProperties(); + return getSwaggerType(p) + "[String, " + getTypeDeclaration(inner) + "]"; + } + return super.getTypeDeclaration(p); + } + + /** + * Optional - swagger type conversion. This is used to map swagger types in + * a `Property` into either language specific types via `typeMapping` or into + * complex models if there is not a mapping. + * + * @return a string value of the type or complex model for this property + * @see io.swagger.models.properties.Property + */ + @Override + public String getSwaggerType(Property p) { + String swaggerType = super.getSwaggerType(p); + String type = null; + if(typeMapping.containsKey(swaggerType)) { + type = typeMapping.get(swaggerType); + if(languageSpecificPrimitives.contains(type)) + return type; + } + else + type = swaggerType; + return toModelName(type); + } + + + /** + * Convert Swagger Parameter object to Codegen Parameter object + * + * @param param Swagger parameter object + * @param imports set of imports for library/package/module + * @return Codegen Parameter object + */ + @Override + public CodegenParameter fromParameter(Parameter param, Set imports) { + + CodegenParameter p = super.fromParameter(param, imports); + + if(param instanceof BodyParameter) { + + Model model = ((BodyParameter)param).getSchema(); + + } + else if(param instanceof SerializableParameter) { + + /** + * Currently it's not possible to specify in the codegen other collection + * formats than 'multi' + */ + SerializableParameter sparam = (SerializableParameter)param; + + if( sparam.getCollectionFormat() != null + && !sparam.getCollectionFormat().isEmpty()) { + + String collectionFormat = sparam.getCollectionFormat(); + + if(sparam.isExclusiveMaximum()!=null && sparam.isExclusiveMaximum()) { + p.vendorExtensions.put("x-codegen-collection-max-items", + sparam.getMaxItems()); + } + + if(sparam.isExclusiveMinimum()!=null && sparam.isExclusiveMinimum()) { + p.vendorExtensions.put("x-codegen-collection-min-items", + sparam.getMinItems()); + } + + if( (collectionFormat.equals("multi")) + && (param.getIn().equals("query")) ) { + + /** + * 'multi' is only supported for query parameters + */ + p.vendorExtensions.put("x-codegen-collection-multi", true); + + } + else if(collectionFormat.equals("csv")) { + p.vendorExtensions.put("x-codegen-collection-csv", true); + } + else if(collectionFormat.equals("ssv")) { + p.vendorExtensions.put("x-codegen-collection-ssv", true); + } + else if(collectionFormat.equals("tsv")) { + p.vendorExtensions.put("x-codegen-collection-tsv", true); + } + else if(collectionFormat.equals("pipes")) { + p.vendorExtensions.put("x-codegen-collection-pipes", true); + } + else { + /** Unsupported collection format */ + } + + } + + } + + return p; + + } + + /** + * Override with any special text escaping logic + */ + @SuppressWarnings("static-method") + public String escapeText(String input) { + if (input == null) { + return input; + } + + /** + * remove standalone '\' + * + * replace " with \" + * outter unescape to retain the original multi-byte characters + */ + String result = escapeUnsafeCharacters( + StringEscapeUtils.unescapeJava( + StringEscapeUtils.escapeJava(input).replace("\\/", "/")) + .replace("\\", "\\\\") + .replace("\"", "\\\"")); + + if(this.processMarkdown) { + + /** + * Convert markdown strong **Bold text** and __Bold text__ + * to bash bold control sequences (tput bold) + */ + result = result.replaceAll("(?m)(^|\\s)\\*{2}([\\w\\d ]+)\\*{2}($|\\s)", + "\\$\\(tput bold\\) $2 \\$\\(tput sgr0\\)"); + + result = result.replaceAll("(?m)(^|\\s)_{2}([\\w\\d ]+)_{2}($|\\s)", + "\\$\\(tput bold\\) $2 \\$\\(tput sgr0\\)"); + /** + * Convert markdown *Italics text* and _Italics text_ to bash dim + * control sequences (tput dim) + */ + result = result.replaceAll("(?m)(^|\\s)\\*{1}([\\w\\d ]+)\\*{1}($|\\s)", + "\\$\\(tput dim\\) $2 \\$\\(tput sgr0\\)"); + + result = result.replaceAll("(?m)(^|\\s)_{1}([\\w\\d ]+)_{1}($|\\s)", + "\\$\\(tput dim\\) $2 \\$\\(tput sgr0\\)"); + + + /** + * Convert all markdown section 1 level headers with bold + */ + result = result.replaceAll("(?m)^\\#\\s+(.+)$", + "\n\\$\\(tput bold\\)\\$\\(tput setaf 7\\)" + +"$1\\$\\(tput sgr0\\)"); + + /** + * Convert all markdown section 2 level headers with bold + */ + result = result.replaceAll("(?m)^\\#\\#\\s+(.+)$", + "\n\\$\\(tput bold\\)\\$\\(tput setaf 7\\)" + +"$1\\$\\(tput sgr0\\)"); + + /** + * Convert all markdown section 3 level headers with bold + */ + result = result.replaceAll("(?m)^\\#\\#\\#\\s+(.+)$", + "\n\\$\\(tput bold\\)\\$\\(tput setaf 7\\)" + +"$1\\$\\(tput sgr0\\)"); + + /** + * Convert all markdown code blocks into --- delimited sections + */ + result = result.replaceAll("(?m)\\s*```.*$", + "\n---"); + + result = result.replaceAll("(?m)\\s*\\'\\'\\'.*$", + "\n---"); + + /** + * Remove any trailing new line at the end of the string + */ + result = result.replaceAll("\\s+$", ""); + } + + return result; + } + + @Override + public String escapeQuotationMark(String input) { + return input; + } + + /** + * Override with any special text escaping logic to handle unsafe + * characters so as to avoid code injection. + * + * @param input String to be cleaned up + * @return string with unsafe characters removed or escaped + */ + public String escapeUnsafeCharacters(String input) { + + /** + * Replace backticks with normal single quotes. + */ + String result = input.replaceAll("`", "'"); + + return result; + } + + + @Override + public CodegenOperation fromOperation(String path, String httpMethod, + Operation operation, + Map definitions, + Swagger swagger) { + + CodegenOperation op = super.fromOperation(path, httpMethod, operation, + definitions, swagger); + + /** + * Check if the operation has a Bash codegen specific description + * for help + */ + if(op.vendorExtensions.containsKey("x-bash-codegen-description")) { + String bash_description + = (String)op.vendorExtensions.get("x-bash-codegen-description"); + + op.vendorExtensions.put("x-bash-codegen-description", + escapeText(bash_description)); + } + + /** + * Check if operation has an 'x-code-samples' vendor extension with + * Shell example + */ + if(op.vendorExtensions.containsKey("x-code-samples")) { + + List codesamples = (List)op.vendorExtensions.get("x-code-samples"); + + for (Object codesample : codesamples) { + ObjectNode codesample_object = (ObjectNode)codesample; + + if((codesample_object.get("lang").asText()).equals("Shell")) { + + op.vendorExtensions.put("x-bash-codegen-sample", + escapeUnsafeCharacters( + codesample_object.get("source").asText())); + + } + + } + } + + for (CodegenParameter p : op.bodyParams) { + if(p.dataType != null && definitions.get(p.dataType) != null) { + /** + * If the operation produces Json and has nonempty example + * try to reformat it. + */ + if(operation.getConsumes() != null + && operation.getConsumes().contains("application/json") + && definitions.get(p.dataType).getExample() != null) { + + ObjectMapper mapper = new ObjectMapper(); + try { + p.vendorExtensions.put( + "x-codegen-body-example", + mapper.writerWithDefaultPrettyPrinter().writeValueAsString( + definitions.get(p.dataType).getExample())); + } + catch(JsonProcessingException e) { + e.printStackTrace(); + } + } + else { + /** + * Otherwise present whatever is provided as example + */ + p.vendorExtensions.put( + "x-codegen-body-example", + definitions.get(p.dataType).getExample()); + } + } + } + + return op; + + } + + /** + * Preprocess original properties from the Swagger definition where necessary. + * + * @param swagger [description] + */ + @Override + public void preprocessSwagger(Swagger swagger) { + super.preprocessSwagger(swagger); + + if ("/".equals(swagger.getBasePath())) { + swagger.setBasePath(""); + } + + if(swagger.getInfo() != null + && swagger.getInfo().getVendorExtensions()!=null) { + String bash_codegen_app_description + = (String)swagger.getInfo().getVendorExtensions() + .get("x-bash-codegen-description"); + + if(bash_codegen_app_description != null) { + + bash_codegen_app_description + = escapeText(bash_codegen_app_description); + + additionalProperties.put("x-bash-codegen-app-description", + bash_codegen_app_description); + + } + } + + } + +} diff --git a/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig b/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig index 02f5ce9c05d..9b36d8c527a 100644 --- a/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig +++ b/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig @@ -2,6 +2,7 @@ io.swagger.codegen.languages.AndroidClientCodegen io.swagger.codegen.languages.AspNet5ServerCodegen io.swagger.codegen.languages.AspNetCoreServerCodegen io.swagger.codegen.languages.AsyncScalaClientCodegen +io.swagger.codegen.languages.BashClientCodegen io.swagger.codegen.languages.ConfluenceWikiGenerator io.swagger.codegen.languages.CSharpClientCodegen io.swagger.codegen.languages.CppRestClientCodegen diff --git a/modules/swagger-codegen/src/main/resources/bash/README.md b/modules/swagger-codegen/src/main/resources/bash/README.md new file mode 100644 index 00000000000..9528032e8fa --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/bash/README.md @@ -0,0 +1,220 @@ +# Bash script generator for Swagger Codegen + +## Overview +This is a Bash client script codegen. + +The codegen creates a standalone, single-file Bash script client to quickly test and access Swagger annotated REST services. The generated script uses underneath [cURL](https://curl.haxx.se) to make actual REST calls. + +The generated Bash script has only 2 dependencies: +- Bash (>= 4.3) +- cURL + +## Features +- Fully automatic generation of a client Bash script to access any Swagger-defined REST service +- Generation of Bash and Zsh completion scripts +- All valid cURL options can be passed directly +- Preview of cURL commands to execute each operation using `--dry-run` option +- Complete help for entire service as well as for each operation +- No external dependencies besides Bash and cURL + +## Usage + +### Generating Bash client for REST service + +Get the sources: +```shell +$ git clone https://github.com/swagger-api/swagger-codegen +``` + +Build the codegen: +```shell +$ mvn assembly:assembly -DdescriptorId=jar-with-dependencies +``` + +Define custom codegen properties in a Json file, e.g.: +```shell +{ + "processMarkdown": true, + "curlOptions": "-sS --tlsv1.2", + "scriptName": "petstore-cli", + "generateBashCompletion": true, + "generateZshCompletion": true, + "hostEnvironmentVariable": "PETSTORE_HOST", + "basicAuthEnvironmentVariable": "PETSTORE_BASIC_AUTH", + "apiKeyAuthEnvironmentVariable": "PETSTORE_API_KEY" +} +``` + +Generate the client: +```shell +$ java -cp target/bash-swagger-codegen-1.0.0.jar io.swagger.codegen.SwaggerCodegen generate -l bash -i http://petstore.swagger.io/v2/swagger.json -o output -c resources/example-config.json + +$ chmod +x output/petstore-cli +``` + +Enjoy: +```shell +$ output/petstore-cli -h + +Swagger Petstore command line client (API version 1.0.0) + +Usage + + petstore-cli [-h|--help] [-V|--version] [--about] [] + [-ac|--accept ] [-ct,--content-type ] + [--host ] [--dry-run] [-h|--help] [] + [] [] + + - - endpoint of the REST service without basepath + Can also be specified in PETSTORE_HOST environment variable. + - - any valid cURL options can be passed before + - - either full mime-type or one of supported abbreviations: + (text, html, md, csv, css, rtf, json, xml, yaml, js, bin, + rdf, jpg, png, gif, bmp, tiff) + - - HTTP headers can be passed in the form HEADER:VALUE + - - REST operation parameters can be passed in the following + forms: + * KEY=VALUE - path or query parameters + - - simple JSON body content (first level only) can be build + using the following arguments: + * KEY==VALUE - body parameters which will be added to body + JSON as '{ ..., "KEY": "VALUE", ... }' + * KEY:=VALUE - body parameters which will be added to body + JSON as '{ ..., "KEY": VALUE, ... }' + +Authentication methods + + - Api-key - add 'api_key:' after + or export PETSTORE_API_KEY='' + - OAuth2 (flow: implicit) + Authorization URL: + * http://petstore.swagger.io/oauth/dialog + Scopes: + * write:pets - modify pets in your account + * read:pets - read your pets + +Operations (grouped by tags) + +[pet] + addPet Add a new pet to the store + deletePet Deletes a pet + findPetsByStatus Finds Pets by status + findPetsByTags Finds Pets by tags + getPetById Find pet by ID + updatePet Update an existing pet + updatePetWithForm Updates a pet in the store with form data + uploadFile uploads an image + +[store] + deleteOrder Delete purchase order by ID + getInventory Returns pet inventories by status + getOrderById Find purchase order by ID + placeOrder Place an order for a pet + +[user] + createUser Create user + createUsersWithArrayInput Creates list of users with given input array + createUsersWithListInput Creates list of users with given input array + deleteUser Delete user + getUserByName Get user by user name + loginUser Logs user into the system + logoutUser Logs out current logged in user session + updateUser Updated user + +Options + -h,--help Print this help + -V,--version Print API version + --about Print the information about service + --host Specify the host URL + (e.g. 'https://petstore.swagger.io') + --force Force command invocation in spite of missing + required parameters or wrong content type + --dry-run Print out the cURL command without + executing it + -ac,--accept Set the 'Accept' header in the request + -ct,--content-type Set the 'Content-type' header in + the request +``` + +Client generator takes several specific configuration options: +* *processMarkdown* - [boolean] if set to `true`, all text (descriptions) in the Swagger specification will be treated as Markdown and converted to terminal formatting commands, +* *curlOptions* - [string] a list of default cURL options that will be added to each command +* *scriptName* - [string] the name of the target script, necessary when building Bash completion script +* *generateBashCompletion* - [boolean] if set to `true` the Bash completion script will be generated +* *generateZshCompletion* - [boolean] if set to `true` the Bash completion script will be generated +* *hostEnvironmentVariable* - [string] the name of environment variable to search for default host +* *basicAuthEnvironmentVariable* - [string] the name of environment variable to search for default basic auth credentials +* *apiKeyAuthEnvironmentVariable* - [string] the name of environment variable to search for default api key + +These options can be specified in a Json file used when running the codegen using option `-c` (see [example](resources/example-config.json)). + +### Using the generated Bash script + +```shell +# Print the list of operations available on the service +$ petstore-cli --help + +# Print the service description +$ petstore-cli --about + +# Print detailed information about specific operation +$ petstore-cli addPet --help + +# Call REST API operation +$ echo '{"id":891,"name":"lucky","status":"available"}' | petstore-cli --host http://petstore.swagger.io --content-type json addPet - + +{"id":891,"name":"lucky","photoUrls":[],"tags":[],"status":"available"} + +# The above is equivalent to +$ petstore-cli --host http://petstore.swagger.io --content-type json --accept xml addPet id:=891 name==lucky status==available + +891luckyavailable + + +# Preview the cURL command without actually executing it +# The above is equivalent to +$ petstore-cli --host http://petstore.swagger.io --content-type json --dry-run addPet id:=891 name==lucky status==available + +curl -sS --tlsv1.2 -H 'Content-type: application/json' -X POST -d '{"name": "lucky", "status": "available", "id": 891}' "http://petstore.swagger.io/v2/pet" +``` + +## Shell completion + +### Bash +The generated bash-completion script can be either directly loaded to the current Bash session using: + +```shell +source output/petstore-cli.bash-completion +``` + +Alternatively, the script can be copied to the `/etc/bash-completion.d` (or on OSX with Homebrew to `/usr/local/etc/bash-completion.d`): + +```shell +sudo cp output/petstore-cli.bash-completion /etc/bash-completion.d/petstore-cli +``` + +#### OS X +On OSX you might need to install bash-completion using Homebrew: +```shell +brew install bash-completion +``` +and add the following to the `~/.bashrc`: + +```shell +if [ -f $(brew --prefix)/etc/bash_completion ]; then + . $(brew --prefix)/etc/bash_completion +fi +``` + +### Zsh +In Zsh, the generated `_{{scriptName}}` file (e.g. _petstore-cli) must be copied to one of the folders under `$fpath` variable. + + +## TODO +- [ ] Add enum values for parameters shell completion +- [ ] Wrap handling of errors returned by the service, using comments defined in the Swagger specification +- [ ] Improve `--help` and `--about` formatting +- [ ] Add support to bash 4.0-4.2 (currently must be >= 4.3) +- [ ] Add manpage generation +- [ ] Add support for form data +- [ ] Move todos to Github issues diff --git a/modules/swagger-codegen/src/main/resources/bash/README.mustache b/modules/swagger-codegen/src/main/resources/bash/README.mustache new file mode 100644 index 00000000000..d60bb0f201d --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/bash/README.mustache @@ -0,0 +1,75 @@ +# {{appName}} Bash client + +## Overview +This is a Bash client script for accessing {{appName}} service. + +The script uses cURL underneath for making all REST calls. + +## Usage + +```shell +# Make sure the script has executable rights +$ chmod u+x {{scriptName}} + +# Print the list of operations available on the service +$ ./{{scriptName}} -h + +# Print the service description +$ ./{{scriptName}} --about + +# Print detailed information about specific operation +$ ./{{scriptName}} -h + +# Make GET request +./{{scriptName}} --host http://: --accept xml = : + +# Make GET request using arbitrary curl options (must be passed before ) to an SSL service using username:password +{{scriptName}} -k -sS --tlsv1.2 --host https:// -u : --accept xml = : + +# Make POST request +$ echo '' | {{scriptName}} --host --content-type json - + +# Make POST request with simple JSON content, e.g.: +# { +# "key1": "value1", +# "key2": "value2", +# "key3": 23 +# } +$ echo '' | {{scriptName}} --host --content-type json key1==value1 key2=value2 key3:=23 - + +# Preview the cURL command without actually executing it +$ {{scriptName}} --host http://: --dry-run + +``` + +## Shell completion + +### Bash +The generated bash-completion script can be either directly loaded to the current Bash session using: + +```shell +source {{scriptName}}.bash-completion +``` + +Alternatively, the script can be copied to the `/etc/bash-completion.d` (or on OSX with Homebrew to `/usr/local/etc/bash-completion.d`): + +```shell +sudo cp {{scriptName}}.bash-completion /etc/bash-completion.d/{{scriptName}} +``` + +#### OS X +On OSX you might need to install bash-completion using Homebrew: +```shell +brew install bash-completion +``` +and add the following to the `~/.bashrc`: + +```shell +if [ -f $(brew --prefix)/etc/bash_completion ]; then + . $(brew --prefix)/etc/bash_completion +fi +``` + +### Zsh +In Zsh, the generated `_{{scriptName}}` Zsh completion file must be copied to one of the folders under `$FPATH` variable. + diff --git a/modules/swagger-codegen/src/main/resources/bash/bash-completion.mustache b/modules/swagger-codegen/src/main/resources/bash/bash-completion.mustache new file mode 100644 index 00000000000..c184a82456d --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/bash/bash-completion.mustache @@ -0,0 +1,286 @@ +# {{scriptName}} completion -*- shell-script -*- + +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# ! +# ! Note: +# ! +# ! THIS SCRIPT HAS BEEN AUTOMATICALLY GENERATED USING +# ! swagger-codegen (https://github.com/swagger-api/swagger-codegen) +# ! FROM SWAGGER SPECIFICATION IN JSON. +# ! +# ! Generated on: {{generatedDate}} +# ! +# ! +# ! System wide installation: +# ! +# ! $ sudo cp {{scriptName}}.bash-completion /etc/bash-completion.d/{{scriptName}} +# ! +# ! +# ! User home installation (add this line to .bash_profile): +# ! +# ! [ -r ~/{{scriptName}}.bash-completion ] && source ~/{{scriptName}}.bash-completion +# ! +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +declare -A mime_type_abbreviations +# text/* +mime_type_abbreviations["text"]="text/plain" +mime_type_abbreviations["html"]="text/html" +mime_type_abbreviations["md"]="text/x-markdown" +mime_type_abbreviations["csv"]="text/csv" +mime_type_abbreviations["css"]="text/css" +mime_type_abbreviations["rtf"]="text/rtf" +# application/* +mime_type_abbreviations["json"]="application/json" +mime_type_abbreviations["xml"]="application/xml" +mime_type_abbreviations["yaml"]="application/yaml" +mime_type_abbreviations["js"]="application/javascript" +mime_type_abbreviations["bin"]="application/octet-stream" +mime_type_abbreviations["rdf"]="application/rdf+xml" +# image/* +mime_type_abbreviations["jpg"]="image/jpeg" +mime_type_abbreviations["png"]="image/png" +mime_type_abbreviations["gif"]="image/gif" +mime_type_abbreviations["bmp"]="image/bmp" +mime_type_abbreviations["tiff"]="image/tiff" + + + +__osx_init_completion() +{ + COMPREPLY=() + _get_comp_words_by_ref cur prev words cword +} + + +_{{scriptName}}() +{ + local cur + local prev + local words + local cword + + #words="${COMP_WORDS}" + #cword="${COMP_CWORD}" + #prev="${COMP_WORDS[COMP_CWORD-1]}" + #cur="${COMP_WORDS[COMP_CWORD]}" + + # The reference of currently selected REST operation + local operation="" + + # The list of available operation in the REST service + # It's modelled as an associative array for efficient key lookup + declare -A operations +{{#apiInfo}} +{{#apis}} +{{#operations}} +{{#operation}} + operations["{{operationId}}"]=1 +{{/operation}} +{{/operations}} +{{/apis}} +{{/apiInfo}} + + # An associative array of operations to their parameters + # Only include path, query and header parameters + declare -A operation_parameters +{{#apiInfo}} +{{#apis}} +{{#operations}} +{{#operation}} + operation_parameters["{{operationId}}"]="{{#pathParams}}{{baseName}}= {{/pathParams}}{{#queryParams}}{{baseName}}= {{/queryParams}}{{#headerParams}}{{baseName}}: {{/headerParams}}" +{{/operation}} +{{/operations}} +{{/apis}} +{{/apiInfo}} + + # An associative array of possible values for enum parameters + declare -A operation_parameters_enum_values +{{#apiInfo}} +{{#apis}} +{{#operations}} +{{#operation}} +{{#allParams}} +{{#pathParams}} +{{#isBoolean}} + operation_parameters_enum_values["{{operationId}}::{{baseName}}"]="true false" +{{/isBoolean}} +{{#isEnum}} + operation_parameters_enum_values["{{operationId}}::{{baseName}}"]="" +{{/isEnum}} +{{/pathParams}} +{{#queryParams}} +{{#isBoolean}} + operation_parameters_enum_values["{{operationId}}::{{baseName}}"]="true false" +{{/isBoolean}} +{{/queryParams}} +{{#headerParams}} +{{#isBoolean}} + operation_parameters_enum_values["{{operationId}}::{{baseName}}"]="true false" +{{/isBoolean}} +{{/headerParams}} +{{/allParams}} +{{/operation}} +{{/operations}} +{{/apis}} +{{/apiInfo}} + + # + # Check if the _init_completion function is available, which is + # available since bash-completion 1.4 + # + if declare -F _init_completions >/dev/null 2>&1; then + _init_completion -s || return + else + __osx_init_completion || return + fi + + + # Check if operation is already in the command line provided + for word in "${words[@]}"; do + if [[ -n $word && ${operations[$word]} ]]; then + operation="${word}" + fi + done + + if [[ -z $operation ]]; then + case $prev in + --ciphers|--connect-timeout|-C|--continue-at|-F|--form|--form-string|\ + --ftp-account|--ftp-alternative-to-user|-P|--ftp-port|-H|--header|-h|\ + --help|--hostpubmd5|--keepalive-time|--krb|--limit-rate|--local-port|\ + --mail-from|--mail-rcpt|--max-filesize|--max-redirs|-m|--max-time|\ + --pass|--proto|--proto-redir|--proxy-user|--proxy1.0|-Q|--quote|-r|\ + --range|-X|--request|--retry|--retry-delay|--retry-max-time|\ + --socks5-gssapi-service|-t|--telnet-option|--tftp-blksize|-z|\ + --time-cond|--url|-u|--user|-A|--user-agent|-V|--version|-w|\ + --write-out|--resolve|--tlsuser|--tlspassword|--about) + return + ;; + -K|--config|-b|--cookie|-c|--cookie-jar|-D|--dump-header|--egd-file|\ + --key|--libcurl|-o|--output|--random-file|-T|--upload-file|--trace|\ + --trace-ascii|--netrc-file) + _filedir + return + ;; + --cacert|-E|--cert) + _filedir '@(c?(e)rt|cer|pem|der)' + return + ;; + --capath) + _filedir -d + return + ;; + --cert-type|--key-type) + COMPREPLY=( $( compgen -W 'DER PEM ENG' -- "$cur" ) ) + return + ;; + --crlfile) + _filedir crl + return + ;; + -d|--data|--data-ascii|--data-binary|--data-urlencode) + if [[ $cur == \@* ]]; then + cur=${cur:1} + _filedir + COMPREPLY=( "${COMPREPLY[@]/#/@}" ) + fi + return + ;; + --delegation) + COMPREPLY=( $( compgen -W 'none policy always' -- "$cur" ) ) + return + ;; + --engine) + COMPREPLY=( $( compgen -W 'list' -- "$cur" ) ) + return + ;; + --ftp-method) + COMPREPLY=( $( compgen -W 'multicwd nocwd singlecwd' -- "$cur" ) ) + return + ;; + --ftp-ssl-ccc-mode) + COMPREPLY=( $( compgen -W 'active passive' -- "$cur" ) ) + return + ;; + --interface) + _available_interfaces -a + return + ;; + -x|--proxy|--socks4|--socks4a|--socks5|--socks5-hostname) + _known_hosts_real + return + ;; + --pubkey) + _filedir pub + return + ;; + --stderr) + COMPREPLY=( $( compgen -W '-' -- "$cur" ) ) + _filedir + return + ;; + --tlsauthtype) + COMPREPLY=( $( compgen -W 'SRP' -- "$cur" ) ) + return + ;; + --host) + COMPREPLY=( $( compgen -W 'http:// https://' -- "$cur" ) ) + return + ;; + -ct|--content-type|-ac|--accept) + COMPREPLY=( $( compgen -W '${!mime_type_abbreviations[*]}' -- "$cur" ) ) + return + ;; + esac + fi + + # + # Complete the server address based on ~/.ssh/known_hosts + # and ~/.ssh/config + # + # \todo Fix - cur matches only '//' when $prev is ':' + # + if [[ "$cur" == "http://" || "$cur" == "https://" ]]; then + COMPREPLY=() + local comp_ssh_hosts=`cat ~/.ssh/known_hosts | \ + cut -f 1 -d ' ' | \ + sed -e s/,.*//g | \ + grep -v ^# | \ + uniq | \ + grep -v "\[" ; + cat ~/.ssh/config | \ + grep "^Host " | \ + awk '{print $2}'` + COMPREPLY=( $(compgen -W "${comp_ssh_hosts}" -- $cur)) + return + fi + + # + # Complete the {{scriptName}} and cURL's arguments + # + if [[ $cur == -* ]]; then + COMPREPLY=( $( compgen -W '$(_parse_help curl) $(_parse_help $1)' -- "$cur" ) ) + return + fi + + # + # If the argument starts with a letter this could be either an operation + # or an operation parameter + # When $cur is empty, suggest the list of operations by default + # + if [[ $cur =~ ^[A-Za-z_0-9]* ]]; then + # If operation has not been yet selected, suggest the list of operations + # otherwise suggest arguments of this operation as declared in the + # Swagger specification + if [[ -z $operation ]]; then + COMPREPLY=( $(compgen -W '${!operations[*]}' -- ${cur}) ) + else + COMPREPLY=( $(compgen -W '${operation_parameters[$operation]}' -- ${cur}) ) + fi + return + fi + +} && +complete -F _{{scriptName}} {{scriptName}} + +# ex: ts=4 sw=4 et filetype=sh \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/bash/client.mustache b/modules/swagger-codegen/src/main/resources/bash/client.mustache new file mode 100644 index 00000000000..5a11334690d --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/bash/client.mustache @@ -0,0 +1,1106 @@ +#!/usr/bin/env bash + +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# ! +# ! Note: +# ! +# ! THIS SCRIPT HAS BEEN AUTOMATICALLY GENERATED USING +# ! swagger-codegen (https://github.com/swagger-api/swagger-codegen) +# ! FROM SWAGGER SPECIFICATION IN JSON. +# ! +# ! Generated on: {{generatedDate}} +# ! +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +# +# This is a Bash client for {{appName}}. +# +# LICENSE: +# {{licenseUrl}} +# +# CONTACT: +# {{infoEmail}} +# +# MORE INFORMATION: +# {{#externalDocs}}{{url}}{{/externalDocs}} +# + + +############################################################################### +# +# Global variables +# +############################################################################### + +## +# The filename of this script for help messages +script_name=`basename "$0"` + +## +# Map for headers passed after operation as KEY:VALUE +declare -A header_arguments + + +## +# Map for operation parameters passed after operation as PARAMETER=VALUE +# These will be mapped to appropriate path or query parameters +# The values in operation_parameters are arrays, so that multiple values +# can be provided for the same parameter if allowed by API specification +declare -A operation_parameters + +## +# This array stores the minimum number of required occurences for parameter +# 0 - optional +# 1 - required +declare -A operation_parameters_minimum_occurences +{{#apiInfo}} +{{#apis}} +{{#operations}} +{{#operation}} +{{#allParams}} +operation_parameters_minimum_occurences["{{operationId}}:::{{baseName}}"]={{#required}}{{#vendorExtensions}}{{#x-codegen-collection-min-items}}{{x-codegen-collection-min-items}}{{/x-codegen-collection-min-items}}{{^x-codegen-collection-min-items}}1{{/x-codegen-collection-min-items}}{{/vendorExtensions}}{{^vendorExtensions}}1{{/vendorExtensions}}{{/required}}{{^required}}0{{/required}} +{{/allParams}} +{{/operation}} +{{/operations}} +{{/apis}} +{{/apiInfo}} + +## +# This array stores the maximum number of allowed occurences for parameter +# 1 - single value +# 2 - 2 values +# N - N values +# 0 - unlimited +declare -A operation_parameters_maximum_occurences +{{#apiInfo}} +{{#apis}} +{{#operations}} +{{#operation}} +{{#allParams}} +operation_parameters_maximum_occurences["{{operationId}}:::{{baseName}}"]={{#vendorExtensions}}{{#x-codegen-collection-max-items}}{{x-codegen-collection-max-items}}{{/x-codegen-collection-max-items}}{{^x-codegen-collection-max-items}}0{{/x-codegen-collection-max-items}}{{/vendorExtensions}}{{^vendorExtensions}}0{{/vendorExtensions}} +{{/allParams}} +{{/operation}} +{{/operations}} +{{/apis}} +{{/apiInfo}} + +## +# The type of collection for specifying multiple values for parameter: +# - multi, csv, ssv, tsv +declare -A operation_parameters_collection_type +{{#apiInfo}} +{{#apis}} +{{#operations}} +{{#operation}} +{{#allParams}} +operation_parameters_collection_type["{{operationId}}:::{{baseName}}"]={{#isContainer}}{{#vendorExtensions}}{{#x-codegen-collection-multi}}"multi"{{/x-codegen-collection-multi}}{{#x-codegen-collection-csv}}"csv"{{/x-codegen-collection-csv}}{{#x-codegen-collection-tsv}}"tsv"{{/x-codegen-collection-tsv}}{{#x-codegen-collection-ssv}}"ssv"{{/x-codegen-collection-ssv}}{{/vendorExtensions}}{{^vendorExtensions}}""{{/vendorExtensions}}{{/isContainer}}{{^isContainer}}""{{/isContainer}} +{{/allParams}} +{{/operation}} +{{/operations}} +{{/apis}} +{{/apiInfo}} + + +## +# Map for body parameters passed after operation as +# PARAMETER==STRING_VALUE or PARAMETER:=NUMERIC_VALUE +# These will be mapped to top level json keys ( { "PARAMETER": "VALUE" }) +declare -A body_parameters + +## +# These arguments will be directly passed to cURL +curl_arguments="{{x-codegen-curl-options}}" + +## +# The host for making the request +host="{{#x-codegen-host-env}}${{x-codegen-host-env}}{{/x-codegen-host-env}}" + +## +# The user credentials for basic authentication +basic_auth_credential="{{#x-codegen-basicauth-env}}${{x-codegen-basicauth-env}}{{/x-codegen-basicauth-env}}" + +## +# The user API key +apikey_auth_credential="{{#x-codegen-apikey-env}}${{x-codegen-apikey-env}}{{/x-codegen-apikey-env}}" + +## +# If true, the script will only output the actual cURL command that would be +# used +print_curl=false + +## +# The operation ID passed on the command line +operation="" + +## +# The provided Accept header value +header_accept="" + +## +# The provided Content-type header value +header_content_type="" + +## +# If there is any body content on the stdin pass it to the body of the request +body_content_temp_file="" + +## +# If this variable is set to true, the request will be performed even +# if parameters for required query, header or body values are not provided +# (path parameters are still required). +force=false + +## +# Declare some mime types abbreviations for easier content-type and accepts +# headers specification +declare -A mime_type_abbreviations +# text/* +mime_type_abbreviations["text"]="text/plain" +mime_type_abbreviations["html"]="text/html" +mime_type_abbreviations["md"]="text/x-markdown" +mime_type_abbreviations["csv"]="text/csv" +mime_type_abbreviations["css"]="text/css" +mime_type_abbreviations["rtf"]="text/rtf" +# application/* +mime_type_abbreviations["json"]="application/json" +mime_type_abbreviations["xml"]="application/xml" +mime_type_abbreviations["yaml"]="application/yaml" +mime_type_abbreviations["js"]="application/javascript" +mime_type_abbreviations["bin"]="application/octet-stream" +mime_type_abbreviations["rdf"]="application/rdf+xml" +# image/* +mime_type_abbreviations["jpg"]="image/jpeg" +mime_type_abbreviations["png"]="image/png" +mime_type_abbreviations["gif"]="image/gif" +mime_type_abbreviations["bmp"]="image/bmp" +mime_type_abbreviations["tiff"]="image/tiff" + + +############################################################################## +# +# Escape special URL characters +# Based on table at http://www.w3schools.com/tags/ref_urlencode.asp +# +############################################################################## +url_escape() { + local raw_url="$1" + + value=$(sed -e 's/ /%20/g' \ + -e 's/!/%21/g' \ + -e 's/"/%22/g' \ + -e 's/#/%23/g' \ + -e 's/\&/%26/g' \ + -e 's/'\''/%28/g' \ + -e 's/(/%28/g' \ + -e 's/)/%29/g' \ + -e 's/:/%3A/g' \ + -e 's/?/%3F/g' <<<$raw_url); + + echo $value +} + +############################################################################## +# +# Lookup the mime type abbreviation in the mime_type_abbreviations array. +# If not present assume the user provided a valid mime type +# +############################################################################## +lookup_mime_type() { + local mime_type=$1 + + if [[ ${mime_type_abbreviations[$mime_type]} ]]; then + echo ${mime_type_abbreviations[$mime_type]} + else + echo $1 + fi +} + +############################################################################## +# +# Converts an associative array into a list of cURL header +# arguments (-H "KEY: VALUE") +# +############################################################################## +header_arguments_to_curl() { + local headers_curl="" + local api_key_header="" + local api_key_header_in_cli="" +{{#hasAuthMethods}} +{{#authMethods}} +{{#isApiKey}} +{{#isKeyInHeader}} + api_key_header="{{keyParamName}}" +{{/isKeyInHeader}} +{{/isApiKey}} +{{/authMethods}} +{{/hasAuthMethods}} + + for key in "${!header_arguments[@]}"; do + headers_curl+="-H \"${key}: ${header_arguments[${key}]}\" " + if [[ "${key}XX" == "${api_key_header}XX" ]]; then + api_key_header_in_cli="YES" + fi + done +{{#hasAuthMethods}} +{{#authMethods}} +{{#isApiKey}} +{{#isKeyInHeader}} + # + # If the api_key was not provided in the header, try one from the + # environment variable + # + if [[ -z $api_key_header_in_cli && -n $apikey_auth_credential ]]; then + headers_curl+="-H \"${api_key_header}: ${apikey_auth_credential}\"" + fi +{{/isKeyInHeader}} +{{/isApiKey}} +{{/authMethods}} +{{/hasAuthMethods}} + headers_curl+=" " + + echo "${headers_curl}" +} + +############################################################################## +# +# Converts an associative array into a simple JSON with keys as top +# level object attributes +# +# \todo Add convertion of more complex attributes using paths +# +############################################################################## +body_parameters_to_json() { + local body_json="-d '{" + local body_parameter_count=${#body_parameters[@]} + local count=0 + for key in "${!body_parameters[@]}"; do + body_json+="\"${key}\": ${body_parameters[${key}]}" + if [[ $count -lt $body_parameter_count-1 ]]; then + body_json+=", " + fi + count+=1 + done + body_json+="}'" + + if [[ "${#body_parameters[@]}" -eq 0 ]]; then + echo "" + else + echo "${body_json}" + fi +} + +############################################################################## +# +# Check if provided parameters match specification requirements +# +############################################################################## +validate_request_parameters() { + local path_template=$1 + local -n path_params=$2 + local -n query_params=$3 + + # First replace all path parameters in the path + for pparam in "${path_params[@]}"; do + regexp="(.*)(\{$pparam\})(.*)" + if [[ $path_template =~ $regexp ]]; then + path_template=${BASH_REMATCH[1]}${operation_parameters[$pparam]}${BASH_REMATCH[3]} + fi + done + + # Now append query parameters - if any + if [[ ${#query_params[@]} -gt 0 ]]; then + path_template+="?" + fi + + local query_parameter_count=${#query_params[@]} + local count=0 + for qparam in "${query_params[@]}"; do + # Get the array of parameter values + local parameter_values=($(echo "${operation_parameters[$qparam]}" | sed -e 's/'":::"'/\n/g' | while read line; do echo $line | sed 's/[\t ]/'":::"'/g'; done)) + + # + # Check if the number of provided values is not less than minimum + # required + # + if [[ "$force" = false ]]; then + if [[ ${#parameter_values[@]} -lt ${operation_parameters_minimum_occurences["${operation}:::${qparam}"]} ]]; then + echo "Error: Too few values provided for '${qparam}' parameter" + exit 1 + fi + + # + # Check if the number of provided values is not more than maximum + # + if [[ ${operation_parameters_maximum_occurences["${operation}:::${qparam}"]} -gt 0 \ + && ${#parameter_values[@]} -gt ${operation_parameters_maximum_occurences["${operation}:::${qparam}"]} ]]; then + if [[ "$force" = false ]]; then + echo "Error: Too many values provided for '${qparam}' parameter" + exit 1 + fi + fi + fi + + if [[ "${operation_parameters_collection_type[${operation}:::${qparam}]}" == "" ]]; then + local vcount=0 + for qvalue in "${parameter_values[@]}"; do + path_template+="${qparam}=${qvalue}" + + if [[ $vcount -lt ${#parameter_values[@]}-1 ]]; then + path_template+="&" + fi + vcount+=1 + done + elif [[ "${operation_parameters_collection_type["${operation}:::${qparam}"]}" == "multi" ]]; then + local vcount=0 + for qvalue in "${parameter_values[@]}"; do + path_template+="${qparam}=${qvalue}" + + if [[ $vcount -lt ${#parameter_values[@]}-1 ]]; then + path_template+="&" + fi + vcount+=1 + done + elif [[ "${operation_parameters_collection_type["${operation}:::${qparam}"]}" == "csv" ]]; then + path_template+="${qparam}=" + local vcount=0 + for qvalue in "${parameter_values[@]}"; do + path_template+="${qvalue}" + + if [[ $vcount -lt ${#parameter_values[@]}-1 ]]; then + path_template+="," + fi + vcount+=1 + done + elif [[ "${operation_parameters_collection_type["${operation}:::${qparam}"]}" == "ssv" ]]; then + path_template+="${qparam}=" + for qvalue in "${parameter_values[@]}"; do + path_template+="${qvalue}" + + if [[ $vcount -lt ${#parameter_values[@]}-1 ]]; then + path_template+=" " + fi + vcount+=1 + done + elif [[ "${operation_parameters_collection_type["${operation}:::${qparam}"]}" == "tsv" ]]; then + path_template+="${qparam}=" + for qvalue in "${parameter_values[@]}"; do + path_template+="${qvalue}" + + if [[ $vcount -lt ${#parameter_values[@]}-1 ]]; then + path_template+="\t" + fi + vcount+=1 + done + else + echo -e "" + echo -e "Error: Unsupported collection format " + echo -e "" + exit 1 + fi + + + if [[ $count -lt $query_parameter_count-1 ]]; then + path_template+="&" + fi + count+=1 + done + +} + + + +############################################################################## +# +# Build request path including query parameters +# +############################################################################## +build_request_path() { + local path_template=$1 + local -n path_params=$2 + local -n query_params=$3 + + + # First replace all path parameters in the path + for pparam in "${path_params[@]}"; do + regexp="(.*)(\{$pparam\})(.*)" + if [[ $path_template =~ $regexp ]]; then + path_template=${BASH_REMATCH[1]}${operation_parameters[$pparam]}${BASH_REMATCH[3]} + fi + done + + local query_request_part="" + + local query_parameter_count=${#query_params[@]} + local count=0 + for qparam in "${query_params[@]}"; do + # Get the array of parameter values + local parameter_values=($(echo "${operation_parameters[$qparam]}" | sed -e 's/'":::"'/\n/g' | while read line; do echo $line | sed 's/[\t ]/'":::"'/g'; done)) + local parameter_value="" + + # + # Check if the number of provided values is not less than minimum + # required + # + if [[ "$force" = false ]]; then + if [[ ${#parameter_values[@]} -lt ${operation_parameters_minimum_occurences["${operation}:::${qparam}"]} ]]; then + echo "Error: Too few values provided for '${qparam}' parameter" + exit 1 + fi + + # + # Check if the number of provided values is not more than maximum + # + if [[ ${operation_parameters_maximum_occurences["${operation}:::${qparam}"]} -gt 0 \ + && ${#parameter_values[@]} -gt ${operation_parameters_maximum_occurences["${operation}:::${qparam}"]} ]]; then + if [[ "$force" = false ]]; then + echo "Error: Too many values provided for '${qparam}' parameter" + exit 1 + fi + fi + fi + + # + # Append parameters without specific cardinality + # + if [[ "${operation_parameters_collection_type["${operation}:::${qparam}"]}" == "" ]]; then + local vcount=0 + for qvalue in "${parameter_values[@]}"; do + parameter_value+="${qparam}=${qvalue}" + + if [[ $vcount -lt ${#parameter_values[@]}-1 ]]; then + parameter_value+="&" + fi + vcount+=1 + done + # + # Append parameters specified as 'mutli' collections i.e. param=value1¶m=value2&... + # + elif [[ "${operation_parameters_collection_type["${operation}:::${qparam}"]}" == "multi" ]]; then + local vcount=0 + for qvalue in "${parameter_values[@]}"; do + parameter_value+="${qparam}=${qvalue}" + + if [[ $vcount -lt ${#parameter_values[@]}-1 ]]; then + parameter_value+="&" + fi + vcount+=1 + done + # + # Append parameters specified as 'csv' collections i.e. param=value1,value2,... + # + elif [[ "${operation_parameters_collection_type["${operation}:::${qparam}"]}" == "csv" ]]; then + parameter_value+="${qparam}=" + local vcount=0 + for qvalue in "${parameter_values[@]}"; do + parameter_value+="${qvalue}" + + if [[ $vcount -lt ${#parameter_values[@]}-1 ]]; then + parameter_value+="," + fi + vcount+=1 + done + # + # Append parameters specified as 'ssv' collections i.e. param="value1 value2 ..." + # + elif [[ "${operation_parameters_collection_type["${operation}:::${qparam}"]}" == "ssv" ]]; then + parameter_value+="${qparam}=" + local vcount=0 + for qvalue in "${parameter_values[@]}"; do + parameter_value+="${qvalue}" + + if [[ $vcount -lt ${#parameter_values[@]}-1 ]]; then + parameter_value+=" " + fi + vcount+=1 + done + # + # Append parameters specified as 'tsv' collections i.e. param="value1\tvalue2\t..." + # + elif [[ "${operation_parameters_collection_type["${operation}:::${qparam}"]}" == "tsv" ]]; then + parameter_value+="${qparam}=" + local vcount=0 + for qvalue in "${parameter_values[@]}"; do + parameter_value+="${qvalue}" + + if [[ $vcount -lt ${#parameter_values[@]}-1 ]]; then + parameter_value+="\t" + fi + vcount+=1 + done + fi + + if [[ -n "${parameter_value}" ]]; then + query_request_part+="${parameter_value}" + fi + + if [[ $count -lt $query_parameter_count-1 && -n "${parameter_value}" ]]; then + query_request_part+="&" + fi + + count+=1 + + done + + + # Now append query parameters - if any + if [[ -n "${query_request_part}" ]]; then + path_template+="?$(echo ${query_request_part} | sed s'/&$//')" + fi + + echo $path_template +} + + + +############################################################################### +# +# Print main help message +# +############################################################################### +print_help() { +cat <$(tput sgr0)] + [-ac|--accept $(tput setaf 2)$(tput sgr0)] [-ct,--content-type $(tput setaf 2)$(tput sgr0)] + [--host $(tput setaf 6)$(tput sgr0)] [--dry-run] $(tput setaf 3)$(tput sgr0) [-h|--help] [$(tput setaf 4)$(tput sgr0)] + [$(tput setaf 5)$(tput sgr0)] [$(tput setaf 5)$(tput sgr0)] + + - $(tput setaf 6)$(tput sgr0) - endpoint of the REST service without basepath +{{#x-codegen-host-env}} Can also be specified in {{x-codegen-host-env}} environment variable.{{/x-codegen-host-env}} + - $(tput setaf 1)$(tput sgr0) - any valid cURL options can be passed before $(tput setaf 3)$(tput sgr0) + - $(tput setaf 2)$(tput sgr0) - either full mime-type or one of supported abbreviations: + (text, html, md, csv, css, rtf, json, xml, yaml, js, bin, + rdf, jpg, png, gif, bmp, tiff) + - $(tput setaf 4)$(tput sgr0) - HTTP headers can be passed in the form $(tput setaf 3)HEADER$(tput sgr0):$(tput setaf 4)VALUE$(tput sgr0) + - $(tput setaf 5)$(tput sgr0) - REST operation parameters can be passed in the following + forms: + * $(tput setaf 3)KEY$(tput sgr0)=$(tput setaf 4)VALUE$(tput sgr0) - path or query parameters + - $(tput setaf 5)$(tput sgr0) - simple JSON body content (first level only) can be build + using the following arguments: + * $(tput setaf 3)KEY$(tput sgr0)==$(tput setaf 4)VALUE$(tput sgr0) - body parameters which will be added to body + JSON as '{ ..., "$(tput setaf 3)KEY$(tput sgr0)": "$(tput setaf 4)VALUE$(tput sgr0)", ... }' + * $(tput setaf 3)KEY$(tput sgr0):=$(tput setaf 4)VALUE$(tput sgr0) - body parameters which will be added to body + JSON as '{ ..., "$(tput setaf 3)KEY$(tput sgr0)": $(tput setaf 4)VALUE$(tput sgr0), ... }' + +EOF +{{#hasAuthMethods}} + echo -e "$(tput bold)$(tput setaf 7)Authentication methods$(tput sgr0)" + echo -e "" +{{#authMethods}} +{{#isBasic}} + echo -e " - $(tput setaf 4)Basic AUTH$(tput sgr0) - add '-u :' before $(tput setaf 3)$(tput sgr0)" + {{#x-codegen-basicauth-env}}echo -e " or export $(tput setaf 1){{x-codegen-basicauth-env}}=':'$(tput sgr0)"{{/x-codegen-basicauth-env}} +{{/isBasic}} +{{#isApiKey}} +{{#isKeyInHeader}} + echo -e " - $(tput setaf 4)Api-key$(tput sgr0) - add '$(tput setaf 1){{keyParamName}}:$(tput sgr0)' after $(tput setaf 3)$(tput sgr0)" +{{/isKeyInHeader}} +{{#isKeyInQuery}} + echo -e " - $(tput setaf 4)Api-key$(tput sgr0) - add '$(tput setaf 1){{keyParamName}}=$(tput sgr0)' after $(tput setaf 3)$(tput sgr0)" +{{/isKeyInQuery}} + {{#x-codegen-apikey-env}}echo -e " or export $(tput setaf 1){{x-codegen-apikey-env}}=''$(tput sgr0)"{{/x-codegen-apikey-env}} +{{/isApiKey}} +{{#isOAuth}} + echo -e " - $(tput setaf 5)OAuth2 (flow: {{flow}})$(tput sgr0)" + echo -e " Authorization URL: " + echo -e " * {{authorizationUrl}}" + echo -e " Scopes:" +{{#scopes}} + echo -e " * {{scope}} - {{description}}" +{{/scopes}} +{{/isOAuth}} +{{/authMethods}} + echo "" +{{/hasAuthMethods}} + echo -e "$(tput bold)$(tput setaf 7)Operations (grouped by tags)$(tput sgr0)" +{{#apiInfo}} +{{#apis}} + echo "" + echo -e "$(tput bold)$(tput setaf 7)[{{classVarName}}]$(tput sgr0)" +read -d '' ops <$(tput sgr0)\t\t\t\tSpecify the host URL " +{{#swagger}} +{{#host}}echo -e " \t\t\t\t(e.g. 'https://{{host}}')"{{/host}} +{{^host}}echo -e " \t\t\t\t(e.g. 'https://127.0.0.1:8080')"{{/host}} +{{/swagger}} + echo -e " --force\t\t\t\tForce command invocation in spite of missing" + echo -e " \t\t\t\trequired parameters or wrong content type" + echo -e " --dry-run\t\t\t\tPrint out the cURL command without" + echo -e " \t\t\t\texecuting it" + echo -e " -ac,--accept $(tput setaf 3)$(tput sgr0)\t\tSet the 'Accept' header in the request" + echo -e " -ct,--content-type $(tput setaf 3)$(tput sgr0)\tSet the 'Content-type' header in " + echo -e " \tthe request" + echo "" +} + + +############################################################################## +# +# Print REST service description +# +############################################################################## +print_about() { + echo "" + echo -e "$(tput bold)$(tput setaf 7){{appName}} command line client (API version {{#swagger}}{{#info}}{{version}}{{/info}}{{/swagger}})$(tput sgr0)" + echo "" + echo -e "License: {{#swagger}}{{#info}}{{#license}}{{name}}{{/license}}{{/info}}{{/swagger}}" + echo -e "Contact: {{#swagger}}{{#info}}{{#contact}}{{email}}{{/contact}}{{/info}}{{/swagger}}" + echo "" +read -d '' appdescription </dev/null 2>&1 || { echo >&2 "Error: You do not have 'cURL' installed."; exit 1; } +type sed >/dev/null 2>&1 || { echo >&2 "Error: You do not have 'sed' installed."; exit 1; } +type column >/dev/null 2>&1 || { echo >&2 "Error: You do not have 'bsdmainutils' installed."; exit 1; } + +# +# Process command line +# +# Pass all arguemnts before 'operation' to cURL except the ones we override +# +take_user=false +take_host=false +take_accept_header=false +take_contenttype_header=false + +for key in "$@"; do +# Take the value of -u|--user argument +if [[ "$take_user" = true ]]; then + basic_auth_credential="$key" + take_user=false + continue +fi +# Take the value of --host argument +if [[ "$take_host" = true ]]; then + host="$key" + take_host=false + continue +fi +# Take the value of --accept argument +if [[ "$take_accept_header" = true ]]; then + header_accept=$(lookup_mime_type "$key") + take_accept_header=false + continue +fi +# Take the value of --content-type argument +if [[ "$take_contenttype_header" = true ]]; then + header_content_type=$(lookup_mime_type "$key") + take_contenttype_header=false + continue +fi +case $key in + -h|--help) + if [[ "x$operation" == "x" ]]; then + print_help + exit 0 + else + eval "print_${operation}_help" + exit 0 + fi + ;; + -V|--version) + print_version + exit 0 + ;; + --about) + print_about + exit 0 + ;; + -u|--user) + take_user=true + ;; + --host) + take_host=true + ;; + --force) + force=true + ;; + -ac|--accept) + take_accept_header=true + ;; + -ct|--content-type) + take_contenttype_header=true + ;; + --dry-run) + print_curl=true + ;; +{{#apiInfo}} +{{#apis}} +{{#operations}} +{{#operation}} + {{operationId}}) + operation="{{operationId}}" + ;; +{{/operation}} +{{/operations}} +{{/apis}} +{{/apiInfo}} + *==*) + # Parse body arguments and convert them into top level + # JSON properties passed in the body content as strings + if [[ "$operation" ]]; then + IFS='==' read body_key sep body_value <<< "$key" + body_parameters[${body_key}]="\"${body_value}\"" + fi + ;; + *:=*) + # Parse body arguments and convert them into top level + # JSON properties passed in the body content without qoutes + if [[ "$operation" ]]; then + IFS=':=' read body_key sep body_value <<< "$key" + body_parameters[${body_key}]=${body_value} + fi + ;; + *:*) + # Parse header arguments and convert them into curl + # only after the operation argument + if [[ "$operation" ]]; then + IFS=':' read header_name header_value <<< "$key" +{{#hasAuthMethods}} +{{#authMethods}} +{{#isApiKey}} +{{#isKeyInHeader}} + # + # If the header key is the same as the api_key expected by API in the + # header, override the ${apikey_auth_credential} variable + # + if [[ $header_name == "{{keyParamName}}" ]]; then + apikey_auth_credential=$header_value + fi +{{/isKeyInHeader}} +{{/isApiKey}} +{{/authMethods}} +{{/hasAuthMethods}} + header_arguments[$header_name]=$header_value + else + curl_arguments+=" $key" + fi + ;; + -) + body_content_temp_file=$(mktemp) + cat - > $body_content_temp_file + ;; + *=*) + # Parse operation arguments and convert them into curl + # only after the operation argument + if [[ "$operation" ]]; then + IFS='=' read parameter_name parameter_value <<< "$key" + if [[ -z "${operation_parameters[$parameter_name]+foo}" ]]; then + operation_parameters[$parameter_name]=$(url_escape "${parameter_value}") + else + operation_parameters[$parameter_name]+=":::"$(url_escape "${parameter_value}") + fi + else + curl_arguments+=" $key" + fi + ;; + *) + # If we are before the operation, treat the arguments as cURL arguments + if [[ "x$operation" == "x" ]]; then + # Maintain quotes around cURL arguments if necessary + space_regexp="[[:space:]]" + if [[ $key =~ $space_regexp ]]; then + curl_arguments+=" \"$key\"" + else + curl_arguments+=" $key" + fi + fi + ;; +esac +done + + +# Check if user provided host name +if [[ -z "$host" ]]; then + echo "Error: No hostname provided!!!" + echo "Check usage: '${script_name} --help'" + exit 1 +fi + +# Check if user specified operation ID +if [[ -z "$operation" ]]; then + echo "Error: No operation specified!" + echo "Check available operations: '${script_name} --help'" + exit 1 +fi + + +# Run cURL command based on the operation ID +case $operation in +{{#apiInfo}} +{{#apis}} +{{#operations}} +{{#operation}} + {{operationId}}) + call_{{operationId}} + ;; +{{/operation}} +{{/operations}} +{{/apis}} +{{/apiInfo}} + *) + echo "Error: Unknown operation: $operation" + echo "" + print_help + exit 1 +esac + diff --git a/modules/swagger-codegen/src/main/resources/bash/zsh-completion.mustache b/modules/swagger-codegen/src/main/resources/bash/zsh-completion.mustache new file mode 100644 index 00000000000..78caea2bc21 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/bash/zsh-completion.mustache @@ -0,0 +1,301 @@ +#compdef {{scriptName}} + +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# ! +# ! Note: +# ! +# ! THIS SCRIPT HAS BEEN AUTOMATICALLY GENERATED USING +# ! swagger-codegen (https://github.com/swagger-api/swagger-codegen) +# ! FROM SWAGGER SPECIFICATION IN JSON. +# ! +# ! Based on: https://github.com/Valodim/zsh-curl-completion/blob/master/_curl +# ! +# ! Generated on: {{generatedDate}} +# ! +# ! +# ! Installation: +# ! +# ! Copy the _{{scriptName}} file to any directory under FPATH +# ! environment variable (echo $FPATH) +# ! +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + +local curcontext="$curcontext" state line ret=1 +typeset -A opt_args + +# +# cURL crypto engines completion function +# +_curl_crypto_engine() { + local vals + vals=( ${${(f)"$(curl --engine list)":gs/ /}[2,$]} ) + _describe -t outputs 'engines' vals && return 0 +} + +# +# cURL post data completion functions= +# +_curl_post_data() { + + # don't do anything further if this is raw content + compset -P '=' && _message 'raw content' && return 0 + + # complete filename or stdin for @ syntax + compset -P '*@' && { + local expl + _description files expl stdin + compadd "$expl[@]" - "-" + _files + return 0 + } + + # got a name already? expecting data. + compset -P '*=' && _message 'data value' && return 0 + + # otherwise, name (or @ or =) should be specified + _message 'data name' && return 0 + +} + + +local arg_http arg_ftp arg_other arg_proxy arg_crypto arg_connection arg_auth arg_input arg_output + +# HTTP Arguments +arg_http=(''\ + {-0,--http1.0}'[force use of use http 1.0 instead of 1.1]' \ + {-b,--cookie}'[pass data to http server as cookie]:data or file' \ + {-c,--cookie-jar}'[specify cookie file]:file name:_files' \ + {-d,--data}'[send specified data as HTTP POST data]:data:{_curl_post_data}' \ + '--data-binary[post HTTP POST data without any processing]:data:{_curl_post_data}' \ + '--data-urlencode[post HTTP POST data, with url encoding]:data:{_curl_post_data}' \ + {-f,--fail}'[enable failfast behavior for server errors]' \ + '*'{-F,--form}'[add POST form data]:name=content' \ + {-G,--get}'[use HTTP GET even with data (-d, --data, --data-binary)]' \ + '*'{-H,--header}'[specify an extra header]:header' \ + '--ignore-content-length[ignore Content-Length header]' \ + {-i,--include}'[include HTTP header in the output]' \ + {-j,--junk-session-cookies}'[discard all session cookies]' \ + {-e,--referer}'[send url as referer]:referer url:_urls' \ + {-L,--location}'[follow Location headers on http 3XX response]' \ + '--location-trusted[like --location, but allows sending of auth data to redirected hosts]' \ + '--max-redirs[set maximum number of redirection followings allowed]:number' \ + {-J,--remote-header-name}'[use Content-Disposition for output file name]' \ + {-O,--remote-name}'[write to filename parsed from url instead of stdout]' \ + '--post301[do not convert POST to GET after following 301 Location response (follow RFC 2616/10.3.2)]' \ + '--post302[do not convert POST to GET after following 302 Location response (follow RFC 2616/10.3.2)]' \ + ) + +# FTP arguments +arg_ftp=(\ + {-a,--append}'[append to target file instead of overwriting (FTP/SFTP)]' \ + '--crlf[convert LF to CRLF in upload]' \ + '--disable-eprt[disable use of EPRT and LPRT for active FTP transfers]' \ + '--disable-epsv[disable use of EPSV for passive FTP transfers]' \ + '--ftp-account[account data (FTP)]:data' \ + '--ftp-alternative-to-user[command to send when USER and PASS commands fail (FTP)]:command' \ + '--ftp-create-dirs[create paths remotely if it does not exist]' \ + '--ftp-method[ftp method to use to reach a file (FTP)]:method:(multicwd ocwd singlecwd)' \ + '--ftp-pasv[use passive mode for the data connection (FTP)]' \ + '--ftp-skip-pasv-ip[do not use the ip the server suggests for PASV]' \ + '--form-string[like --form, but do not parse content]:name=string' \ + '--ftp-pret[send PRET before PASV]' \ + '--ftp-ssl-ccc[use clear command channel (CCC) after authentication (FTP)]' \ + '--ftp-ssl-ccc-mode[sets the CCC mode (FTP)]:mode:(active passive)' \ + '--ftp-ssl-control[require SSL/TLS for FTP login, clear for transfer]' \ + {-l,--list-only}'[list names only when listing directories (FTP)]' \ + {-P,--ftp-port}'[use active mode, tell server to connect to specified address or interface (FTP]:address' \ + '*'{-Q,--quote}'[send arbitrary command to the remote server before transfer (FTP/SFTP)]:command' \ + ) + +# Other Protocol arguments +arg_other=(\ + '--mail-from[specify From: address]:address' \ + '--mail-rcpt[specify email recipient for SMTP, may be given multiple times]:address' \ + {-t,--telnet-option}'[pass options to telnet protocol]:opt=val' \ + '--tftp-blksize[set tftp BLKSIZE option]:value' \ + ) + +# Proxy arguments +arg_proxy=(\ + '--noproxy[list of hosts to connect directly to instead of through proxy]:no-proxy-list' \ + {-p,--proxytunnel}'[tunnel non-http protocols through http proxy]' \ + {-U,--proxy-user}'[specify the user name and password to use for proxy authentication]:user:password' \ + '--proxy-anyauth[use any authentication method for proxy, default to most secure]' \ + '--proxy-basic[use HTTP Basic authentication for proxy]' \ + '--proxy-digest[use http digest authentication for proxy]' \ + '--proxy-negotiate[enable GSS-Negotiate authentication for proxy]' \ + '--proxy-ntlm[enable ntlm authentication for proxy]' \ + '--proxy1.0[use http 1.0 proxy]:proxy url' \ + {-x,--proxy}'[use specified proxy]:proxy url' \ + '--socks5-gssapi-service[change service name for socks server]:servicename' \ + '--socks5-gssapi-nec[allow unprotected exchange of protection mode negotiation]' \ + ) + +# Crypto arguments +arg_crypto=(\ + {-1,--tlsv1}'[Forces curl to use TLS version 1 when negotiating with a remote TLS server.]' \ + {-2,--sslv2}'[Forces curl to use SSL version 2 when negotiating with a remote SSL server.]' \ + {-3,--sslv3}'[Forces curl to use SSL version 3 when negotiating with a remote SSL server.]' \ + '--ciphers[specifies which cipher to use for the ssl connection]:list of ciphers' \ + '--crlfile[specify file with revoked certificates]:file' \ + '--delegation[set delegation policy to use with GSS/kerberos]:delegation policy:(none policy always)' \ + {-E,--cert}'[use specified client certificate]:certificate file:_files' \ + '--engine[use selected OpenSSL crypto engine]:ssl crypto engine:{_curl_crypto_engine}' \ + '--egd-file[set ssl entropy gathering daemon socket]:entropy socket:_files' \ + '--cert-type[specify certificate type (PEM, DER, ENG)]:certificate type:(PEM DER ENG)' \ + '--cacert[specify certificate file to verify the peer with]:CA certificate:_files' \ + '--capath[specify a search path for certificate files]:CA certificate directory:_directories' \ + '--hostpubmd5[check remote hosts public key]:md5 hash' \ + {-k,--insecure}'[allow ssl to perform insecure ssl connections (ie, ignore certificate)]' \ + '--key[ssl/ssh private key file name]:key file:_files' \ + '--key-type[ssl/ssh private key file type]:file type:(PEM DER ENG)' \ + '--pubkey[ssh public key file]:pubkey file:_files' \ + '--random-file[set source of random data for ssl]:random source:_files' \ + '--no-sessionid[disable caching of ssl session ids]' \ + '--pass:phrase[passphrase for ssl/ssh private key]' \ + '--ssl[try to use ssl/tls for connection, if available]' \ + '--ssl-reqd[try to use ssl/tls for connection, fail if unavailable]' \ + '--tlsauthtype[set TLS authentication type (only SRP supported!)]:authtype' \ + '--tlsuser[set username for TLS authentication]:user' \ + '--tlspassword[set password for TLS authentication]:password' \ + ) + +# Connection arguments +arg_connection=(\ + {-4,--ipv4}'[prefer ipv4]' \ + {-6,--ipv6}'[prefer ipv6, if available]' \ + {-B,--use-ascii}'[use ascii mode]' \ + '--compressed[request a compressed transfer]' \ + '--connect-timeout[timeout for connection phase]:seconds' \ + {-I,--head}'[fetch http HEAD only (HTTP/FTP/FILE]' \ + '--interface[work on a specific interface]:name' \ + '--keepalive-time[set time to wait before sending keepalive probes]:seconds' \ + '--limit-rate[specify maximum transfer rate]:speed' \ + '--local-port[set preferred number or range of local ports to use]:num' \ + {-N,--no-buffer}'[disable buffering of the output stream]' \ + '--no-keepalive[disable use of keepalive messages in TCP connections]' \ + '--raw[disable all http decoding and pass raw data]' \ + '--resolve[provide a custom address for a specific host and port pair]:host\:port\:address' \ + '--retry[specify maximum number of retries for transient errors]:num' \ + '--retry-delay[specify delay between retries]:seconds' \ + '--retry-max-time[maximum time to spend on retries]:seconds' \ + '--tcp-nodelay[turn on TCP_NODELAY option]' \ + {-y,--speed-time}'[specify time to abort after if download is slower than speed-limit]:time' \ + {-Y,--speed-limit}'[specify minimum speed for --speed-time]:speed' \ + ) + +# Authentication arguments +arg_auth=(\ + '--anyauth[use any authentication method, default to most secure]' \ + '--basic[use HTTP Basic authentication]' \ + '--ntlm[enable ntlm authentication]' \ + '--digest[use http digest authentication]' \ + '--krb[use kerberos authentication]:auth:(clear safe confidential private)' \ + '--negotiate[enable GSS-Negotiate authentication]' \ + {-n,--netrc}'[scan ~/.netrc for login data]' \ + '--netrc-optional[like --netrc, but does not make .netrc usage mandatory]' \ + '--netrc-file[like --netrc, but specify file to use]:netrc file:_files' \ + '--tr-encoding[request compressed transfer-encoding]' \ + {-u,--user}'[specify user name and password for server authentication]:user\:password' \ + ) + +# Input arguments +arg_input=(\ + {-C,--continue-at}'[resume at offset ]:offset' \ + {-g,--globoff}'[do not glob {}\[\] letters]' \ + '--max-filesize[maximum filesize to download, fail for bigger files]:bytes' \ + '--proto[specify allowed protocols for transfer]:protocols' \ + '--proto-redir[specify allowed protocols for transfer after a redirect]:protocols' \ + {-r,--range}'[set range of bytes to request (HTTP/FTP/SFTP/FILE)]:range' \ + {-R,--remote-time}'[use timestamp of remote file for local file]' \ + {-T,--upload-file}'[transfer file to remote url (using PUT for HTTP)]:file to upload:_files' \ + '--url[specify a URL to fetch (multi)]:url:_urls' \ + {-z,--time-cond}'[request downloaded file to be newer than date or given reference file]:date expression' \ + ) + +# Output arguments +arg_output=(\ + '--create-dirs[create local directory hierarchy as needed]' \ + {-D,--dump-header}'[write protocol headers to file]:dump file:_files' \ + {-o,--output}'[write to specified file instead of stdout]:output file:_files' \ + {--progress-bar,-\#}'[display progress as a simple progress bar]' \ + {-\#,--progress-bar}'[Make curl display progress as a simple progress bar instead of the standard, more informational, meter.]' \ + {-R,--remote-time}'[use timestamp of remote file for local file]' \ + '--raw[disable all http decoding and pass raw data]' \ + {-s,--silent}'[silent mode, do not show progress meter or error messages]' \ + {-S,--show-error}'[show errors in silent mode]' \ + '--stderr[redirect stderr to specified file]:output file:_files' \ + '--trace[enable full trace dump of all incoming and outgoing data]:trace file:_files' \ + '--trace-ascii[enable full trace dump of all incoming and outgoing data, without hex data]:trace file:_files' \ + '--trace-time[prepends a time stamp to each trace or verbose line that curl displays]' \ + {-v,--verbose}'[output debug info]' \ + {-w,--write-out}'[specify message to output on successful operation]:format string' \ + '--xattr[store some file metadata in extended file attributes]' \ + {-X,--request}'[specifies request method for HTTP server]:method:(GET POST PUT DELETE HEAD OPTIONS TRACE CONNECT PATCH LINK UNLINK)' \ + ) + +_arguments -C -s $arg_http $arg_ftp $arg_other $arg_crypto $arg_connection $arg_auth $arg_input $arg_output \ + {-M,--manual}'[print manual]' \ + '*'{-K,--config}'[use other config file to read arguments from]:config file:_files' \ + '--libcurl[output libcurl code for the operation to file]:output file:_files' \ + {-m,--max-time}'[limit total time of operation]:seconds' \ + {-s,--silent}'[silent mode, do not show progress meter or error messages]' \ + {-S,--show-error}'[show errors in silent mode]' \ + '--stderr[redirect stderr to specified file]:output file:_files' \ + '-q[do not read settings from .curlrc (must be first option)]' \ + {-h,--help}'[Print help and list of operations]' \ + {-V,--version}'[Print service API version]' \ + '--about[Print the information about service]' \ + '--host[Specify the host URL]':URL:_urls \ + '--dry-run[Print out the cURL command without executing it]' \ + {-ac,--accept}'[Set the 'Accept' header in the request]' \ + {-ct,--content-type}'[Set the 'Content-type' header in request]' \ + '1: :->ops' \ + '*:: :->args' \ + && ret=0 + + +case $state in + ops) + # Operations + _values "Operations" \ +{{#apiInfo}} +{{#apis}} +{{#operations}} +{{#operation}} + "{{operationId}}[{{{summary}}}]" {{#hasMore}}\ +{{/hasMore}}{{/operation}}{{/operations}}{{/apis}}{{#hasMore}}\ +{{/hasMore}} +{{/apiInfo}} + + _arguments "(--help)--help[Print information about operation]" + + ret=0 + ;; + args) + case $line[1] in +{{#apiInfo}} +{{#apis}} +{{#operations}} +{{#operation}} + {{operationId}}) + local -a _op_arguments + _op_arguments=( + {{#pathParams}}"{{baseName}}=:{{{description}}}" +{{/pathParams}} {{#queryParams}}{{#isBoolean}}"{{baseName}}=true:{{description}}" + "{{baseName}}=false:{{description}}"{{/isBoolean}}{{^isBoolean}}"{{baseName}}=:{{description}}"{{/isBoolean}} +{{/queryParams}} {{#headerParams}}"{{baseName}}\::{{{description}}}" +{{/headerParams}}) + _describe -t actions 'operations' _op_arguments && ret=0 + ;; +{{/operation}} +{{/operations}} +{{/apis}} +{{/apiInfo}} + esac + ;; + +esac + +return ret \ No newline at end of file diff --git a/modules/swagger-codegen/src/test/java/io/swagger/codegen/bash/BashClientOptionsTest.java b/modules/swagger-codegen/src/test/java/io/swagger/codegen/bash/BashClientOptionsTest.java new file mode 100644 index 00000000000..9a99726dace --- /dev/null +++ b/modules/swagger-codegen/src/test/java/io/swagger/codegen/bash/BashClientOptionsTest.java @@ -0,0 +1,56 @@ +package io.swagger.codegen.bash; + +import io.swagger.codegen.AbstractOptionsTest; +import io.swagger.codegen.CodegenConfig; +import io.swagger.codegen.languages.BashClientCodegen; +import io.swagger.codegen.options.BashClientOptionsProvider; + +import mockit.Expectations; +import mockit.Tested; + +public class BashClientOptionsTest extends AbstractOptionsTest { + + @Tested + private BashClientCodegen clientCodegen; + + public BashClientOptionsTest() { + super(new BashClientOptionsProvider()); + } + + @Override + protected CodegenConfig getCodegenConfig() { + return clientCodegen; + } + + @SuppressWarnings("unused") + @Override + protected void setExpectations() { + new Expectations(clientCodegen) {{ + clientCodegen.setCurlOptions( + BashClientOptionsProvider.CURL_OPTIONS); + times = 1; + clientCodegen.setProcessMarkdown( + Boolean.parseBoolean( + BashClientOptionsProvider.PROCESS_MARKDOWN)); + times = 1; + clientCodegen.setScriptName( + BashClientOptionsProvider.SCRIPT_NAME); + times = 1; + clientCodegen.setGenerateBashCompletion( + Boolean.parseBoolean( + BashClientOptionsProvider.GENERATE_BASH_COMPLETION)); + times = 1; + clientCodegen.setGenerateZshCompletion( + Boolean.parseBoolean( + BashClientOptionsProvider.GENERATE_ZSH_COMPLETION)); + times = 1; + clientCodegen.setHostEnvironmentVariable( + BashClientOptionsProvider.HOST_ENVIRONMENT_VARIABLE_NAME); + times = 1; + clientCodegen.setApiKeyAuthEnvironmentVariable( + BashClientOptionsProvider.APIKEY_AUTH_ENVIRONMENT_VARIABLE_NAME); + times = 1; + }}; + } +} + diff --git a/modules/swagger-codegen/src/test/java/io/swagger/codegen/bash/BashTest.java b/modules/swagger-codegen/src/test/java/io/swagger/codegen/bash/BashTest.java new file mode 100644 index 00000000000..a59b083201a --- /dev/null +++ b/modules/swagger-codegen/src/test/java/io/swagger/codegen/bash/BashTest.java @@ -0,0 +1,158 @@ +package io.swagger.codegen.python; + +import io.swagger.codegen.CodegenModel; +import io.swagger.codegen.CodegenOperation; +import io.swagger.codegen.CodegenProperty; +import io.swagger.codegen.CodegenParameter; +import io.swagger.codegen.DefaultCodegen; +import io.swagger.codegen.languages.BashClientCodegen; +import io.swagger.models.ArrayModel; +import io.swagger.models.Model; +import io.swagger.models.ModelImpl; +import io.swagger.models.Operation; +import io.swagger.models.Swagger; +import io.swagger.models.properties.ArrayProperty; +import io.swagger.models.properties.DateTimeProperty; +import io.swagger.models.properties.LongProperty; +import io.swagger.models.properties.MapProperty; +import io.swagger.models.properties.RefProperty; +import io.swagger.models.properties.StringProperty; +import io.swagger.parser.SwaggerParser; + +import org.testng.Assert; +import org.testng.annotations.Test; +import org.testng.annotations.ITestAnnotation; + +import com.google.common.collect.Sets; +import java.util.Map; + +@SuppressWarnings("static-method") +public class BashTest { + + @Test(description = "test basic petstore operation with Bash extensions") + public void petstoreOperationTest() { + + final Swagger swagger + = new SwaggerParser() + .read("src/test/resources/2_0/petstore-bash.json"); + final DefaultCodegen codegen = new BashClientCodegen(); + final Operation findPetsByStatusOperation + = swagger.getPath("/pet/findByStatus").getGet(); + + final CodegenOperation op + = codegen.fromOperation( + "/pet/findByStatus", + "GET", + findPetsByStatusOperation, + swagger.getDefinitions(), + swagger); + + Assert.assertTrue( + op.vendorExtensions.containsKey("x-bash-codegen-sample")); + + Assert.assertEquals( + op.vendorExtensions.get("x-bash-codegen-description"), + "Multiple status 'values' can be provided with comma separated strings"); + + } + + @Test(description = "test basic petstore operation with example body") + public void petstoreParameterExampleTest() { + + final Swagger swagger + = new SwaggerParser() + .read("src/test/resources/2_0/petstore-bash.json"); + final DefaultCodegen codegen = new BashClientCodegen(); + final Operation addPetOperation + = swagger.getPath("/pet").getPost(); + + final CodegenOperation op + = codegen.fromOperation( + "/pet", + "POST", + addPetOperation, + swagger.getDefinitions(), + swagger); + + Assert.assertEquals(op.bodyParams.size(), 1); + + CodegenParameter pet = op.bodyParams.get(0); + + Assert.assertTrue(pet.vendorExtensions + .containsKey("x-codegen-body-example")); + + } + + + @Test(description = "test Bash client codegen escapeText method") + public void escapeTextTest() { + final DefaultCodegen codegen = new BashClientCodegen(); + + + Assert.assertEquals(codegen.escapeText("\\/"), "/"); + + Assert.assertEquals(codegen.escapeText("\\"), "\\\\"); + + + ((BashClientCodegen)codegen).setProcessMarkdown(false); + + Assert.assertEquals(codegen.escapeText("__Bold text__"), + "__Bold text__"); + + Assert.assertEquals(codegen.escapeText("**Bold text**"), + "**Bold text**"); + + Assert.assertEquals(codegen.escapeText("*Italic text*"), + "*Italic text*"); + + Assert.assertEquals(codegen.escapeText("_Italic text_"), + "_Italic text_"); + + + ((BashClientCodegen)codegen).setProcessMarkdown(true); + + Assert.assertEquals(codegen.escapeText("__Bold text__"), + "$(tput bold) Bold text $(tput sgr0)"); + + Assert.assertEquals(codegen.escapeText("**Bold text**"), + "$(tput bold) Bold text $(tput sgr0)"); + + Assert.assertEquals(codegen.escapeText("*Italic text*"), + "$(tput dim) Italic text $(tput sgr0)"); + + Assert.assertEquals(codegen.escapeText("_Italic text_"), + "$(tput dim) Italic text $(tput sgr0)"); + + Assert.assertEquals(codegen.escapeText("# SECTION NAME"), + "\n$(tput bold)$(tput setaf 7)SECTION NAME$(tput sgr0)"); + + Assert.assertEquals(codegen.escapeText("## SECTION NAME"), + "\n$(tput bold)$(tput setaf 7)SECTION NAME$(tput sgr0)"); + + Assert.assertEquals(codegen.escapeText("### SECTION NAME"), + "\n$(tput bold)$(tput setaf 7)SECTION NAME$(tput sgr0)"); + + Assert.assertEquals(codegen.escapeText( + "```\nnice -n 100 mvn test\n```"), + "\n---\nnice -n 100 mvn test\n---"); + } + + @Test(description = "test Bash client codegen escapeUnsafeCharacters method") + public void escapeUnsafeCharactersTest() { + final DefaultCodegen codegen = new BashClientCodegen(); + + Assert.assertEquals(codegen.escapeUnsafeCharacters("`no backticks`"), + "'no backticks'"); + + + } + + @Test(description = "test Bash client codegen escapeReservedWord method") + public void escapeReservedWordTest() { + final DefaultCodegen codegen = new BashClientCodegen(); + + Assert.assertEquals(codegen.escapeReservedWord("case"), "_case"); + } + + +} diff --git a/modules/swagger-codegen/src/test/java/io/swagger/codegen/options/BashClientOptionsProvider.java b/modules/swagger-codegen/src/test/java/io/swagger/codegen/options/BashClientOptionsProvider.java new file mode 100644 index 00000000000..3f3ad19fc1f --- /dev/null +++ b/modules/swagger-codegen/src/test/java/io/swagger/codegen/options/BashClientOptionsProvider.java @@ -0,0 +1,61 @@ +package io.swagger.codegen.options; + +import io.swagger.codegen.CodegenConstants; +import io.swagger.codegen.languages.BashClientCodegen; + +import com.google.common.collect.ImmutableMap; + +import java.util.Map; + +public class BashClientOptionsProvider implements OptionsProvider { + + public static final String CURL_OPTIONS = "-k --tlsv1.2"; + public static final String PROCESS_MARKDOWN = "true"; + public static final String SCRIPT_NAME = "petstore-cli"; + public static final String GENERATE_BASH_COMPLETION = "true"; + public static final String GENERATE_ZSH_COMPLETION = "false"; + public static final String HOST_ENVIRONMENT_VARIABLE_NAME + = "PETSTORE_HOSTNAME"; + public static final String BASIC_AUTH_ENVIRONMENT_VARIABLE_NAME + = "PETSTORE_BASIC_AUTH"; + public static final String APIKEY_AUTH_ENVIRONMENT_VARIABLE_NAME + = "PETSTORE_APIKEY"; + + @Override + public String getLanguage() { + return "bash"; + } + + @Override + public Map createOptions() { + + ImmutableMap.Builder builder + = new ImmutableMap.Builder(); + + return builder + .put(BashClientCodegen.CURL_OPTIONS, CURL_OPTIONS) + .put(BashClientCodegen.SCRIPT_NAME, SCRIPT_NAME) + .put(BashClientCodegen.PROCESS_MARKDOWN, PROCESS_MARKDOWN) + .put(BashClientCodegen.GENERATE_BASH_COMPLETION, + GENERATE_BASH_COMPLETION) + .put(BashClientCodegen.GENERATE_ZSH_COMPLETION, + GENERATE_ZSH_COMPLETION) + .put(BashClientCodegen.HOST_ENVIRONMENT_VARIABLE_NAME, + HOST_ENVIRONMENT_VARIABLE_NAME) + .put(BashClientCodegen.BASIC_AUTH_ENVIRONMENT_VARIABLE_NAME, + BASIC_AUTH_ENVIRONMENT_VARIABLE_NAME) + .put(BashClientCodegen.APIKEY_AUTH_ENVIRONMENT_VARIABLE_NAME, + APIKEY_AUTH_ENVIRONMENT_VARIABLE_NAME) + .put(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG, "false") + .put(CodegenConstants.ENSURE_UNIQUE_PARAMS, "false") + .build(); + + } + + @Override + public boolean isServer() { + + return false; + + } +} diff --git a/modules/swagger-codegen/src/test/resources/2_0/bash-config.json b/modules/swagger-codegen/src/test/resources/2_0/bash-config.json new file mode 100644 index 00000000000..a95e6b41733 --- /dev/null +++ b/modules/swagger-codegen/src/test/resources/2_0/bash-config.json @@ -0,0 +1,10 @@ +{ + "processMarkdown": true, + "curlOptions": "-sS --tlsv1.2", + "scriptName": "petstore-cli", + "generateBashCompletion": true, + "generateZshCompletion": true, + "hostEnvironmentVariable": "PETSTORE_HOST", + "basicAuthEnvironmentVariable": "PETSTORE_BASIC_AUTH", + "apiKeyAuthEnvironmentVariable": "PETSTORE_API_KEY" +} \ No newline at end of file diff --git a/modules/swagger-codegen/src/test/resources/2_0/petstore-bash.json b/modules/swagger-codegen/src/test/resources/2_0/petstore-bash.json new file mode 100644 index 00000000000..b58cd694d4e --- /dev/null +++ b/modules/swagger-codegen/src/test/resources/2_0/petstore-bash.json @@ -0,0 +1,1056 @@ +{ + "swagger":"2.0", + "info":{ + "description":"This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.", + "version":"1.0.0", + "title":"Swagger Petstore", + "termsOfService":"http://swagger.io/terms/", + "contact":{ + "email":"apiteam@swagger.io" + }, + "license":{ + "name":"Apache 2.0", + "url":"http://www.apache.org/licenses/LICENSE-2.0.html" + } + }, + "host":"petstore.swagger.io", + "basePath":"/v2", + "tags":[ + { + "name":"pet", + "description":"Everything about your Pets", + "externalDocs":{ + "description":"Find out more", + "url":"http://swagger.io" + } + }, + { + "name":"store", + "description":"Access to Petstore orders" + }, + { + "name":"user", + "description":"Operations about user", + "externalDocs":{ + "description":"Find out more about our store", + "url":"http://swagger.io" + } + } + ], + "schemes":[ + "http" + ], + "paths":{ + "/pet":{ + "post":{ + "tags":[ + "pet" + ], + "summary":"Add a new pet to the store", + "description":"", + "operationId":"addPet", + "consumes":[ + "application/json", + "application/xml" + ], + "produces":[ + "application/xml", + "application/json" + ], + "parameters":[ + { + "in":"body", + "name":"body", + "description":"Pet object that needs to be added to the store", + "required":true, + "schema":{ + "$ref":"#/definitions/Pet" + } + } + ], + "responses":{ + "405":{ + "description":"Invalid input" + } + }, + "security":[ + { + "petstore_auth":[ + "write:pets", + "read:pets" + ] + } + ] + }, + "put":{ + "tags":[ + "pet" + ], + "summary":"Update an existing pet", + "description":"", + "operationId":"updatePet", + "consumes":[ + "application/json", + "application/xml" + ], + "produces":[ + "application/xml", + "application/json" + ], + "parameters":[ + { + "in":"body", + "name":"body", + "description":"Pet object that needs to be added to the store", + "required":true, + "schema":{ + "$ref":"#/definitions/Pet" + } + } + ], + "responses":{ + "400":{ + "description":"Invalid ID supplied" + }, + "404":{ + "description":"Pet not found" + }, + "405":{ + "description":"Validation exception" + } + }, + "security":[ + { + "petstore_auth":[ + "write:pets", + "read:pets" + ] + } + ] + } + }, + "/pet/findByStatus":{ + "get":{ + "tags":[ + "pet" + ], + "summary":"Finds Pets by status", + "x-bash-codegen-description": "Multiple status `values` can be provided with comma separated strings", + "description": "Multiple status values can be provided with comma separated strings", + "operationId":"findPetsByStatus", + "produces":[ + "application/xml", + "application/json" + ], + "x-code-samples":[ + { + "lang": "Shell", + "source": "petstore-cli findPetsByStatus status=available" + } + ], + "parameters":[ + { + "name":"status", + "in":"query", + "description":"Status values that need to be considered for filter", + "required":true, + "type":"array", + "items":{ + "type":"string", + "enum":[ + "available", + "pending", + "sold" + ], + "default":"available" + }, + "collectionFormat":"multi" + } + ], + "responses":{ + "200":{ + "description":"successful operation", + "schema":{ + "type":"array", + "items":{ + "$ref":"#/definitions/Pet" + } + } + }, + "400":{ + "description":"Invalid status value" + } + }, + "security":[ + { + "petstore_auth":[ + "write:pets", + "read:pets" + ] + } + ] + } + }, + "/pet/findByTags":{ + "get":{ + "tags":[ + "pet" + ], + "summary":"Finds Pets by tags", + "description":"Muliple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.", + "operationId":"findPetsByTags", + "produces":[ + "application/xml", + "application/json" + ], + "parameters":[ + { + "name":"tags", + "in":"query", + "description":"Tags to filter by", + "required":true, + "type":"array", + "items":{ + "type":"string" + }, + "collectionFormat":"csv" + } + ], + "responses":{ + "200":{ + "description":"successful operation", + "schema":{ + "type":"array", + "items":{ + "$ref":"#/definitions/Pet" + } + } + }, + "400":{ + "description":"Invalid tag value" + } + }, + "security":[ + { + "petstore_auth":[ + "write:pets", + "read:pets" + ] + } + ], + "deprecated":true + } + }, + "/pet/{petId}":{ + "get":{ + "tags":[ + "pet" + ], + "summary":"Find pet by ID", + "description":"Returns a single pet", + "operationId":"getPetById", + "produces":[ + "application/xml", + "application/json" + ], + "parameters":[ + { + "name":"petId", + "in":"path", + "description":"ID of pet to return", + "required":true, + "type":"integer", + "format":"int64" + } + ], + "responses":{ + "200":{ + "description":"successful operation", + "schema":{ + "$ref":"#/definitions/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", + "consumes":[ + "application/x-www-form-urlencoded" + ], + "produces":[ + "application/xml", + "application/json" + ], + "parameters":[ + { + "name":"petId", + "in":"path", + "description":"ID of pet that needs to be updated", + "required":true, + "type":"integer", + "format":"int64" + }, + { + "name":"name", + "in":"formData", + "description":"Updated name of the pet", + "required":false, + "type":"string" + }, + { + "name":"status", + "in":"formData", + "description":"Updated status of the pet", + "required":false, + "type":"string" + } + ], + "responses":{ + "405":{ + "description":"Invalid input" + } + }, + "security":[ + { + "petstore_auth":[ + "write:pets", + "read:pets" + ] + } + ] + }, + "delete":{ + "tags":[ + "pet" + ], + "summary":"Deletes a pet", + "description":"", + "operationId":"deletePet", + "produces":[ + "application/xml", + "application/json" + ], + "parameters":[ + { + "name":"api_key", + "in":"header", + "required":false, + "type":"string" + }, + { + "name":"petId", + "in":"path", + "description":"Pet id to delete", + "required":true, + "type":"integer", + "format":"int64" + } + ], + "responses":{ + "400":{ + "description":"Invalid ID supplied" + }, + "404":{ + "description":"Pet not found" + } + }, + "security":[ + { + "petstore_auth":[ + "write:pets", + "read:pets" + ] + } + ] + } + }, + "/pet/{petId}/uploadImage":{ + "post":{ + "tags":[ + "pet" + ], + "summary":"uploads an image", + "description":"", + "operationId":"uploadFile", + "consumes":[ + "multipart/form-data" + ], + "produces":[ + "application/json" + ], + "parameters":[ + { + "name":"petId", + "in":"path", + "description":"ID of pet to update", + "required":true, + "type":"integer", + "format":"int64" + }, + { + "name":"additionalMetadata", + "in":"formData", + "description":"Additional data to pass to server", + "required":false, + "type":"string" + }, + { + "name":"file", + "in":"formData", + "description":"file to upload", + "required":false, + "type":"file" + } + ], + "responses":{ + "200":{ + "description":"successful operation", + "schema":{ + "$ref":"#/definitions/ApiResponse" + } + } + }, + "security":[ + { + "petstore_auth":[ + "write:pets", + "read:pets" + ] + } + ] + } + }, + "/store/inventory":{ + "get":{ + "tags":[ + "store" + ], + "summary":"Returns pet inventories by status", + "description":"Returns a map of status codes to quantities", + "operationId":"getInventory", + "produces":[ + "application/json" + ], + "parameters":[ + + ], + "responses":{ + "200":{ + "description":"successful operation", + "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", + "produces":[ + "application/xml", + "application/json" + ], + "parameters":[ + { + "in":"body", + "name":"body", + "description":"order placed for purchasing the pet", + "required":true, + "schema":{ + "$ref":"#/definitions/Order" + } + } + ], + "responses":{ + "200":{ + "description":"successful operation", + "schema":{ + "$ref":"#/definitions/Order" + } + }, + "400":{ + "description":"Invalid Order" + } + } + } + }, + "/store/order/{orderId}":{ + "get":{ + "tags":[ + "store" + ], + "summary":"Find purchase order by ID", + "description":"For valid response try integer IDs with value >= 1 and <= 10. Other values will generated exceptions", + "operationId":"getOrderById", + "produces":[ + "application/xml", + "application/json" + ], + "parameters":[ + { + "name":"orderId", + "in":"path", + "description":"ID of pet that needs to be fetched", + "required":true, + "type":"integer", + "maximum":10.0, + "minimum":1.0, + "format":"int64" + } + ], + "responses":{ + "200":{ + "description":"successful operation", + "schema":{ + "$ref":"#/definitions/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 positive integer value. Negative or non-integer values will generate API errors", + "operationId":"deleteOrder", + "produces":[ + "application/xml", + "application/json" + ], + "parameters":[ + { + "name":"orderId", + "in":"path", + "description":"ID of the order that needs to be deleted", + "required":true, + "type":"integer", + "minimum":1.0, + "format":"int64" + } + ], + "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", + "produces":[ + "application/xml", + "application/json" + ], + "parameters":[ + { + "in":"body", + "name":"body", + "description":"Created user object", + "required":true, + "schema":{ + "$ref":"#/definitions/User" + } + } + ], + "responses":{ + "default":{ + "description":"successful operation" + } + } + } + }, + "/user/createWithArray":{ + "post":{ + "tags":[ + "user" + ], + "summary":"Creates list of users with given input array", + "description":"", + "operationId":"createUsersWithArrayInput", + "produces":[ + "application/xml", + "application/json" + ], + "parameters":[ + { + "in":"body", + "name":"body", + "description":"List of user object", + "required":true, + "schema":{ + "type":"array", + "items":{ + "$ref":"#/definitions/User" + } + } + } + ], + "responses":{ + "default":{ + "description":"successful operation" + } + } + } + }, + "/user/createWithList":{ + "post":{ + "tags":[ + "user" + ], + "summary":"Creates list of users with given input array", + "description":"", + "operationId":"createUsersWithListInput", + "produces":[ + "application/xml", + "application/json" + ], + "parameters":[ + { + "in":"body", + "name":"body", + "description":"List of user object", + "required":true, + "schema":{ + "type":"array", + "items":{ + "$ref":"#/definitions/User" + } + } + } + ], + "responses":{ + "default":{ + "description":"successful operation" + } + } + } + }, + "/user/login":{ + "get":{ + "tags":[ + "user" + ], + "summary":"Logs user into the system", + "description":"", + "operationId":"loginUser", + "produces":[ + "application/xml", + "application/json" + ], + "parameters":[ + { + "name":"username", + "in":"query", + "description":"The user name for login", + "required":true, + "type":"string" + }, + { + "name":"password", + "in":"query", + "description":"The password for login in clear text", + "required":true, + "type":"string" + } + ], + "responses":{ + "200":{ + "description":"successful operation", + "schema":{ + "type":"string" + }, + "headers":{ + "X-Rate-Limit":{ + "type":"integer", + "format":"int32", + "description":"calls per hour allowed by the user" + }, + "X-Expires-After":{ + "type":"string", + "format":"date-time", + "description":"date in UTC when token expires" + } + } + }, + "400":{ + "description":"Invalid username/password supplied" + } + } + } + }, + "/user/logout":{ + "get":{ + "tags":[ + "user" + ], + "summary":"Logs out current logged in user session", + "description":"", + "operationId":"logoutUser", + "produces":[ + "application/xml", + "application/json" + ], + "parameters":[ + + ], + "responses":{ + "default":{ + "description":"successful operation" + } + } + } + }, + "/user/{username}":{ + "get":{ + "tags":[ + "user" + ], + "summary":"Get user by user name", + "description":"", + "operationId":"getUserByName", + "produces":[ + "application/xml", + "application/json" + ], + "parameters":[ + { + "name":"username", + "in":"path", + "description":"The name that needs to be fetched. Use user1 for testing. ", + "required":true, + "type":"string" + } + ], + "responses":{ + "200":{ + "description":"successful operation", + "schema":{ + "$ref":"#/definitions/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", + "produces":[ + "application/xml", + "application/json" + ], + "parameters":[ + { + "name":"username", + "in":"path", + "description":"name that need to be updated", + "required":true, + "type":"string" + }, + { + "in":"body", + "name":"body", + "description":"Updated user object", + "required":true, + "schema":{ + "$ref":"#/definitions/User" + } + } + ], + "responses":{ + "400":{ + "description":"Invalid user supplied" + }, + "404":{ + "description":"User not found" + } + } + }, + "delete":{ + "tags":[ + "user" + ], + "summary":"Delete user", + "description":"This can only be done by the logged in user.", + "operationId":"deleteUser", + "produces":[ + "application/xml", + "application/json" + ], + "parameters":[ + { + "name":"username", + "in":"path", + "description":"The name that needs to be deleted", + "required":true, + "type":"string" + } + ], + "responses":{ + "400":{ + "description":"Invalid username supplied" + }, + "404":{ + "description":"User not found" + } + } + } + } + }, + "securityDefinitions":{ + "petstore_auth":{ + "type":"oauth2", + "authorizationUrl":"http://petstore.swagger.io/oauth/dialog", + "flow":"implicit", + "scopes":{ + "write:pets":"modify pets in your account", + "read:pets":"read your pets" + } + }, + "api_key":{ + "type":"apiKey", + "name":"api_key", + "in":"header" + } + }, + "definitions":{ + "Order":{ + "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":{ + "type":"object", + "properties":{ + "id":{ + "type":"integer", + "format":"int64" + }, + "name":{ + "type":"string" + } + }, + "xml":{ + "name":"Category" + } + }, + "User":{ + "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":{ + "type":"object", + "properties":{ + "id":{ + "type":"integer", + "format":"int64" + }, + "name":{ + "type":"string" + } + }, + "xml":{ + "name":"Tag" + } + }, + "Pet":{ + "type":"object", + "required":[ + "name", + "photoUrls" + ], + "example": { + "name": "lucky", + "photoUrls": [ + "http://example.com/lucky1.jpg" + ] + }, + "properties":{ + "id":{ + "type":"integer", + "format":"int64" + }, + "category":{ + "$ref":"#/definitions/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":"#/definitions/Tag" + } + }, + "status":{ + "type":"string", + "description":"pet status in the store", + "enum":[ + "available", + "pending", + "sold" + ] + } + }, + "xml":{ + "name":"Pet" + } + }, + "ApiResponse":{ + "type":"object", + "properties":{ + "code":{ + "type":"integer", + "format":"int32" + }, + "type":{ + "type":"string" + }, + "message":{ + "type":"string" + } + } + } + }, + "externalDocs":{ + "description":"Find out more about Swagger", + "url":"http://swagger.io" + } +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index 43fcd5542d1..063b84da50d 100644 --- a/pom.xml +++ b/pom.xml @@ -314,6 +314,18 @@ samples/client/petstore/android/volley + + bash-client + + + env + java + + + + samples/client/petstore/bash + + clojure-client @@ -748,6 +760,7 @@ samples/client/petstore/ruby samples/client/petstore/android/volley + samples/client/petstore/bash samples/client/petstore/clojure samples/client/petstore/go samples/client/petstore/java/feign diff --git a/samples/client/petstore/bash/.swagger-codegen-ignore b/samples/client/petstore/bash/.swagger-codegen-ignore new file mode 100644 index 00000000000..c5fa491b4c5 --- /dev/null +++ b/samples/client/petstore/bash/.swagger-codegen-ignore @@ -0,0 +1,23 @@ +# Swagger Codegen Ignore +# Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen + +# 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 Swagger Codgen 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/client/petstore/bash/README.md b/samples/client/petstore/bash/README.md new file mode 100644 index 00000000000..ba13931cd24 --- /dev/null +++ b/samples/client/petstore/bash/README.md @@ -0,0 +1,75 @@ +# Swagger Petstore Bash client + +## Overview +This is a Bash client script for accessing Swagger Petstore service. + +The script uses cURL underneath for making all REST calls. + +## Usage + +```shell +# Make sure the script has executable rights +$ chmod u+x petstore-cli + +# Print the list of operations available on the service +$ ./petstore-cli -h + +# Print the service description +$ ./petstore-cli --about + +# Print detailed information about specific operation +$ ./petstore-cli -h + +# Make GET request +./petstore-cli --host http://: --accept xml = : + +# Make GET request using arbitrary curl options (must be passed before ) to an SSL service using username:password +petstore-cli -k -sS --tlsv1.2 --host https:// -u : --accept xml = : + +# Make POST request +$ echo '' | petstore-cli --host --content-type json - + +# Make POST request with simple JSON content, e.g.: +# { +# "key1": "value1", +# "key2": "value2", +# "key3": 23 +# } +$ echo '' | petstore-cli --host --content-type json key1==value1 key2=value2 key3:=23 - + +# Preview the cURL command without actually executing it +$ petstore-cli --host http://: --dry-run + +``` + +## Shell completion + +### Bash +The generated bash-completion script can be either directly loaded to the current Bash session using: + +```shell +source petstore-cli.bash-completion +``` + +Alternatively, the script can be copied to the `/etc/bash-completion.d` (or on OSX with Homebrew to `/usr/local/etc/bash-completion.d`): + +```shell +sudo cp petstore-cli.bash-completion /etc/bash-completion.d/petstore-cli +``` + +#### OS X +On OSX you might need to install bash-completion using Homebrew: +```shell +brew install bash-completion +``` +and add the following to the `~/.bashrc`: + +```shell +if [ -f $(brew --prefix)/etc/bash_completion ]; then + . $(brew --prefix)/etc/bash_completion +fi +``` + +### Zsh +In Zsh, the generated `_petstore-cli` Zsh completion file must be copied to one of the folders under `$FPATH` variable. + diff --git a/samples/client/petstore/bash/_petstore-cli b/samples/client/petstore/bash/_petstore-cli new file mode 100644 index 00000000000..6ff898e15c6 --- /dev/null +++ b/samples/client/petstore/bash/_petstore-cli @@ -0,0 +1,454 @@ +#compdef petstore-cli + +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# ! +# ! Note: +# ! +# ! THIS SCRIPT HAS BEEN AUTOMATICALLY GENERATED USING +# ! swagger-codegen (https://github.com/swagger-api/swagger-codegen) +# ! FROM SWAGGER SPECIFICATION IN JSON. +# ! +# ! Based on: https://github.com/Valodim/zsh-curl-completion/blob/master/_curl +# ! +# ! Generated on: 2017-01-12T00:07:27.471+01:00 +# ! +# ! +# ! Installation: +# ! +# ! Copy the _petstore-cli file to any directory under FPATH +# ! environment variable (echo $FPATH) +# ! +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + +local curcontext="$curcontext" state line ret=1 +typeset -A opt_args + +# +# cURL crypto engines completion function +# +_curl_crypto_engine() { + local vals + vals=( ${${(f)"$(curl --engine list)":gs/ /}[2,$]} ) + _describe -t outputs 'engines' vals && return 0 +} + +# +# cURL post data completion functions= +# +_curl_post_data() { + + # don't do anything further if this is raw content + compset -P '=' && _message 'raw content' && return 0 + + # complete filename or stdin for @ syntax + compset -P '*@' && { + local expl + _description files expl stdin + compadd "$expl[@]" - "-" + _files + return 0 + } + + # got a name already? expecting data. + compset -P '*=' && _message 'data value' && return 0 + + # otherwise, name (or @ or =) should be specified + _message 'data name' && return 0 + +} + + +local arg_http arg_ftp arg_other arg_proxy arg_crypto arg_connection arg_auth arg_input arg_output + +# HTTP Arguments +arg_http=(''\ + {-0,--http1.0}'[force use of use http 1.0 instead of 1.1]' \ + {-b,--cookie}'[pass data to http server as cookie]:data or file' \ + {-c,--cookie-jar}'[specify cookie file]:file name:_files' \ + {-d,--data}'[send specified data as HTTP POST data]:data:{_curl_post_data}' \ + '--data-binary[post HTTP POST data without any processing]:data:{_curl_post_data}' \ + '--data-urlencode[post HTTP POST data, with url encoding]:data:{_curl_post_data}' \ + {-f,--fail}'[enable failfast behavior for server errors]' \ + '*'{-F,--form}'[add POST form data]:name=content' \ + {-G,--get}'[use HTTP GET even with data (-d, --data, --data-binary)]' \ + '*'{-H,--header}'[specify an extra header]:header' \ + '--ignore-content-length[ignore Content-Length header]' \ + {-i,--include}'[include HTTP header in the output]' \ + {-j,--junk-session-cookies}'[discard all session cookies]' \ + {-e,--referer}'[send url as referer]:referer url:_urls' \ + {-L,--location}'[follow Location headers on http 3XX response]' \ + '--location-trusted[like --location, but allows sending of auth data to redirected hosts]' \ + '--max-redirs[set maximum number of redirection followings allowed]:number' \ + {-J,--remote-header-name}'[use Content-Disposition for output file name]' \ + {-O,--remote-name}'[write to filename parsed from url instead of stdout]' \ + '--post301[do not convert POST to GET after following 301 Location response (follow RFC 2616/10.3.2)]' \ + '--post302[do not convert POST to GET after following 302 Location response (follow RFC 2616/10.3.2)]' \ + ) + +# FTP arguments +arg_ftp=(\ + {-a,--append}'[append to target file instead of overwriting (FTP/SFTP)]' \ + '--crlf[convert LF to CRLF in upload]' \ + '--disable-eprt[disable use of EPRT and LPRT for active FTP transfers]' \ + '--disable-epsv[disable use of EPSV for passive FTP transfers]' \ + '--ftp-account[account data (FTP)]:data' \ + '--ftp-alternative-to-user[command to send when USER and PASS commands fail (FTP)]:command' \ + '--ftp-create-dirs[create paths remotely if it does not exist]' \ + '--ftp-method[ftp method to use to reach a file (FTP)]:method:(multicwd ocwd singlecwd)' \ + '--ftp-pasv[use passive mode for the data connection (FTP)]' \ + '--ftp-skip-pasv-ip[do not use the ip the server suggests for PASV]' \ + '--form-string[like --form, but do not parse content]:name=string' \ + '--ftp-pret[send PRET before PASV]' \ + '--ftp-ssl-ccc[use clear command channel (CCC) after authentication (FTP)]' \ + '--ftp-ssl-ccc-mode[sets the CCC mode (FTP)]:mode:(active passive)' \ + '--ftp-ssl-control[require SSL/TLS for FTP login, clear for transfer]' \ + {-l,--list-only}'[list names only when listing directories (FTP)]' \ + {-P,--ftp-port}'[use active mode, tell server to connect to specified address or interface (FTP]:address' \ + '*'{-Q,--quote}'[send arbitrary command to the remote server before transfer (FTP/SFTP)]:command' \ + ) + +# Other Protocol arguments +arg_other=(\ + '--mail-from[specify From: address]:address' \ + '--mail-rcpt[specify email recipient for SMTP, may be given multiple times]:address' \ + {-t,--telnet-option}'[pass options to telnet protocol]:opt=val' \ + '--tftp-blksize[set tftp BLKSIZE option]:value' \ + ) + +# Proxy arguments +arg_proxy=(\ + '--noproxy[list of hosts to connect directly to instead of through proxy]:no-proxy-list' \ + {-p,--proxytunnel}'[tunnel non-http protocols through http proxy]' \ + {-U,--proxy-user}'[specify the user name and password to use for proxy authentication]:user:password' \ + '--proxy-anyauth[use any authentication method for proxy, default to most secure]' \ + '--proxy-basic[use HTTP Basic authentication for proxy]' \ + '--proxy-digest[use http digest authentication for proxy]' \ + '--proxy-negotiate[enable GSS-Negotiate authentication for proxy]' \ + '--proxy-ntlm[enable ntlm authentication for proxy]' \ + '--proxy1.0[use http 1.0 proxy]:proxy url' \ + {-x,--proxy}'[use specified proxy]:proxy url' \ + '--socks5-gssapi-service[change service name for socks server]:servicename' \ + '--socks5-gssapi-nec[allow unprotected exchange of protection mode negotiation]' \ + ) + +# Crypto arguments +arg_crypto=(\ + {-1,--tlsv1}'[Forces curl to use TLS version 1 when negotiating with a remote TLS server.]' \ + {-2,--sslv2}'[Forces curl to use SSL version 2 when negotiating with a remote SSL server.]' \ + {-3,--sslv3}'[Forces curl to use SSL version 3 when negotiating with a remote SSL server.]' \ + '--ciphers[specifies which cipher to use for the ssl connection]:list of ciphers' \ + '--crlfile[specify file with revoked certificates]:file' \ + '--delegation[set delegation policy to use with GSS/kerberos]:delegation policy:(none policy always)' \ + {-E,--cert}'[use specified client certificate]:certificate file:_files' \ + '--engine[use selected OpenSSL crypto engine]:ssl crypto engine:{_curl_crypto_engine}' \ + '--egd-file[set ssl entropy gathering daemon socket]:entropy socket:_files' \ + '--cert-type[specify certificate type (PEM, DER, ENG)]:certificate type:(PEM DER ENG)' \ + '--cacert[specify certificate file to verify the peer with]:CA certificate:_files' \ + '--capath[specify a search path for certificate files]:CA certificate directory:_directories' \ + '--hostpubmd5[check remote hosts public key]:md5 hash' \ + {-k,--insecure}'[allow ssl to perform insecure ssl connections (ie, ignore certificate)]' \ + '--key[ssl/ssh private key file name]:key file:_files' \ + '--key-type[ssl/ssh private key file type]:file type:(PEM DER ENG)' \ + '--pubkey[ssh public key file]:pubkey file:_files' \ + '--random-file[set source of random data for ssl]:random source:_files' \ + '--no-sessionid[disable caching of ssl session ids]' \ + '--pass:phrase[passphrase for ssl/ssh private key]' \ + '--ssl[try to use ssl/tls for connection, if available]' \ + '--ssl-reqd[try to use ssl/tls for connection, fail if unavailable]' \ + '--tlsauthtype[set TLS authentication type (only SRP supported!)]:authtype' \ + '--tlsuser[set username for TLS authentication]:user' \ + '--tlspassword[set password for TLS authentication]:password' \ + ) + +# Connection arguments +arg_connection=(\ + {-4,--ipv4}'[prefer ipv4]' \ + {-6,--ipv6}'[prefer ipv6, if available]' \ + {-B,--use-ascii}'[use ascii mode]' \ + '--compressed[request a compressed transfer]' \ + '--connect-timeout[timeout for connection phase]:seconds' \ + {-I,--head}'[fetch http HEAD only (HTTP/FTP/FILE]' \ + '--interface[work on a specific interface]:name' \ + '--keepalive-time[set time to wait before sending keepalive probes]:seconds' \ + '--limit-rate[specify maximum transfer rate]:speed' \ + '--local-port[set preferred number or range of local ports to use]:num' \ + {-N,--no-buffer}'[disable buffering of the output stream]' \ + '--no-keepalive[disable use of keepalive messages in TCP connections]' \ + '--raw[disable all http decoding and pass raw data]' \ + '--resolve[provide a custom address for a specific host and port pair]:host\:port\:address' \ + '--retry[specify maximum number of retries for transient errors]:num' \ + '--retry-delay[specify delay between retries]:seconds' \ + '--retry-max-time[maximum time to spend on retries]:seconds' \ + '--tcp-nodelay[turn on TCP_NODELAY option]' \ + {-y,--speed-time}'[specify time to abort after if download is slower than speed-limit]:time' \ + {-Y,--speed-limit}'[specify minimum speed for --speed-time]:speed' \ + ) + +# Authentication arguments +arg_auth=(\ + '--anyauth[use any authentication method, default to most secure]' \ + '--basic[use HTTP Basic authentication]' \ + '--ntlm[enable ntlm authentication]' \ + '--digest[use http digest authentication]' \ + '--krb[use kerberos authentication]:auth:(clear safe confidential private)' \ + '--negotiate[enable GSS-Negotiate authentication]' \ + {-n,--netrc}'[scan ~/.netrc for login data]' \ + '--netrc-optional[like --netrc, but does not make .netrc usage mandatory]' \ + '--netrc-file[like --netrc, but specify file to use]:netrc file:_files' \ + '--tr-encoding[request compressed transfer-encoding]' \ + {-u,--user}'[specify user name and password for server authentication]:user\:password' \ + ) + +# Input arguments +arg_input=(\ + {-C,--continue-at}'[resume at offset ]:offset' \ + {-g,--globoff}'[do not glob {}\[\] letters]' \ + '--max-filesize[maximum filesize to download, fail for bigger files]:bytes' \ + '--proto[specify allowed protocols for transfer]:protocols' \ + '--proto-redir[specify allowed protocols for transfer after a redirect]:protocols' \ + {-r,--range}'[set range of bytes to request (HTTP/FTP/SFTP/FILE)]:range' \ + {-R,--remote-time}'[use timestamp of remote file for local file]' \ + {-T,--upload-file}'[transfer file to remote url (using PUT for HTTP)]:file to upload:_files' \ + '--url[specify a URL to fetch (multi)]:url:_urls' \ + {-z,--time-cond}'[request downloaded file to be newer than date or given reference file]:date expression' \ + ) + +# Output arguments +arg_output=(\ + '--create-dirs[create local directory hierarchy as needed]' \ + {-D,--dump-header}'[write protocol headers to file]:dump file:_files' \ + {-o,--output}'[write to specified file instead of stdout]:output file:_files' \ + {--progress-bar,-\#}'[display progress as a simple progress bar]' \ + {-\#,--progress-bar}'[Make curl display progress as a simple progress bar instead of the standard, more informational, meter.]' \ + {-R,--remote-time}'[use timestamp of remote file for local file]' \ + '--raw[disable all http decoding and pass raw data]' \ + {-s,--silent}'[silent mode, do not show progress meter or error messages]' \ + {-S,--show-error}'[show errors in silent mode]' \ + '--stderr[redirect stderr to specified file]:output file:_files' \ + '--trace[enable full trace dump of all incoming and outgoing data]:trace file:_files' \ + '--trace-ascii[enable full trace dump of all incoming and outgoing data, without hex data]:trace file:_files' \ + '--trace-time[prepends a time stamp to each trace or verbose line that curl displays]' \ + {-v,--verbose}'[output debug info]' \ + {-w,--write-out}'[specify message to output on successful operation]:format string' \ + '--xattr[store some file metadata in extended file attributes]' \ + {-X,--request}'[specifies request method for HTTP server]:method:(GET POST PUT DELETE HEAD OPTIONS TRACE CONNECT PATCH LINK UNLINK)' \ + ) + +_arguments -C -s $arg_http $arg_ftp $arg_other $arg_crypto $arg_connection $arg_auth $arg_input $arg_output \ + {-M,--manual}'[print manual]' \ + '*'{-K,--config}'[use other config file to read arguments from]:config file:_files' \ + '--libcurl[output libcurl code for the operation to file]:output file:_files' \ + {-m,--max-time}'[limit total time of operation]:seconds' \ + {-s,--silent}'[silent mode, do not show progress meter or error messages]' \ + {-S,--show-error}'[show errors in silent mode]' \ + '--stderr[redirect stderr to specified file]:output file:_files' \ + '-q[do not read settings from .curlrc (must be first option)]' \ + {-h,--help}'[Print help and list of operations]' \ + {-V,--version}'[Print service API version]' \ + '--about[Print the information about service]' \ + '--host[Specify the host URL]':URL:_urls \ + '--dry-run[Print out the cURL command without executing it]' \ + {-ac,--accept}'[Set the 'Accept' header in the request]' \ + {-ct,--content-type}'[Set the 'Content-type' header in request]' \ + '1: :->ops' \ + '*:: :->args' \ + && ret=0 + + +case $state in + ops) + # Operations + _values "Operations" \ + "testClientModel[To test \"client\" model]" \ + "testEndpointParameters[Fake endpoint for testing various parameters +假端點 +偽のエンドポイント +가짜 엔드 포인트]" \ + "testEnumParameters[To test enum parameters]" "addPet[Add a new pet to the store]" \ + "deletePet[Deletes a pet]" \ + "findPetsByStatus[Finds Pets by status]" \ + "findPetsByTags[Finds Pets by tags]" \ + "getPetById[Find pet by ID]" \ + "updatePet[Update an existing pet]" \ + "updatePetWithForm[Updates a pet in the store with form data]" \ + "uploadFile[uploads an image]" "deleteOrder[Delete purchase order by ID]" \ + "getInventory[Returns pet inventories by status]" \ + "getOrderById[Find purchase order by ID]" \ + "placeOrder[Place an order for a pet]" "createUser[Create user]" \ + "createUsersWithArrayInput[Creates list of users with given input array]" \ + "createUsersWithListInput[Creates list of users with given input array]" \ + "deleteUser[Delete user]" \ + "getUserByName[Get user by user name]" \ + "loginUser[Logs user into the system]" \ + "logoutUser[Logs out current logged in user session]" \ + "updateUser[Updated user]" + _arguments "(--help)--help[Print information about operation]" + + ret=0 + ;; + args) + case $line[1] in + testClientModel) + local -a _op_arguments + _op_arguments=( + ) + _describe -t actions 'operations' _op_arguments && ret=0 + ;; + testEndpointParameters) + local -a _op_arguments + _op_arguments=( + ) + _describe -t actions 'operations' _op_arguments && ret=0 + ;; + testEnumParameters) + local -a _op_arguments + _op_arguments=( + "enum_query_string_array=:Query parameter enum test (string array)" +"enum_query_string=:Query parameter enum test (string)" +"enum_query_integer=:Query parameter enum test (double)" + "enum_header_string_array\::Header parameter enum test (string array)" +"enum_header_string\::Header parameter enum test (string)" +) + _describe -t actions 'operations' _op_arguments && ret=0 + ;; + addPet) + local -a _op_arguments + _op_arguments=( + ) + _describe -t actions 'operations' _op_arguments && ret=0 + ;; + deletePet) + local -a _op_arguments + _op_arguments=( + "petId=:Pet id to delete" + "api_key\::" +) + _describe -t actions 'operations' _op_arguments && ret=0 + ;; + findPetsByStatus) + local -a _op_arguments + _op_arguments=( + "status=:Status values that need to be considered for filter" + ) + _describe -t actions 'operations' _op_arguments && ret=0 + ;; + findPetsByTags) + local -a _op_arguments + _op_arguments=( + "tags=:Tags to filter by" + ) + _describe -t actions 'operations' _op_arguments && ret=0 + ;; + getPetById) + local -a _op_arguments + _op_arguments=( + "petId=:ID of pet to return" + ) + _describe -t actions 'operations' _op_arguments && ret=0 + ;; + updatePet) + local -a _op_arguments + _op_arguments=( + ) + _describe -t actions 'operations' _op_arguments && ret=0 + ;; + updatePetWithForm) + local -a _op_arguments + _op_arguments=( + "petId=:ID of pet that needs to be updated" + ) + _describe -t actions 'operations' _op_arguments && ret=0 + ;; + uploadFile) + local -a _op_arguments + _op_arguments=( + "petId=:ID of pet to update" + ) + _describe -t actions 'operations' _op_arguments && ret=0 + ;; + deleteOrder) + local -a _op_arguments + _op_arguments=( + "orderId=:ID of the order that needs to be deleted" + ) + _describe -t actions 'operations' _op_arguments && ret=0 + ;; + getInventory) + local -a _op_arguments + _op_arguments=( + ) + _describe -t actions 'operations' _op_arguments && ret=0 + ;; + getOrderById) + local -a _op_arguments + _op_arguments=( + "orderId=:ID of pet that needs to be fetched" + ) + _describe -t actions 'operations' _op_arguments && ret=0 + ;; + placeOrder) + local -a _op_arguments + _op_arguments=( + ) + _describe -t actions 'operations' _op_arguments && ret=0 + ;; + createUser) + local -a _op_arguments + _op_arguments=( + ) + _describe -t actions 'operations' _op_arguments && ret=0 + ;; + createUsersWithArrayInput) + local -a _op_arguments + _op_arguments=( + ) + _describe -t actions 'operations' _op_arguments && ret=0 + ;; + createUsersWithListInput) + local -a _op_arguments + _op_arguments=( + ) + _describe -t actions 'operations' _op_arguments && ret=0 + ;; + deleteUser) + local -a _op_arguments + _op_arguments=( + "username=:The name that needs to be deleted" + ) + _describe -t actions 'operations' _op_arguments && ret=0 + ;; + getUserByName) + local -a _op_arguments + _op_arguments=( + "username=:The name that needs to be fetched. Use user1 for testing." + ) + _describe -t actions 'operations' _op_arguments && ret=0 + ;; + loginUser) + local -a _op_arguments + _op_arguments=( + "username=:The user name for login" +"password=:The password for login in clear text" + ) + _describe -t actions 'operations' _op_arguments && ret=0 + ;; + logoutUser) + local -a _op_arguments + _op_arguments=( + ) + _describe -t actions 'operations' _op_arguments && ret=0 + ;; + updateUser) + local -a _op_arguments + _op_arguments=( + "username=:name that need to be deleted" + ) + _describe -t actions 'operations' _op_arguments && ret=0 + ;; + esac + ;; + +esac + +return ret \ No newline at end of file diff --git a/samples/client/petstore/bash/petstore-cli b/samples/client/petstore/bash/petstore-cli new file mode 100755 index 00000000000..cff2a4cf5f8 --- /dev/null +++ b/samples/client/petstore/bash/petstore-cli @@ -0,0 +1,3312 @@ +#!/usr/bin/env bash + +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# ! +# ! Note: +# ! +# ! THIS SCRIPT HAS BEEN AUTOMATICALLY GENERATED USING +# ! swagger-codegen (https://github.com/swagger-api/swagger-codegen) +# ! FROM SWAGGER SPECIFICATION IN JSON. +# ! +# ! Generated on: 2017-01-12T00:07:27.471+01:00 +# ! +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +# +# This is a Bash client for Swagger Petstore. +# +# LICENSE: +# http://www.apache.org/licenses/LICENSE-2.0.html +# +# CONTACT: +# apiteam@swagger.io +# +# MORE INFORMATION: +# http://swagger.io +# + + +############################################################################### +# +# Global variables +# +############################################################################### + +## +# The filename of this script for help messages +script_name=`basename "$0"` + +## +# Map for headers passed after operation as KEY:VALUE +declare -A header_arguments + + +## +# Map for operation parameters passed after operation as PARAMETER=VALUE +# These will be mapped to appropriate path or query parameters +# The values in operation_parameters are arrays, so that multiple values +# can be provided for the same parameter if allowed by API specification +declare -A operation_parameters + +## +# This array stores the minimum number of required occurences for parameter +# 0 - optional +# 1 - required +declare -A operation_parameters_minimum_occurences +operation_parameters_minimum_occurences["testClientModel:::body"]=1 +operation_parameters_minimum_occurences["testEndpointParameters:::number"]=1 +operation_parameters_minimum_occurences["testEndpointParameters:::double"]=1 +operation_parameters_minimum_occurences["testEndpointParameters:::pattern_without_delimiter"]=1 +operation_parameters_minimum_occurences["testEndpointParameters:::byte"]=1 +operation_parameters_minimum_occurences["testEndpointParameters:::integer"]=0 +operation_parameters_minimum_occurences["testEndpointParameters:::int32"]=0 +operation_parameters_minimum_occurences["testEndpointParameters:::int64"]=0 +operation_parameters_minimum_occurences["testEndpointParameters:::float"]=0 +operation_parameters_minimum_occurences["testEndpointParameters:::string"]=0 +operation_parameters_minimum_occurences["testEndpointParameters:::binary"]=0 +operation_parameters_minimum_occurences["testEndpointParameters:::date"]=0 +operation_parameters_minimum_occurences["testEndpointParameters:::dateTime"]=0 +operation_parameters_minimum_occurences["testEndpointParameters:::password"]=0 +operation_parameters_minimum_occurences["testEndpointParameters:::callback"]=0 +operation_parameters_minimum_occurences["testEnumParameters:::enum_form_string_array"]=0 +operation_parameters_minimum_occurences["testEnumParameters:::enum_form_string"]=0 +operation_parameters_minimum_occurences["testEnumParameters:::enum_header_string_array"]=0 +operation_parameters_minimum_occurences["testEnumParameters:::enum_header_string"]=0 +operation_parameters_minimum_occurences["testEnumParameters:::enum_query_string_array"]=0 +operation_parameters_minimum_occurences["testEnumParameters:::enum_query_string"]=0 +operation_parameters_minimum_occurences["testEnumParameters:::enum_query_integer"]=0 +operation_parameters_minimum_occurences["testEnumParameters:::enum_query_double"]=0 +operation_parameters_minimum_occurences["addPet:::body"]=1 +operation_parameters_minimum_occurences["deletePet:::petId"]=1 +operation_parameters_minimum_occurences["deletePet:::api_key"]=0 +operation_parameters_minimum_occurences["findPetsByStatus:::status"]=1 +operation_parameters_minimum_occurences["findPetsByTags:::tags"]=1 +operation_parameters_minimum_occurences["getPetById:::petId"]=1 +operation_parameters_minimum_occurences["updatePet:::body"]=1 +operation_parameters_minimum_occurences["updatePetWithForm:::petId"]=1 +operation_parameters_minimum_occurences["updatePetWithForm:::name"]=0 +operation_parameters_minimum_occurences["updatePetWithForm:::status"]=0 +operation_parameters_minimum_occurences["uploadFile:::petId"]=1 +operation_parameters_minimum_occurences["uploadFile:::additionalMetadata"]=0 +operation_parameters_minimum_occurences["uploadFile:::file"]=0 +operation_parameters_minimum_occurences["deleteOrder:::orderId"]=1 +operation_parameters_minimum_occurences["getOrderById:::orderId"]=1 +operation_parameters_minimum_occurences["placeOrder:::body"]=1 +operation_parameters_minimum_occurences["createUser:::body"]=1 +operation_parameters_minimum_occurences["createUsersWithArrayInput:::body"]=1 +operation_parameters_minimum_occurences["createUsersWithListInput:::body"]=1 +operation_parameters_minimum_occurences["deleteUser:::username"]=1 +operation_parameters_minimum_occurences["getUserByName:::username"]=1 +operation_parameters_minimum_occurences["loginUser:::username"]=1 +operation_parameters_minimum_occurences["loginUser:::password"]=1 +operation_parameters_minimum_occurences["updateUser:::username"]=1 +operation_parameters_minimum_occurences["updateUser:::body"]=1 + +## +# This array stores the maximum number of allowed occurences for parameter +# 1 - single value +# 2 - 2 values +# N - N values +# 0 - unlimited +declare -A operation_parameters_maximum_occurences +operation_parameters_maximum_occurences["testClientModel:::body"]=0 +operation_parameters_maximum_occurences["testEndpointParameters:::number"]=0 +operation_parameters_maximum_occurences["testEndpointParameters:::double"]=0 +operation_parameters_maximum_occurences["testEndpointParameters:::pattern_without_delimiter"]=0 +operation_parameters_maximum_occurences["testEndpointParameters:::byte"]=0 +operation_parameters_maximum_occurences["testEndpointParameters:::integer"]=0 +operation_parameters_maximum_occurences["testEndpointParameters:::int32"]=0 +operation_parameters_maximum_occurences["testEndpointParameters:::int64"]=0 +operation_parameters_maximum_occurences["testEndpointParameters:::float"]=0 +operation_parameters_maximum_occurences["testEndpointParameters:::string"]=0 +operation_parameters_maximum_occurences["testEndpointParameters:::binary"]=0 +operation_parameters_maximum_occurences["testEndpointParameters:::date"]=0 +operation_parameters_maximum_occurences["testEndpointParameters:::dateTime"]=0 +operation_parameters_maximum_occurences["testEndpointParameters:::password"]=0 +operation_parameters_maximum_occurences["testEndpointParameters:::callback"]=0 +operation_parameters_maximum_occurences["testEnumParameters:::enum_form_string_array"]=0 +operation_parameters_maximum_occurences["testEnumParameters:::enum_form_string"]=0 +operation_parameters_maximum_occurences["testEnumParameters:::enum_header_string_array"]=0 +operation_parameters_maximum_occurences["testEnumParameters:::enum_header_string"]=0 +operation_parameters_maximum_occurences["testEnumParameters:::enum_query_string_array"]=0 +operation_parameters_maximum_occurences["testEnumParameters:::enum_query_string"]=0 +operation_parameters_maximum_occurences["testEnumParameters:::enum_query_integer"]=0 +operation_parameters_maximum_occurences["testEnumParameters:::enum_query_double"]=0 +operation_parameters_maximum_occurences["addPet:::body"]=0 +operation_parameters_maximum_occurences["deletePet:::petId"]=0 +operation_parameters_maximum_occurences["deletePet:::api_key"]=0 +operation_parameters_maximum_occurences["findPetsByStatus:::status"]=0 +operation_parameters_maximum_occurences["findPetsByTags:::tags"]=0 +operation_parameters_maximum_occurences["getPetById:::petId"]=0 +operation_parameters_maximum_occurences["updatePet:::body"]=0 +operation_parameters_maximum_occurences["updatePetWithForm:::petId"]=0 +operation_parameters_maximum_occurences["updatePetWithForm:::name"]=0 +operation_parameters_maximum_occurences["updatePetWithForm:::status"]=0 +operation_parameters_maximum_occurences["uploadFile:::petId"]=0 +operation_parameters_maximum_occurences["uploadFile:::additionalMetadata"]=0 +operation_parameters_maximum_occurences["uploadFile:::file"]=0 +operation_parameters_maximum_occurences["deleteOrder:::orderId"]=0 +operation_parameters_maximum_occurences["getOrderById:::orderId"]=0 +operation_parameters_maximum_occurences["placeOrder:::body"]=0 +operation_parameters_maximum_occurences["createUser:::body"]=0 +operation_parameters_maximum_occurences["createUsersWithArrayInput:::body"]=0 +operation_parameters_maximum_occurences["createUsersWithListInput:::body"]=0 +operation_parameters_maximum_occurences["deleteUser:::username"]=0 +operation_parameters_maximum_occurences["getUserByName:::username"]=0 +operation_parameters_maximum_occurences["loginUser:::username"]=0 +operation_parameters_maximum_occurences["loginUser:::password"]=0 +operation_parameters_maximum_occurences["updateUser:::username"]=0 +operation_parameters_maximum_occurences["updateUser:::body"]=0 + +## +# The type of collection for specifying multiple values for parameter: +# - multi, csv, ssv, tsv +declare -A operation_parameters_collection_type +operation_parameters_collection_type["testClientModel:::body"]="" +operation_parameters_collection_type["testEndpointParameters:::number"]="" +operation_parameters_collection_type["testEndpointParameters:::double"]="" +operation_parameters_collection_type["testEndpointParameters:::pattern_without_delimiter"]="" +operation_parameters_collection_type["testEndpointParameters:::byte"]="" +operation_parameters_collection_type["testEndpointParameters:::integer"]="" +operation_parameters_collection_type["testEndpointParameters:::int32"]="" +operation_parameters_collection_type["testEndpointParameters:::int64"]="" +operation_parameters_collection_type["testEndpointParameters:::float"]="" +operation_parameters_collection_type["testEndpointParameters:::string"]="" +operation_parameters_collection_type["testEndpointParameters:::binary"]="" +operation_parameters_collection_type["testEndpointParameters:::date"]="" +operation_parameters_collection_type["testEndpointParameters:::dateTime"]="" +operation_parameters_collection_type["testEndpointParameters:::password"]="" +operation_parameters_collection_type["testEndpointParameters:::callback"]="" +operation_parameters_collection_type["testEnumParameters:::enum_form_string_array"]= +operation_parameters_collection_type["testEnumParameters:::enum_form_string"]="" +operation_parameters_collection_type["testEnumParameters:::enum_header_string_array"]= +operation_parameters_collection_type["testEnumParameters:::enum_header_string"]="" +operation_parameters_collection_type["testEnumParameters:::enum_query_string_array"]= +operation_parameters_collection_type["testEnumParameters:::enum_query_string"]="" +operation_parameters_collection_type["testEnumParameters:::enum_query_integer"]="" +operation_parameters_collection_type["testEnumParameters:::enum_query_double"]="" +operation_parameters_collection_type["addPet:::body"]="" +operation_parameters_collection_type["deletePet:::petId"]="" +operation_parameters_collection_type["deletePet:::api_key"]="" +operation_parameters_collection_type["findPetsByStatus:::status"]="csv" +operation_parameters_collection_type["findPetsByTags:::tags"]="csv" +operation_parameters_collection_type["getPetById:::petId"]="" +operation_parameters_collection_type["updatePet:::body"]="" +operation_parameters_collection_type["updatePetWithForm:::petId"]="" +operation_parameters_collection_type["updatePetWithForm:::name"]="" +operation_parameters_collection_type["updatePetWithForm:::status"]="" +operation_parameters_collection_type["uploadFile:::petId"]="" +operation_parameters_collection_type["uploadFile:::additionalMetadata"]="" +operation_parameters_collection_type["uploadFile:::file"]="" +operation_parameters_collection_type["deleteOrder:::orderId"]="" +operation_parameters_collection_type["getOrderById:::orderId"]="" +operation_parameters_collection_type["placeOrder:::body"]="" +operation_parameters_collection_type["createUser:::body"]="" +operation_parameters_collection_type["createUsersWithArrayInput:::body"]= +operation_parameters_collection_type["createUsersWithListInput:::body"]= +operation_parameters_collection_type["deleteUser:::username"]="" +operation_parameters_collection_type["getUserByName:::username"]="" +operation_parameters_collection_type["loginUser:::username"]="" +operation_parameters_collection_type["loginUser:::password"]="" +operation_parameters_collection_type["updateUser:::username"]="" +operation_parameters_collection_type["updateUser:::body"]="" + + +## +# Map for body parameters passed after operation as +# PARAMETER==STRING_VALUE or PARAMETER:=NUMERIC_VALUE +# These will be mapped to top level json keys ( { "PARAMETER": "VALUE" }) +declare -A body_parameters + +## +# These arguments will be directly passed to cURL +curl_arguments="" + +## +# The host for making the request +host="$PETSTORE_HOST" + +## +# The user credentials for basic authentication +basic_auth_credential="$PETSTORE_BASIC_AUTH" + +## +# The user API key +apikey_auth_credential="$PETSTORE_API_KEY" + +## +# If true, the script will only output the actual cURL command that would be +# used +print_curl=false + +## +# The operation ID passed on the command line +operation="" + +## +# The provided Accept header value +header_accept="" + +## +# The provided Content-type header value +header_content_type="" + +## +# If there is any body content on the stdin pass it to the body of the request +body_content_temp_file="" + +## +# If this variable is set to true, the request will be performed even +# if parameters for required query, header or body values are not provided +# (path parameters are still required). +force=false + +## +# Declare some mime types abbreviations for easier content-type and accepts +# headers specification +declare -A mime_type_abbreviations +# text/* +mime_type_abbreviations["text"]="text/plain" +mime_type_abbreviations["html"]="text/html" +mime_type_abbreviations["md"]="text/x-markdown" +mime_type_abbreviations["csv"]="text/csv" +mime_type_abbreviations["css"]="text/css" +mime_type_abbreviations["rtf"]="text/rtf" +# application/* +mime_type_abbreviations["json"]="application/json" +mime_type_abbreviations["xml"]="application/xml" +mime_type_abbreviations["yaml"]="application/yaml" +mime_type_abbreviations["js"]="application/javascript" +mime_type_abbreviations["bin"]="application/octet-stream" +mime_type_abbreviations["rdf"]="application/rdf+xml" +# image/* +mime_type_abbreviations["jpg"]="image/jpeg" +mime_type_abbreviations["png"]="image/png" +mime_type_abbreviations["gif"]="image/gif" +mime_type_abbreviations["bmp"]="image/bmp" +mime_type_abbreviations["tiff"]="image/tiff" + + +############################################################################## +# +# Escape special URL characters +# Based on table at http://www.w3schools.com/tags/ref_urlencode.asp +# +############################################################################## +url_escape() { + local raw_url="$1" + + value=$(sed -e 's/ /%20/g' \ + -e 's/!/%21/g' \ + -e 's/"/%22/g' \ + -e 's/#/%23/g' \ + -e 's/\&/%26/g' \ + -e 's/'\''/%28/g' \ + -e 's/(/%28/g' \ + -e 's/)/%29/g' \ + -e 's/:/%3A/g' \ + -e 's/?/%3F/g' <<<$raw_url); + + echo $value +} + +############################################################################## +# +# Lookup the mime type abbreviation in the mime_type_abbreviations array. +# If not present assume the user provided a valid mime type +# +############################################################################## +lookup_mime_type() { + local mime_type=$1 + + if [[ ${mime_type_abbreviations[$mime_type]} ]]; then + echo ${mime_type_abbreviations[$mime_type]} + else + echo $1 + fi +} + +############################################################################## +# +# Converts an associative array into a list of cURL header +# arguments (-H "KEY: VALUE") +# +############################################################################## +header_arguments_to_curl() { + local headers_curl="" + local api_key_header="" + local api_key_header_in_cli="" + api_key_header="api_key" + + for key in "${!header_arguments[@]}"; do + headers_curl+="-H \"${key}: ${header_arguments[${key}]}\" " + if [[ "${key}XX" == "${api_key_header}XX" ]]; then + api_key_header_in_cli="YES" + fi + done + # + # If the api_key was not provided in the header, try one from the + # environment variable + # + if [[ -z $api_key_header_in_cli && -n $apikey_auth_credential ]]; then + headers_curl+="-H \"${api_key_header}: ${apikey_auth_credential}\"" + fi + headers_curl+=" " + + echo "${headers_curl}" +} + +############################################################################## +# +# Converts an associative array into a simple JSON with keys as top +# level object attributes +# +# \todo Add convertion of more complex attributes using paths +# +############################################################################## +body_parameters_to_json() { + local body_json="-d '{" + local body_parameter_count=${#body_parameters[@]} + local count=0 + for key in "${!body_parameters[@]}"; do + body_json+="\"${key}\": ${body_parameters[${key}]}" + if [[ $count -lt $body_parameter_count-1 ]]; then + body_json+=", " + fi + count+=1 + done + body_json+="}'" + + if [[ "${#body_parameters[@]}" -eq 0 ]]; then + echo "" + else + echo "${body_json}" + fi +} + +############################################################################## +# +# Check if provided parameters match specification requirements +# +############################################################################## +validate_request_parameters() { + local path_template=$1 + local -n path_params=$2 + local -n query_params=$3 + + # First replace all path parameters in the path + for pparam in "${path_params[@]}"; do + regexp="(.*)(\{$pparam\})(.*)" + if [[ $path_template =~ $regexp ]]; then + path_template=${BASH_REMATCH[1]}${operation_parameters[$pparam]}${BASH_REMATCH[3]} + fi + done + + # Now append query parameters - if any + if [[ ${#query_params[@]} -gt 0 ]]; then + path_template+="?" + fi + + local query_parameter_count=${#query_params[@]} + local count=0 + for qparam in "${query_params[@]}"; do + # Get the array of parameter values + local parameter_values=($(echo "${operation_parameters[$qparam]}" | sed -e 's/'":::"'/\n/g' | while read line; do echo $line | sed 's/[\t ]/'":::"'/g'; done)) + + # + # Check if the number of provided values is not less than minimum + # required + # + if [[ "$force" = false ]]; then + if [[ ${#parameter_values[@]} -lt ${operation_parameters_minimum_occurences["${operation}:::${qparam}"]} ]]; then + echo "Error: Too few values provided for '${qparam}' parameter" + exit 1 + fi + + # + # Check if the number of provided values is not more than maximum + # + if [[ ${operation_parameters_maximum_occurences["${operation}:::${qparam}"]} -gt 0 \ + && ${#parameter_values[@]} -gt ${operation_parameters_maximum_occurences["${operation}:::${qparam}"]} ]]; then + if [[ "$force" = false ]]; then + echo "Error: Too many values provided for '${qparam}' parameter" + exit 1 + fi + fi + fi + + if [[ "${operation_parameters_collection_type[${operation}:::${qparam}]}" == "" ]]; then + local vcount=0 + for qvalue in "${parameter_values[@]}"; do + path_template+="${qparam}=${qvalue}" + + if [[ $vcount -lt ${#parameter_values[@]}-1 ]]; then + path_template+="&" + fi + vcount+=1 + done + elif [[ "${operation_parameters_collection_type["${operation}:::${qparam}"]}" == "multi" ]]; then + local vcount=0 + for qvalue in "${parameter_values[@]}"; do + path_template+="${qparam}=${qvalue}" + + if [[ $vcount -lt ${#parameter_values[@]}-1 ]]; then + path_template+="&" + fi + vcount+=1 + done + elif [[ "${operation_parameters_collection_type["${operation}:::${qparam}"]}" == "csv" ]]; then + path_template+="${qparam}=" + local vcount=0 + for qvalue in "${parameter_values[@]}"; do + path_template+="${qvalue}" + + if [[ $vcount -lt ${#parameter_values[@]}-1 ]]; then + path_template+="," + fi + vcount+=1 + done + elif [[ "${operation_parameters_collection_type["${operation}:::${qparam}"]}" == "ssv" ]]; then + path_template+="${qparam}=" + for qvalue in "${parameter_values[@]}"; do + path_template+="${qvalue}" + + if [[ $vcount -lt ${#parameter_values[@]}-1 ]]; then + path_template+=" " + fi + vcount+=1 + done + elif [[ "${operation_parameters_collection_type["${operation}:::${qparam}"]}" == "tsv" ]]; then + path_template+="${qparam}=" + for qvalue in "${parameter_values[@]}"; do + path_template+="${qvalue}" + + if [[ $vcount -lt ${#parameter_values[@]}-1 ]]; then + path_template+="\t" + fi + vcount+=1 + done + else + echo -e "" + echo -e "Error: Unsupported collection format " + echo -e "" + exit 1 + fi + + + if [[ $count -lt $query_parameter_count-1 ]]; then + path_template+="&" + fi + count+=1 + done + +} + + + +############################################################################## +# +# Build request path including query parameters +# +############################################################################## +build_request_path() { + local path_template=$1 + local -n path_params=$2 + local -n query_params=$3 + + + # First replace all path parameters in the path + for pparam in "${path_params[@]}"; do + regexp="(.*)(\{$pparam\})(.*)" + if [[ $path_template =~ $regexp ]]; then + path_template=${BASH_REMATCH[1]}${operation_parameters[$pparam]}${BASH_REMATCH[3]} + fi + done + + local query_request_part="" + + local query_parameter_count=${#query_params[@]} + local count=0 + for qparam in "${query_params[@]}"; do + # Get the array of parameter values + local parameter_values=($(echo "${operation_parameters[$qparam]}" | sed -e 's/'":::"'/\n/g' | while read line; do echo $line | sed 's/[\t ]/'":::"'/g'; done)) + local parameter_value="" + + # + # Check if the number of provided values is not less than minimum + # required + # + if [[ "$force" = false ]]; then + if [[ ${#parameter_values[@]} -lt ${operation_parameters_minimum_occurences["${operation}:::${qparam}"]} ]]; then + echo "Error: Too few values provided for '${qparam}' parameter" + exit 1 + fi + + # + # Check if the number of provided values is not more than maximum + # + if [[ ${operation_parameters_maximum_occurences["${operation}:::${qparam}"]} -gt 0 \ + && ${#parameter_values[@]} -gt ${operation_parameters_maximum_occurences["${operation}:::${qparam}"]} ]]; then + if [[ "$force" = false ]]; then + echo "Error: Too many values provided for '${qparam}' parameter" + exit 1 + fi + fi + fi + + # + # Append parameters without specific cardinality + # + if [[ "${operation_parameters_collection_type["${operation}:::${qparam}"]}" == "" ]]; then + local vcount=0 + for qvalue in "${parameter_values[@]}"; do + parameter_value+="${qparam}=${qvalue}" + + if [[ $vcount -lt ${#parameter_values[@]}-1 ]]; then + parameter_value+="&" + fi + vcount+=1 + done + # + # Append parameters specified as 'mutli' collections i.e. param=value1¶m=value2&... + # + elif [[ "${operation_parameters_collection_type["${operation}:::${qparam}"]}" == "multi" ]]; then + local vcount=0 + for qvalue in "${parameter_values[@]}"; do + parameter_value+="${qparam}=${qvalue}" + + if [[ $vcount -lt ${#parameter_values[@]}-1 ]]; then + parameter_value+="&" + fi + vcount+=1 + done + # + # Append parameters specified as 'csv' collections i.e. param=value1,value2,... + # + elif [[ "${operation_parameters_collection_type["${operation}:::${qparam}"]}" == "csv" ]]; then + parameter_value+="${qparam}=" + local vcount=0 + for qvalue in "${parameter_values[@]}"; do + parameter_value+="${qvalue}" + + if [[ $vcount -lt ${#parameter_values[@]}-1 ]]; then + parameter_value+="," + fi + vcount+=1 + done + # + # Append parameters specified as 'ssv' collections i.e. param="value1 value2 ..." + # + elif [[ "${operation_parameters_collection_type["${operation}:::${qparam}"]}" == "ssv" ]]; then + parameter_value+="${qparam}=" + local vcount=0 + for qvalue in "${parameter_values[@]}"; do + parameter_value+="${qvalue}" + + if [[ $vcount -lt ${#parameter_values[@]}-1 ]]; then + parameter_value+=" " + fi + vcount+=1 + done + # + # Append parameters specified as 'tsv' collections i.e. param="value1\tvalue2\t..." + # + elif [[ "${operation_parameters_collection_type["${operation}:::${qparam}"]}" == "tsv" ]]; then + parameter_value+="${qparam}=" + local vcount=0 + for qvalue in "${parameter_values[@]}"; do + parameter_value+="${qvalue}" + + if [[ $vcount -lt ${#parameter_values[@]}-1 ]]; then + parameter_value+="\t" + fi + vcount+=1 + done + fi + + if [[ -n "${parameter_value}" ]]; then + query_request_part+="${parameter_value}" + fi + + if [[ $count -lt $query_parameter_count-1 && -n "${parameter_value}" ]]; then + query_request_part+="&" + fi + + count+=1 + + done + + + # Now append query parameters - if any + if [[ -n "${query_request_part}" ]]; then + path_template+="?$(echo ${query_request_part} | sed s'/&$//')" + fi + + echo $path_template +} + + + +############################################################################### +# +# Print main help message +# +############################################################################### +print_help() { +cat <$(tput sgr0)] + [-ac|--accept $(tput setaf 2)$(tput sgr0)] [-ct,--content-type $(tput setaf 2)$(tput sgr0)] + [--host $(tput setaf 6)$(tput sgr0)] [--dry-run] $(tput setaf 3)$(tput sgr0) [-h|--help] [$(tput setaf 4)$(tput sgr0)] + [$(tput setaf 5)$(tput sgr0)] [$(tput setaf 5)$(tput sgr0)] + + - $(tput setaf 6)$(tput sgr0) - endpoint of the REST service without basepath + Can also be specified in PETSTORE_HOST environment variable. + - $(tput setaf 1)$(tput sgr0) - any valid cURL options can be passed before $(tput setaf 3)$(tput sgr0) + - $(tput setaf 2)$(tput sgr0) - either full mime-type or one of supported abbreviations: + (text, html, md, csv, css, rtf, json, xml, yaml, js, bin, + rdf, jpg, png, gif, bmp, tiff) + - $(tput setaf 4)$(tput sgr0) - HTTP headers can be passed in the form $(tput setaf 3)HEADER$(tput sgr0):$(tput setaf 4)VALUE$(tput sgr0) + - $(tput setaf 5)$(tput sgr0) - REST operation parameters can be passed in the following + forms: + * $(tput setaf 3)KEY$(tput sgr0)=$(tput setaf 4)VALUE$(tput sgr0) - path or query parameters + - $(tput setaf 5)$(tput sgr0) - simple JSON body content (first level only) can be build + using the following arguments: + * $(tput setaf 3)KEY$(tput sgr0)==$(tput setaf 4)VALUE$(tput sgr0) - body parameters which will be added to body + JSON as '{ ..., "$(tput setaf 3)KEY$(tput sgr0)": "$(tput setaf 4)VALUE$(tput sgr0)", ... }' + * $(tput setaf 3)KEY$(tput sgr0):=$(tput setaf 4)VALUE$(tput sgr0) - body parameters which will be added to body + JSON as '{ ..., "$(tput setaf 3)KEY$(tput sgr0)": $(tput setaf 4)VALUE$(tput sgr0), ... }' + +EOF + echo -e "$(tput bold)$(tput setaf 7)Authentication methods$(tput sgr0)" + echo -e "" + echo -e " - $(tput setaf 4)Api-key$(tput sgr0) - add '$(tput setaf 1)api_key:$(tput sgr0)' after $(tput setaf 3)$(tput sgr0)" + echo -e " or export $(tput setaf 1)PETSTORE_API_KEY=''$(tput sgr0)" + echo -e " - $(tput setaf 4)Basic AUTH$(tput sgr0) - add '-u :' before $(tput setaf 3)$(tput sgr0)" + echo -e " or export $(tput setaf 1)PETSTORE_BASIC_AUTH=':'$(tput sgr0)" + echo -e " - $(tput setaf 5)OAuth2 (flow: implicit)$(tput sgr0)" + echo -e " Authorization URL: " + echo -e " * http://petstore.swagger.io/api/oauth/dialog" + echo -e " Scopes:" + echo -e " * write:pets - modify pets in your account" + echo -e " * read:pets - read your pets" + echo "" + echo -e "$(tput bold)$(tput setaf 7)Operations (grouped by tags)$(tput sgr0)" + echo "" + echo -e "$(tput bold)$(tput setaf 7)[fake]$(tput sgr0)" +read -d '' ops <$(tput sgr0)\t\t\t\tSpecify the host URL " +echo -e " \t\t\t\t(e.g. 'https://petstore.swagger.io')" + + echo -e " --force\t\t\t\tForce command invocation in spite of missing" + echo -e " \t\t\t\trequired parameters or wrong content type" + echo -e " --dry-run\t\t\t\tPrint out the cURL command without" + echo -e " \t\t\t\texecuting it" + echo -e " -ac,--accept $(tput setaf 3)$(tput sgr0)\t\tSet the 'Accept' header in the request" + echo -e " -ct,--content-type $(tput setaf 3)$(tput sgr0)\tSet the 'Content-type' header in " + echo -e " \tthe request" + echo "" +} + + +############################################################################## +# +# Print REST service description +# +############################################################################## +print_about() { + echo "" + echo -e "$(tput bold)$(tput setaf 7)Swagger Petstore command line client (API version 1.0.0)$(tput sgr0)" + echo "" + echo -e "License: Apache 2.0" + echo -e "Contact: apiteam@swagger.io" + echo "" +read -d '' appdescription < 10. Other values will generated exceptions" | fold -sw 80 + echo -e "" + echo -e "$(tput bold)$(tput setaf 7)Parameters$(tput sgr0)" + echo -e " * $(tput setaf 2)orderId$(tput sgr0) $(tput setaf 4)[Integer]$(tput sgr0) $(tput setaf 1)(required)$(tput sgr0)$(tput sgr0) - ID of pet that needs to be fetched $(tput setaf 3)Specify as: orderId=value$(tput sgr0)" | fold -sw 80 | sed '2,$s/^/ /' + echo "" + echo -e "$(tput bold)$(tput setaf 7)Responses$(tput sgr0)" + case 200 in + 1*) + echo -e "$(tput setaf 7) 200;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 2*) + echo -e "$(tput setaf 2) 200;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 3*) + echo -e "$(tput setaf 3) 200;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 4*) + echo -e "$(tput setaf 1) 200;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 5*) + echo -e "$(tput setaf 5) 200;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + *) + echo -e "$(tput setaf 7) 200;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + esac + case 400 in + 1*) + echo -e "$(tput setaf 7) 400;Invalid ID supplied$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 2*) + echo -e "$(tput setaf 2) 400;Invalid ID supplied$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 3*) + echo -e "$(tput setaf 3) 400;Invalid ID supplied$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 4*) + echo -e "$(tput setaf 1) 400;Invalid ID supplied$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 5*) + echo -e "$(tput setaf 5) 400;Invalid ID supplied$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + *) + echo -e "$(tput setaf 7) 400;Invalid ID supplied$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + esac + case 404 in + 1*) + echo -e "$(tput setaf 7) 404;Order not found$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 2*) + echo -e "$(tput setaf 2) 404;Order not found$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 3*) + echo -e "$(tput setaf 3) 404;Order not found$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 4*) + echo -e "$(tput setaf 1) 404;Order not found$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 5*) + echo -e "$(tput setaf 5) 404;Order not found$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + *) + echo -e "$(tput setaf 7) 404;Order not found$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + esac +} +############################################################################## +# +# Print help for placeOrder operation +# +############################################################################## +print_placeOrder_help() { + echo "" + echo -e "$(tput bold)$(tput setaf 7)placeOrder - Place an order for a pet$(tput sgr0)" + echo -e "" + echo -e "" | fold -sw 80 + echo -e "" + echo -e "$(tput bold)$(tput setaf 7)Parameters$(tput sgr0)" + echo -e " * $(tput setaf 2)body$(tput sgr0) $(tput setaf 4)[]$(tput sgr0) $(tput setaf 1)(required)$(tput sgr0)$(tput sgr0) - order placed for purchasing the pet" | fold -sw 80 | sed '2,$s/^/ /' + echo -e "" + echo "" + echo -e "$(tput bold)$(tput setaf 7)Responses$(tput sgr0)" + case 200 in + 1*) + echo -e "$(tput setaf 7) 200;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 2*) + echo -e "$(tput setaf 2) 200;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 3*) + echo -e "$(tput setaf 3) 200;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 4*) + echo -e "$(tput setaf 1) 200;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 5*) + echo -e "$(tput setaf 5) 200;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + *) + echo -e "$(tput setaf 7) 200;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + esac + case 400 in + 1*) + echo -e "$(tput setaf 7) 400;Invalid Order$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 2*) + echo -e "$(tput setaf 2) 400;Invalid Order$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 3*) + echo -e "$(tput setaf 3) 400;Invalid Order$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 4*) + echo -e "$(tput setaf 1) 400;Invalid Order$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 5*) + echo -e "$(tput setaf 5) 400;Invalid Order$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + *) + echo -e "$(tput setaf 7) 400;Invalid Order$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + esac +} +############################################################################## +# +# Print help for createUser operation +# +############################################################################## +print_createUser_help() { + echo "" + echo -e "$(tput bold)$(tput setaf 7)createUser - Create user$(tput sgr0)" + echo -e "" + echo -e "This can only be done by the logged in user." | fold -sw 80 + echo -e "" + echo -e "$(tput bold)$(tput setaf 7)Parameters$(tput sgr0)" + echo -e " * $(tput setaf 2)body$(tput sgr0) $(tput setaf 4)[]$(tput sgr0) $(tput setaf 1)(required)$(tput sgr0)$(tput sgr0) - Created user object" | fold -sw 80 | sed '2,$s/^/ /' + echo -e "" + echo "" + echo -e "$(tput bold)$(tput setaf 7)Responses$(tput sgr0)" + case 0 in + 1*) + echo -e "$(tput setaf 7) 0;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 2*) + echo -e "$(tput setaf 2) 0;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 3*) + echo -e "$(tput setaf 3) 0;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 4*) + echo -e "$(tput setaf 1) 0;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 5*) + echo -e "$(tput setaf 5) 0;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + *) + echo -e "$(tput setaf 7) 0;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + esac +} +############################################################################## +# +# Print help for createUsersWithArrayInput operation +# +############################################################################## +print_createUsersWithArrayInput_help() { + echo "" + echo -e "$(tput bold)$(tput setaf 7)createUsersWithArrayInput - Creates list of users with given input array$(tput sgr0)" + echo -e "" + echo -e "" | fold -sw 80 + echo -e "" + echo -e "$(tput bold)$(tput setaf 7)Parameters$(tput sgr0)" + echo -e " * $(tput setaf 2)body$(tput sgr0) $(tput setaf 4)[]$(tput sgr0) $(tput setaf 1)(required)$(tput sgr0)$(tput sgr0) - List of user object" | fold -sw 80 | sed '2,$s/^/ /' + echo -e "" + echo "" + echo -e "$(tput bold)$(tput setaf 7)Responses$(tput sgr0)" + case 0 in + 1*) + echo -e "$(tput setaf 7) 0;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 2*) + echo -e "$(tput setaf 2) 0;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 3*) + echo -e "$(tput setaf 3) 0;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 4*) + echo -e "$(tput setaf 1) 0;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 5*) + echo -e "$(tput setaf 5) 0;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + *) + echo -e "$(tput setaf 7) 0;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + esac +} +############################################################################## +# +# Print help for createUsersWithListInput operation +# +############################################################################## +print_createUsersWithListInput_help() { + echo "" + echo -e "$(tput bold)$(tput setaf 7)createUsersWithListInput - Creates list of users with given input array$(tput sgr0)" + echo -e "" + echo -e "" | fold -sw 80 + echo -e "" + echo -e "$(tput bold)$(tput setaf 7)Parameters$(tput sgr0)" + echo -e " * $(tput setaf 2)body$(tput sgr0) $(tput setaf 4)[]$(tput sgr0) $(tput setaf 1)(required)$(tput sgr0)$(tput sgr0) - List of user object" | fold -sw 80 | sed '2,$s/^/ /' + echo -e "" + echo "" + echo -e "$(tput bold)$(tput setaf 7)Responses$(tput sgr0)" + case 0 in + 1*) + echo -e "$(tput setaf 7) 0;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 2*) + echo -e "$(tput setaf 2) 0;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 3*) + echo -e "$(tput setaf 3) 0;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 4*) + echo -e "$(tput setaf 1) 0;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 5*) + echo -e "$(tput setaf 5) 0;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + *) + echo -e "$(tput setaf 7) 0;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + esac +} +############################################################################## +# +# Print help for deleteUser operation +# +############################################################################## +print_deleteUser_help() { + echo "" + echo -e "$(tput bold)$(tput setaf 7)deleteUser - Delete user$(tput sgr0)" + echo -e "" + echo -e "This can only be done by the logged in user." | fold -sw 80 + echo -e "" + echo -e "$(tput bold)$(tput setaf 7)Parameters$(tput sgr0)" + echo -e " * $(tput setaf 2)username$(tput sgr0) $(tput setaf 4)[String]$(tput sgr0) $(tput setaf 1)(required)$(tput sgr0)$(tput sgr0) - The name that needs to be deleted $(tput setaf 3)Specify as: username=value$(tput sgr0)" | fold -sw 80 | sed '2,$s/^/ /' + echo "" + echo -e "$(tput bold)$(tput setaf 7)Responses$(tput sgr0)" + case 400 in + 1*) + echo -e "$(tput setaf 7) 400;Invalid username supplied$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 2*) + echo -e "$(tput setaf 2) 400;Invalid username supplied$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 3*) + echo -e "$(tput setaf 3) 400;Invalid username supplied$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 4*) + echo -e "$(tput setaf 1) 400;Invalid username supplied$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 5*) + echo -e "$(tput setaf 5) 400;Invalid username supplied$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + *) + echo -e "$(tput setaf 7) 400;Invalid username supplied$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + esac + case 404 in + 1*) + echo -e "$(tput setaf 7) 404;User not found$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 2*) + echo -e "$(tput setaf 2) 404;User not found$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 3*) + echo -e "$(tput setaf 3) 404;User not found$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 4*) + echo -e "$(tput setaf 1) 404;User not found$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 5*) + echo -e "$(tput setaf 5) 404;User not found$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + *) + echo -e "$(tput setaf 7) 404;User not found$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + esac +} +############################################################################## +# +# Print help for getUserByName operation +# +############################################################################## +print_getUserByName_help() { + echo "" + echo -e "$(tput bold)$(tput setaf 7)getUserByName - Get user by user name$(tput sgr0)" + echo -e "" + echo -e "" | fold -sw 80 + echo -e "" + echo -e "$(tput bold)$(tput setaf 7)Parameters$(tput sgr0)" + echo -e " * $(tput setaf 2)username$(tput sgr0) $(tput setaf 4)[String]$(tput sgr0) $(tput setaf 1)(required)$(tput sgr0)$(tput sgr0) - The name that needs to be fetched. Use user1 for testing. $(tput setaf 3)Specify as: username=value$(tput sgr0)" | fold -sw 80 | sed '2,$s/^/ /' + echo "" + echo -e "$(tput bold)$(tput setaf 7)Responses$(tput sgr0)" + case 200 in + 1*) + echo -e "$(tput setaf 7) 200;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 2*) + echo -e "$(tput setaf 2) 200;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 3*) + echo -e "$(tput setaf 3) 200;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 4*) + echo -e "$(tput setaf 1) 200;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 5*) + echo -e "$(tput setaf 5) 200;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + *) + echo -e "$(tput setaf 7) 200;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + esac + case 400 in + 1*) + echo -e "$(tput setaf 7) 400;Invalid username supplied$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 2*) + echo -e "$(tput setaf 2) 400;Invalid username supplied$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 3*) + echo -e "$(tput setaf 3) 400;Invalid username supplied$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 4*) + echo -e "$(tput setaf 1) 400;Invalid username supplied$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 5*) + echo -e "$(tput setaf 5) 400;Invalid username supplied$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + *) + echo -e "$(tput setaf 7) 400;Invalid username supplied$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + esac + case 404 in + 1*) + echo -e "$(tput setaf 7) 404;User not found$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 2*) + echo -e "$(tput setaf 2) 404;User not found$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 3*) + echo -e "$(tput setaf 3) 404;User not found$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 4*) + echo -e "$(tput setaf 1) 404;User not found$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 5*) + echo -e "$(tput setaf 5) 404;User not found$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + *) + echo -e "$(tput setaf 7) 404;User not found$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + esac +} +############################################################################## +# +# Print help for loginUser operation +# +############################################################################## +print_loginUser_help() { + echo "" + echo -e "$(tput bold)$(tput setaf 7)loginUser - Logs user into the system$(tput sgr0)" + echo -e "" + echo -e "" | fold -sw 80 + echo -e "" + echo -e "$(tput bold)$(tput setaf 7)Parameters$(tput sgr0)" + echo -e " * $(tput setaf 2)username$(tput sgr0) $(tput setaf 4)[String]$(tput sgr0) $(tput setaf 1)(required)$(tput sgr0)$(tput sgr0) - The user name for login$(tput setaf 3) Specify as: username=value$(tput sgr0)" \ + | fold -sw 80 | sed '2,$s/^/ /' + echo -e " * $(tput setaf 2)password$(tput sgr0) $(tput setaf 4)[String]$(tput sgr0) $(tput setaf 1)(required)$(tput sgr0)$(tput sgr0) - The password for login in clear text$(tput setaf 3) Specify as: password=value$(tput sgr0)" \ + | fold -sw 80 | sed '2,$s/^/ /' + echo "" + echo -e "$(tput bold)$(tput setaf 7)Responses$(tput sgr0)" + case 200 in + 1*) + echo -e "$(tput setaf 7) 200;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 2*) + echo -e "$(tput setaf 2) 200;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 3*) + echo -e "$(tput setaf 3) 200;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 4*) + echo -e "$(tput setaf 1) 200;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 5*) + echo -e "$(tput setaf 5) 200;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + *) + echo -e "$(tput setaf 7) 200;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + esac + echo -e " $(tput bold)$(tput setaf 7)Response headers$(tput sgr0)" + echo -e " $(tput setaf 4)X-Rate-Limit$(tput sgr0) - calls per hour allowed by the user" | fold -sw 80 | sed '2,$s/^/ /' + echo -e " $(tput setaf 4)X-Expires-After$(tput sgr0) - date in UTC when toekn expires" | fold -sw 80 | sed '2,$s/^/ /' + case 400 in + 1*) + echo -e "$(tput setaf 7) 400;Invalid username/password supplied$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 2*) + echo -e "$(tput setaf 2) 400;Invalid username/password supplied$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 3*) + echo -e "$(tput setaf 3) 400;Invalid username/password supplied$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 4*) + echo -e "$(tput setaf 1) 400;Invalid username/password supplied$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 5*) + echo -e "$(tput setaf 5) 400;Invalid username/password supplied$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + *) + echo -e "$(tput setaf 7) 400;Invalid username/password supplied$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + esac +} +############################################################################## +# +# Print help for logoutUser operation +# +############################################################################## +print_logoutUser_help() { + echo "" + echo -e "$(tput bold)$(tput setaf 7)logoutUser - Logs out current logged in user session$(tput sgr0)" + echo -e "" + echo -e "" | fold -sw 80 + echo -e "" + echo "" + echo -e "$(tput bold)$(tput setaf 7)Responses$(tput sgr0)" + case 0 in + 1*) + echo -e "$(tput setaf 7) 0;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 2*) + echo -e "$(tput setaf 2) 0;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 3*) + echo -e "$(tput setaf 3) 0;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 4*) + echo -e "$(tput setaf 1) 0;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 5*) + echo -e "$(tput setaf 5) 0;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + *) + echo -e "$(tput setaf 7) 0;successful operation$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + esac +} +############################################################################## +# +# Print help for updateUser operation +# +############################################################################## +print_updateUser_help() { + echo "" + echo -e "$(tput bold)$(tput setaf 7)updateUser - Updated user$(tput sgr0)" + echo -e "" + echo -e "This can only be done by the logged in user." | fold -sw 80 + echo -e "" + echo -e "$(tput bold)$(tput setaf 7)Parameters$(tput sgr0)" + echo -e " * $(tput setaf 2)username$(tput sgr0) $(tput setaf 4)[String]$(tput sgr0) $(tput setaf 1)(required)$(tput sgr0)$(tput sgr0) - name that need to be deleted $(tput setaf 3)Specify as: username=value$(tput sgr0)" | fold -sw 80 | sed '2,$s/^/ /' + echo -e " * $(tput setaf 2)body$(tput sgr0) $(tput setaf 4)[]$(tput sgr0) $(tput setaf 1)(required)$(tput sgr0)$(tput sgr0) - Updated user object" | fold -sw 80 | sed '2,$s/^/ /' + echo -e "" + echo "" + echo -e "$(tput bold)$(tput setaf 7)Responses$(tput sgr0)" + case 400 in + 1*) + echo -e "$(tput setaf 7) 400;Invalid user supplied$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 2*) + echo -e "$(tput setaf 2) 400;Invalid user supplied$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 3*) + echo -e "$(tput setaf 3) 400;Invalid user supplied$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 4*) + echo -e "$(tput setaf 1) 400;Invalid user supplied$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 5*) + echo -e "$(tput setaf 5) 400;Invalid user supplied$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + *) + echo -e "$(tput setaf 7) 400;Invalid user supplied$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + esac + case 404 in + 1*) + echo -e "$(tput setaf 7) 404;User not found$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 2*) + echo -e "$(tput setaf 2) 404;User not found$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 3*) + echo -e "$(tput setaf 3) 404;User not found$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 4*) + echo -e "$(tput setaf 1) 404;User not found$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + 5*) + echo -e "$(tput setaf 5) 404;User not found$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + *) + echo -e "$(tput setaf 7) 404;User not found$(tput sgr0)" | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /' + ;; + esac +} + + +############################################################################## +# +# Call testClientModel operation +# +############################################################################## +call_testClientModel() { + local path_parameter_names=() + local query_parameter_names=() + + if [[ $force = false ]]; then + validate_request_parameters "/v2/fake" path_parameter_names query_parameter_names + fi + + local path=$(build_request_path "/v2/fake" path_parameter_names query_parameter_names) + local method="PATCH" + local headers_curl=$(header_arguments_to_curl) + if [[ -n $header_accept ]]; then + headers_curl="${headers_curl} -H 'Accept: ${header_accept}'" + fi + + local basic_auth_option="" + if [[ -n $basic_auth_credential ]]; then + basic_auth_option="-u ${basic_auth_credential}" + fi + local body_json_curl="" + + # + # Check if the user provided 'Content-type' headers in the + # command line. If not try to set them based on the Swagger specification + # if values produces and consumes are defined unambigously + # + if [[ -z $header_content_type ]]; then + header_content_type="application/json" + fi + + + if [[ -z $header_content_type && "$force" = false ]]; then + : + echo "Error: Request's content-type not specified!!!" + echo "This operation expects content-type in one of the following formats:" + echo -e "\t- application/json" + echo "" + echo "Use '--content-type' to set proper content type" + exit 1 + else + headers_curl="${headers_curl} -H 'Content-type: ${header_content_type}'" + fi + + + # + # If we have received some body content over pipe, pass it from the + # temporary file to cURL + # + if [[ -n $body_content_temp_file ]]; then + if [[ "$print_curl" = true ]]; then + echo "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-" + else + eval "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-" + fi + rm "${body_content_temp_file}" + # + # If not, try to build the content body from arguments KEY==VALUE and KEY:=VALUE + # + else + body_json_curl=$(body_parameters_to_json) + if [[ "$print_curl" = true ]]; then + echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\"" + else + eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\"" + fi + fi +} + +############################################################################## +# +# Call testEndpointParameters operation +# +############################################################################## +call_testEndpointParameters() { + local path_parameter_names=() + local query_parameter_names=() + + if [[ $force = false ]]; then + validate_request_parameters "/v2/fake" path_parameter_names query_parameter_names + fi + + local path=$(build_request_path "/v2/fake" path_parameter_names query_parameter_names) + local method="POST" + local headers_curl=$(header_arguments_to_curl) + if [[ -n $header_accept ]]; then + headers_curl="${headers_curl} -H 'Accept: ${header_accept}'" + fi + + local basic_auth_option="" + if [[ -n $basic_auth_credential ]]; then + basic_auth_option="-u ${basic_auth_credential}" + fi + if [[ "$print_curl" = true ]]; then + echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\"" + else + eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\"" + fi +} + +############################################################################## +# +# Call testEnumParameters operation +# +############################################################################## +call_testEnumParameters() { + local path_parameter_names=() + local query_parameter_names=(enum_query_string_array enum_query_string enum_query_integer) + + if [[ $force = false ]]; then + validate_request_parameters "/v2/fake" path_parameter_names query_parameter_names + fi + + local path=$(build_request_path "/v2/fake" path_parameter_names query_parameter_names) + local method="GET" + local headers_curl=$(header_arguments_to_curl) + if [[ -n $header_accept ]]; then + headers_curl="${headers_curl} -H 'Accept: ${header_accept}'" + fi + + local basic_auth_option="" + if [[ -n $basic_auth_credential ]]; then + basic_auth_option="-u ${basic_auth_credential}" + fi + if [[ "$print_curl" = true ]]; then + echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\"" + else + eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\"" + fi +} + +############################################################################## +# +# Call addPet operation +# +############################################################################## +call_addPet() { + local path_parameter_names=() + local query_parameter_names=() + + if [[ $force = false ]]; then + validate_request_parameters "/v2/pet" path_parameter_names query_parameter_names + fi + + local path=$(build_request_path "/v2/pet" path_parameter_names query_parameter_names) + local method="POST" + local headers_curl=$(header_arguments_to_curl) + if [[ -n $header_accept ]]; then + headers_curl="${headers_curl} -H 'Accept: ${header_accept}'" + fi + + local basic_auth_option="" + if [[ -n $basic_auth_credential ]]; then + basic_auth_option="-u ${basic_auth_credential}" + fi + local body_json_curl="" + + # + # Check if the user provided 'Content-type' headers in the + # command line. If not try to set them based on the Swagger specification + # if values produces and consumes are defined unambigously + # + + + if [[ -z $header_content_type && "$force" = false ]]; then + : + echo "Error: Request's content-type not specified!!!" + echo "This operation expects content-type in one of the following formats:" + echo -e "\t- application/json" + echo -e "\t- application/xml" + echo "" + echo "Use '--content-type' to set proper content type" + exit 1 + else + headers_curl="${headers_curl} -H 'Content-type: ${header_content_type}'" + fi + + + # + # If we have received some body content over pipe, pass it from the + # temporary file to cURL + # + if [[ -n $body_content_temp_file ]]; then + if [[ "$print_curl" = true ]]; then + echo "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-" + else + eval "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-" + fi + rm "${body_content_temp_file}" + # + # If not, try to build the content body from arguments KEY==VALUE and KEY:=VALUE + # + else + body_json_curl=$(body_parameters_to_json) + if [[ "$print_curl" = true ]]; then + echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\"" + else + eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\"" + fi + fi +} + +############################################################################## +# +# Call deletePet operation +# +############################################################################## +call_deletePet() { + local path_parameter_names=(petId) + local query_parameter_names=() + + if [[ $force = false ]]; then + validate_request_parameters "/v2/pet/{petId}" path_parameter_names query_parameter_names + fi + + local path=$(build_request_path "/v2/pet/{petId}" path_parameter_names query_parameter_names) + local method="DELETE" + local headers_curl=$(header_arguments_to_curl) + if [[ -n $header_accept ]]; then + headers_curl="${headers_curl} -H 'Accept: ${header_accept}'" + fi + + local basic_auth_option="" + if [[ -n $basic_auth_credential ]]; then + basic_auth_option="-u ${basic_auth_credential}" + fi + if [[ "$print_curl" = true ]]; then + echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\"" + else + eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\"" + fi +} + +############################################################################## +# +# Call findPetsByStatus operation +# +############################################################################## +call_findPetsByStatus() { + local path_parameter_names=() + local query_parameter_names=(status) + + if [[ $force = false ]]; then + validate_request_parameters "/v2/pet/findByStatus" path_parameter_names query_parameter_names + fi + + local path=$(build_request_path "/v2/pet/findByStatus" path_parameter_names query_parameter_names) + local method="GET" + local headers_curl=$(header_arguments_to_curl) + if [[ -n $header_accept ]]; then + headers_curl="${headers_curl} -H 'Accept: ${header_accept}'" + fi + + local basic_auth_option="" + if [[ -n $basic_auth_credential ]]; then + basic_auth_option="-u ${basic_auth_credential}" + fi + if [[ "$print_curl" = true ]]; then + echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\"" + else + eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\"" + fi +} + +############################################################################## +# +# Call findPetsByTags operation +# +############################################################################## +call_findPetsByTags() { + local path_parameter_names=() + local query_parameter_names=(tags) + + if [[ $force = false ]]; then + validate_request_parameters "/v2/pet/findByTags" path_parameter_names query_parameter_names + fi + + local path=$(build_request_path "/v2/pet/findByTags" path_parameter_names query_parameter_names) + local method="GET" + local headers_curl=$(header_arguments_to_curl) + if [[ -n $header_accept ]]; then + headers_curl="${headers_curl} -H 'Accept: ${header_accept}'" + fi + + local basic_auth_option="" + if [[ -n $basic_auth_credential ]]; then + basic_auth_option="-u ${basic_auth_credential}" + fi + if [[ "$print_curl" = true ]]; then + echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\"" + else + eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\"" + fi +} + +############################################################################## +# +# Call getPetById operation +# +############################################################################## +call_getPetById() { + local path_parameter_names=(petId) + local query_parameter_names=() + + if [[ $force = false ]]; then + validate_request_parameters "/v2/pet/{petId}" path_parameter_names query_parameter_names + fi + + local path=$(build_request_path "/v2/pet/{petId}" path_parameter_names query_parameter_names) + local method="GET" + local headers_curl=$(header_arguments_to_curl) + if [[ -n $header_accept ]]; then + headers_curl="${headers_curl} -H 'Accept: ${header_accept}'" + fi + + local basic_auth_option="" + if [[ -n $basic_auth_credential ]]; then + basic_auth_option="-u ${basic_auth_credential}" + fi + if [[ "$print_curl" = true ]]; then + echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\"" + else + eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\"" + fi +} + +############################################################################## +# +# Call updatePet operation +# +############################################################################## +call_updatePet() { + local path_parameter_names=() + local query_parameter_names=() + + if [[ $force = false ]]; then + validate_request_parameters "/v2/pet" path_parameter_names query_parameter_names + fi + + local path=$(build_request_path "/v2/pet" path_parameter_names query_parameter_names) + local method="PUT" + local headers_curl=$(header_arguments_to_curl) + if [[ -n $header_accept ]]; then + headers_curl="${headers_curl} -H 'Accept: ${header_accept}'" + fi + + local basic_auth_option="" + if [[ -n $basic_auth_credential ]]; then + basic_auth_option="-u ${basic_auth_credential}" + fi + local body_json_curl="" + + # + # Check if the user provided 'Content-type' headers in the + # command line. If not try to set them based on the Swagger specification + # if values produces and consumes are defined unambigously + # + + + if [[ -z $header_content_type && "$force" = false ]]; then + : + echo "Error: Request's content-type not specified!!!" + echo "This operation expects content-type in one of the following formats:" + echo -e "\t- application/json" + echo -e "\t- application/xml" + echo "" + echo "Use '--content-type' to set proper content type" + exit 1 + else + headers_curl="${headers_curl} -H 'Content-type: ${header_content_type}'" + fi + + + # + # If we have received some body content over pipe, pass it from the + # temporary file to cURL + # + if [[ -n $body_content_temp_file ]]; then + if [[ "$print_curl" = true ]]; then + echo "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-" + else + eval "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-" + fi + rm "${body_content_temp_file}" + # + # If not, try to build the content body from arguments KEY==VALUE and KEY:=VALUE + # + else + body_json_curl=$(body_parameters_to_json) + if [[ "$print_curl" = true ]]; then + echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\"" + else + eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\"" + fi + fi +} + +############################################################################## +# +# Call updatePetWithForm operation +# +############################################################################## +call_updatePetWithForm() { + local path_parameter_names=(petId) + local query_parameter_names=() + + if [[ $force = false ]]; then + validate_request_parameters "/v2/pet/{petId}" path_parameter_names query_parameter_names + fi + + local path=$(build_request_path "/v2/pet/{petId}" path_parameter_names query_parameter_names) + local method="POST" + local headers_curl=$(header_arguments_to_curl) + if [[ -n $header_accept ]]; then + headers_curl="${headers_curl} -H 'Accept: ${header_accept}'" + fi + + local basic_auth_option="" + if [[ -n $basic_auth_credential ]]; then + basic_auth_option="-u ${basic_auth_credential}" + fi + if [[ "$print_curl" = true ]]; then + echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\"" + else + eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\"" + fi +} + +############################################################################## +# +# Call uploadFile operation +# +############################################################################## +call_uploadFile() { + local path_parameter_names=(petId) + local query_parameter_names=() + + if [[ $force = false ]]; then + validate_request_parameters "/v2/pet/{petId}/uploadImage" path_parameter_names query_parameter_names + fi + + local path=$(build_request_path "/v2/pet/{petId}/uploadImage" path_parameter_names query_parameter_names) + local method="POST" + local headers_curl=$(header_arguments_to_curl) + if [[ -n $header_accept ]]; then + headers_curl="${headers_curl} -H 'Accept: ${header_accept}'" + fi + + local basic_auth_option="" + if [[ -n $basic_auth_credential ]]; then + basic_auth_option="-u ${basic_auth_credential}" + fi + if [[ "$print_curl" = true ]]; then + echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\"" + else + eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\"" + fi +} + +############################################################################## +# +# Call deleteOrder operation +# +############################################################################## +call_deleteOrder() { + local path_parameter_names=(orderId) + local query_parameter_names=() + + if [[ $force = false ]]; then + validate_request_parameters "/v2/store/order/{orderId}" path_parameter_names query_parameter_names + fi + + local path=$(build_request_path "/v2/store/order/{orderId}" path_parameter_names query_parameter_names) + local method="DELETE" + local headers_curl=$(header_arguments_to_curl) + if [[ -n $header_accept ]]; then + headers_curl="${headers_curl} -H 'Accept: ${header_accept}'" + fi + + local basic_auth_option="" + if [[ -n $basic_auth_credential ]]; then + basic_auth_option="-u ${basic_auth_credential}" + fi + if [[ "$print_curl" = true ]]; then + echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\"" + else + eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\"" + fi +} + +############################################################################## +# +# Call getInventory operation +# +############################################################################## +call_getInventory() { + local path_parameter_names=() + local query_parameter_names=() + + if [[ $force = false ]]; then + validate_request_parameters "/v2/store/inventory" path_parameter_names query_parameter_names + fi + + local path=$(build_request_path "/v2/store/inventory" path_parameter_names query_parameter_names) + local method="GET" + local headers_curl=$(header_arguments_to_curl) + if [[ -n $header_accept ]]; then + headers_curl="${headers_curl} -H 'Accept: ${header_accept}'" + fi + + local basic_auth_option="" + if [[ -n $basic_auth_credential ]]; then + basic_auth_option="-u ${basic_auth_credential}" + fi + if [[ "$print_curl" = true ]]; then + echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\"" + else + eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\"" + fi +} + +############################################################################## +# +# Call getOrderById operation +# +############################################################################## +call_getOrderById() { + local path_parameter_names=(orderId) + local query_parameter_names=() + + if [[ $force = false ]]; then + validate_request_parameters "/v2/store/order/{orderId}" path_parameter_names query_parameter_names + fi + + local path=$(build_request_path "/v2/store/order/{orderId}" path_parameter_names query_parameter_names) + local method="GET" + local headers_curl=$(header_arguments_to_curl) + if [[ -n $header_accept ]]; then + headers_curl="${headers_curl} -H 'Accept: ${header_accept}'" + fi + + local basic_auth_option="" + if [[ -n $basic_auth_credential ]]; then + basic_auth_option="-u ${basic_auth_credential}" + fi + if [[ "$print_curl" = true ]]; then + echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\"" + else + eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\"" + fi +} + +############################################################################## +# +# Call placeOrder operation +# +############################################################################## +call_placeOrder() { + local path_parameter_names=() + local query_parameter_names=() + + if [[ $force = false ]]; then + validate_request_parameters "/v2/store/order" path_parameter_names query_parameter_names + fi + + local path=$(build_request_path "/v2/store/order" path_parameter_names query_parameter_names) + local method="POST" + local headers_curl=$(header_arguments_to_curl) + if [[ -n $header_accept ]]; then + headers_curl="${headers_curl} -H 'Accept: ${header_accept}'" + fi + + local basic_auth_option="" + if [[ -n $basic_auth_credential ]]; then + basic_auth_option="-u ${basic_auth_credential}" + fi + local body_json_curl="" + + # + # Check if the user provided 'Content-type' headers in the + # command line. If not try to set them based on the Swagger specification + # if values produces and consumes are defined unambigously + # + + + if [[ -z $header_content_type && "$force" = false ]]; then + : + else + headers_curl="${headers_curl} -H 'Content-type: ${header_content_type}'" + fi + + + # + # If we have received some body content over pipe, pass it from the + # temporary file to cURL + # + if [[ -n $body_content_temp_file ]]; then + if [[ "$print_curl" = true ]]; then + echo "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-" + else + eval "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-" + fi + rm "${body_content_temp_file}" + # + # If not, try to build the content body from arguments KEY==VALUE and KEY:=VALUE + # + else + body_json_curl=$(body_parameters_to_json) + if [[ "$print_curl" = true ]]; then + echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\"" + else + eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\"" + fi + fi +} + +############################################################################## +# +# Call createUser operation +# +############################################################################## +call_createUser() { + local path_parameter_names=() + local query_parameter_names=() + + if [[ $force = false ]]; then + validate_request_parameters "/v2/user" path_parameter_names query_parameter_names + fi + + local path=$(build_request_path "/v2/user" path_parameter_names query_parameter_names) + local method="POST" + local headers_curl=$(header_arguments_to_curl) + if [[ -n $header_accept ]]; then + headers_curl="${headers_curl} -H 'Accept: ${header_accept}'" + fi + + local basic_auth_option="" + if [[ -n $basic_auth_credential ]]; then + basic_auth_option="-u ${basic_auth_credential}" + fi + local body_json_curl="" + + # + # Check if the user provided 'Content-type' headers in the + # command line. If not try to set them based on the Swagger specification + # if values produces and consumes are defined unambigously + # + + + if [[ -z $header_content_type && "$force" = false ]]; then + : + else + headers_curl="${headers_curl} -H 'Content-type: ${header_content_type}'" + fi + + + # + # If we have received some body content over pipe, pass it from the + # temporary file to cURL + # + if [[ -n $body_content_temp_file ]]; then + if [[ "$print_curl" = true ]]; then + echo "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-" + else + eval "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-" + fi + rm "${body_content_temp_file}" + # + # If not, try to build the content body from arguments KEY==VALUE and KEY:=VALUE + # + else + body_json_curl=$(body_parameters_to_json) + if [[ "$print_curl" = true ]]; then + echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\"" + else + eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\"" + fi + fi +} + +############################################################################## +# +# Call createUsersWithArrayInput operation +# +############################################################################## +call_createUsersWithArrayInput() { + local path_parameter_names=() + local query_parameter_names=() + + if [[ $force = false ]]; then + validate_request_parameters "/v2/user/createWithArray" path_parameter_names query_parameter_names + fi + + local path=$(build_request_path "/v2/user/createWithArray" path_parameter_names query_parameter_names) + local method="POST" + local headers_curl=$(header_arguments_to_curl) + if [[ -n $header_accept ]]; then + headers_curl="${headers_curl} -H 'Accept: ${header_accept}'" + fi + + local basic_auth_option="" + if [[ -n $basic_auth_credential ]]; then + basic_auth_option="-u ${basic_auth_credential}" + fi + local body_json_curl="" + + # + # Check if the user provided 'Content-type' headers in the + # command line. If not try to set them based on the Swagger specification + # if values produces and consumes are defined unambigously + # + + + if [[ -z $header_content_type && "$force" = false ]]; then + : + else + headers_curl="${headers_curl} -H 'Content-type: ${header_content_type}'" + fi + + + # + # If we have received some body content over pipe, pass it from the + # temporary file to cURL + # + if [[ -n $body_content_temp_file ]]; then + if [[ "$print_curl" = true ]]; then + echo "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-" + else + eval "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-" + fi + rm "${body_content_temp_file}" + # + # If not, try to build the content body from arguments KEY==VALUE and KEY:=VALUE + # + else + body_json_curl=$(body_parameters_to_json) + if [[ "$print_curl" = true ]]; then + echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\"" + else + eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\"" + fi + fi +} + +############################################################################## +# +# Call createUsersWithListInput operation +# +############################################################################## +call_createUsersWithListInput() { + local path_parameter_names=() + local query_parameter_names=() + + if [[ $force = false ]]; then + validate_request_parameters "/v2/user/createWithList" path_parameter_names query_parameter_names + fi + + local path=$(build_request_path "/v2/user/createWithList" path_parameter_names query_parameter_names) + local method="POST" + local headers_curl=$(header_arguments_to_curl) + if [[ -n $header_accept ]]; then + headers_curl="${headers_curl} -H 'Accept: ${header_accept}'" + fi + + local basic_auth_option="" + if [[ -n $basic_auth_credential ]]; then + basic_auth_option="-u ${basic_auth_credential}" + fi + local body_json_curl="" + + # + # Check if the user provided 'Content-type' headers in the + # command line. If not try to set them based on the Swagger specification + # if values produces and consumes are defined unambigously + # + + + if [[ -z $header_content_type && "$force" = false ]]; then + : + else + headers_curl="${headers_curl} -H 'Content-type: ${header_content_type}'" + fi + + + # + # If we have received some body content over pipe, pass it from the + # temporary file to cURL + # + if [[ -n $body_content_temp_file ]]; then + if [[ "$print_curl" = true ]]; then + echo "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-" + else + eval "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-" + fi + rm "${body_content_temp_file}" + # + # If not, try to build the content body from arguments KEY==VALUE and KEY:=VALUE + # + else + body_json_curl=$(body_parameters_to_json) + if [[ "$print_curl" = true ]]; then + echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\"" + else + eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\"" + fi + fi +} + +############################################################################## +# +# Call deleteUser operation +# +############################################################################## +call_deleteUser() { + local path_parameter_names=(username) + local query_parameter_names=() + + if [[ $force = false ]]; then + validate_request_parameters "/v2/user/{username}" path_parameter_names query_parameter_names + fi + + local path=$(build_request_path "/v2/user/{username}" path_parameter_names query_parameter_names) + local method="DELETE" + local headers_curl=$(header_arguments_to_curl) + if [[ -n $header_accept ]]; then + headers_curl="${headers_curl} -H 'Accept: ${header_accept}'" + fi + + local basic_auth_option="" + if [[ -n $basic_auth_credential ]]; then + basic_auth_option="-u ${basic_auth_credential}" + fi + if [[ "$print_curl" = true ]]; then + echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\"" + else + eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\"" + fi +} + +############################################################################## +# +# Call getUserByName operation +# +############################################################################## +call_getUserByName() { + local path_parameter_names=(username) + local query_parameter_names=() + + if [[ $force = false ]]; then + validate_request_parameters "/v2/user/{username}" path_parameter_names query_parameter_names + fi + + local path=$(build_request_path "/v2/user/{username}" path_parameter_names query_parameter_names) + local method="GET" + local headers_curl=$(header_arguments_to_curl) + if [[ -n $header_accept ]]; then + headers_curl="${headers_curl} -H 'Accept: ${header_accept}'" + fi + + local basic_auth_option="" + if [[ -n $basic_auth_credential ]]; then + basic_auth_option="-u ${basic_auth_credential}" + fi + if [[ "$print_curl" = true ]]; then + echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\"" + else + eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\"" + fi +} + +############################################################################## +# +# Call loginUser operation +# +############################################################################## +call_loginUser() { + local path_parameter_names=() + local query_parameter_names=(username password) + + if [[ $force = false ]]; then + validate_request_parameters "/v2/user/login" path_parameter_names query_parameter_names + fi + + local path=$(build_request_path "/v2/user/login" path_parameter_names query_parameter_names) + local method="GET" + local headers_curl=$(header_arguments_to_curl) + if [[ -n $header_accept ]]; then + headers_curl="${headers_curl} -H 'Accept: ${header_accept}'" + fi + + local basic_auth_option="" + if [[ -n $basic_auth_credential ]]; then + basic_auth_option="-u ${basic_auth_credential}" + fi + if [[ "$print_curl" = true ]]; then + echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\"" + else + eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\"" + fi +} + +############################################################################## +# +# Call logoutUser operation +# +############################################################################## +call_logoutUser() { + local path_parameter_names=() + local query_parameter_names=() + + if [[ $force = false ]]; then + validate_request_parameters "/v2/user/logout" path_parameter_names query_parameter_names + fi + + local path=$(build_request_path "/v2/user/logout" path_parameter_names query_parameter_names) + local method="GET" + local headers_curl=$(header_arguments_to_curl) + if [[ -n $header_accept ]]; then + headers_curl="${headers_curl} -H 'Accept: ${header_accept}'" + fi + + local basic_auth_option="" + if [[ -n $basic_auth_credential ]]; then + basic_auth_option="-u ${basic_auth_credential}" + fi + if [[ "$print_curl" = true ]]; then + echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\"" + else + eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\"" + fi +} + +############################################################################## +# +# Call updateUser operation +# +############################################################################## +call_updateUser() { + local path_parameter_names=(username) + local query_parameter_names=() + + if [[ $force = false ]]; then + validate_request_parameters "/v2/user/{username}" path_parameter_names query_parameter_names + fi + + local path=$(build_request_path "/v2/user/{username}" path_parameter_names query_parameter_names) + local method="PUT" + local headers_curl=$(header_arguments_to_curl) + if [[ -n $header_accept ]]; then + headers_curl="${headers_curl} -H 'Accept: ${header_accept}'" + fi + + local basic_auth_option="" + if [[ -n $basic_auth_credential ]]; then + basic_auth_option="-u ${basic_auth_credential}" + fi + local body_json_curl="" + + # + # Check if the user provided 'Content-type' headers in the + # command line. If not try to set them based on the Swagger specification + # if values produces and consumes are defined unambigously + # + + + if [[ -z $header_content_type && "$force" = false ]]; then + : + else + headers_curl="${headers_curl} -H 'Content-type: ${header_content_type}'" + fi + + + # + # If we have received some body content over pipe, pass it from the + # temporary file to cURL + # + if [[ -n $body_content_temp_file ]]; then + if [[ "$print_curl" = true ]]; then + echo "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-" + else + eval "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-" + fi + rm "${body_content_temp_file}" + # + # If not, try to build the content body from arguments KEY==VALUE and KEY:=VALUE + # + else + body_json_curl=$(body_parameters_to_json) + if [[ "$print_curl" = true ]]; then + echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\"" + else + eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\"" + fi + fi +} + + + +############################################################################## +# +# Main +# +############################################################################## + + +# Make sure Bash is at least in version 4.3 +if [[ ${BASH_VERSION:0:1} < 4 && ${BASH_VERSION:2:1} < 3 ]]; then + echo "Sorry - your Bash version is ${BASH_VERSION}" + echo "" + echo "You need at least Bash 4.3 to run this script." + exit 1 +fi + +# Check dependencies +type curl >/dev/null 2>&1 || { echo >&2 "Error: You do not have 'cURL' installed."; exit 1; } +type sed >/dev/null 2>&1 || { echo >&2 "Error: You do not have 'sed' installed."; exit 1; } +type column >/dev/null 2>&1 || { echo >&2 "Error: You do not have 'bsdmainutils' installed."; exit 1; } + +# +# Process command line +# +# Pass all arguemnts before 'operation' to cURL except the ones we override +# +take_user=false +take_host=false +take_accept_header=false +take_contenttype_header=false + +for key in "$@"; do +# Take the value of -u|--user argument +if [[ "$take_user" = true ]]; then + basic_auth_credential="$key" + take_user=false + continue +fi +# Take the value of --host argument +if [[ "$take_host" = true ]]; then + host="$key" + take_host=false + continue +fi +# Take the value of --accept argument +if [[ "$take_accept_header" = true ]]; then + header_accept=$(lookup_mime_type "$key") + take_accept_header=false + continue +fi +# Take the value of --content-type argument +if [[ "$take_contenttype_header" = true ]]; then + header_content_type=$(lookup_mime_type "$key") + take_contenttype_header=false + continue +fi +case $key in + -h|--help) + if [[ "x$operation" == "x" ]]; then + print_help + exit 0 + else + eval "print_${operation}_help" + exit 0 + fi + ;; + -V|--version) + print_version + exit 0 + ;; + --about) + print_about + exit 0 + ;; + -u|--user) + take_user=true + ;; + --host) + take_host=true + ;; + --force) + force=true + ;; + -ac|--accept) + take_accept_header=true + ;; + -ct|--content-type) + take_contenttype_header=true + ;; + --dry-run) + print_curl=true + ;; + testClientModel) + operation="testClientModel" + ;; + testEndpointParameters) + operation="testEndpointParameters" + ;; + testEnumParameters) + operation="testEnumParameters" + ;; + addPet) + operation="addPet" + ;; + deletePet) + operation="deletePet" + ;; + findPetsByStatus) + operation="findPetsByStatus" + ;; + findPetsByTags) + operation="findPetsByTags" + ;; + getPetById) + operation="getPetById" + ;; + updatePet) + operation="updatePet" + ;; + updatePetWithForm) + operation="updatePetWithForm" + ;; + uploadFile) + operation="uploadFile" + ;; + deleteOrder) + operation="deleteOrder" + ;; + getInventory) + operation="getInventory" + ;; + getOrderById) + operation="getOrderById" + ;; + placeOrder) + operation="placeOrder" + ;; + createUser) + operation="createUser" + ;; + createUsersWithArrayInput) + operation="createUsersWithArrayInput" + ;; + createUsersWithListInput) + operation="createUsersWithListInput" + ;; + deleteUser) + operation="deleteUser" + ;; + getUserByName) + operation="getUserByName" + ;; + loginUser) + operation="loginUser" + ;; + logoutUser) + operation="logoutUser" + ;; + updateUser) + operation="updateUser" + ;; + *==*) + # Parse body arguments and convert them into top level + # JSON properties passed in the body content as strings + if [[ "$operation" ]]; then + IFS='==' read body_key sep body_value <<< "$key" + body_parameters[${body_key}]="\"${body_value}\"" + fi + ;; + *:=*) + # Parse body arguments and convert them into top level + # JSON properties passed in the body content without qoutes + if [[ "$operation" ]]; then + IFS=':=' read body_key sep body_value <<< "$key" + body_parameters[${body_key}]=${body_value} + fi + ;; + *:*) + # Parse header arguments and convert them into curl + # only after the operation argument + if [[ "$operation" ]]; then + IFS=':' read header_name header_value <<< "$key" + # + # If the header key is the same as the api_key expected by API in the + # header, override the ${apikey_auth_credential} variable + # + if [[ $header_name == "api_key" ]]; then + apikey_auth_credential=$header_value + fi + header_arguments[$header_name]=$header_value + else + curl_arguments+=" $key" + fi + ;; + -) + body_content_temp_file=$(mktemp) + cat - > $body_content_temp_file + ;; + *=*) + # Parse operation arguments and convert them into curl + # only after the operation argument + if [[ "$operation" ]]; then + IFS='=' read parameter_name parameter_value <<< "$key" + if [[ -z "${operation_parameters[$parameter_name]+foo}" ]]; then + operation_parameters[$parameter_name]=$(url_escape "${parameter_value}") + else + operation_parameters[$parameter_name]+=":::"$(url_escape "${parameter_value}") + fi + else + curl_arguments+=" $key" + fi + ;; + *) + # If we are before the operation, treat the arguments as cURL arguments + if [[ "x$operation" == "x" ]]; then + # Maintain quotes around cURL arguments if necessary + space_regexp="[[:space:]]" + if [[ $key =~ $space_regexp ]]; then + curl_arguments+=" \"$key\"" + else + curl_arguments+=" $key" + fi + fi + ;; +esac +done + + +# Check if user provided host name +if [[ -z "$host" ]]; then + echo "Error: No hostname provided!!!" + echo "Check usage: '${script_name} --help'" + exit 1 +fi + +# Check if user specified operation ID +if [[ -z "$operation" ]]; then + echo "Error: No operation specified!" + echo "Check available operations: '${script_name} --help'" + exit 1 +fi + + +# Run cURL command based on the operation ID +case $operation in + testClientModel) + call_testClientModel + ;; + testEndpointParameters) + call_testEndpointParameters + ;; + testEnumParameters) + call_testEnumParameters + ;; + addPet) + call_addPet + ;; + deletePet) + call_deletePet + ;; + findPetsByStatus) + call_findPetsByStatus + ;; + findPetsByTags) + call_findPetsByTags + ;; + getPetById) + call_getPetById + ;; + updatePet) + call_updatePet + ;; + updatePetWithForm) + call_updatePetWithForm + ;; + uploadFile) + call_uploadFile + ;; + deleteOrder) + call_deleteOrder + ;; + getInventory) + call_getInventory + ;; + getOrderById) + call_getOrderById + ;; + placeOrder) + call_placeOrder + ;; + createUser) + call_createUser + ;; + createUsersWithArrayInput) + call_createUsersWithArrayInput + ;; + createUsersWithListInput) + call_createUsersWithListInput + ;; + deleteUser) + call_deleteUser + ;; + getUserByName) + call_getUserByName + ;; + loginUser) + call_loginUser + ;; + logoutUser) + call_logoutUser + ;; + updateUser) + call_updateUser + ;; + *) + echo "Error: Unknown operation: $operation" + echo "" + print_help + exit 1 +esac + diff --git a/samples/client/petstore/bash/petstore-cli.bash-completion b/samples/client/petstore/bash/petstore-cli.bash-completion new file mode 100644 index 00000000000..cdb743c60b2 --- /dev/null +++ b/samples/client/petstore/bash/petstore-cli.bash-completion @@ -0,0 +1,286 @@ +# petstore-cli completion -*- shell-script -*- + +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# ! +# ! Note: +# ! +# ! THIS SCRIPT HAS BEEN AUTOMATICALLY GENERATED USING +# ! swagger-codegen (https://github.com/swagger-api/swagger-codegen) +# ! FROM SWAGGER SPECIFICATION IN JSON. +# ! +# ! Generated on: 2017-01-12T00:07:27.471+01:00 +# ! +# ! +# ! System wide installation: +# ! +# ! $ sudo cp petstore-cli.bash-completion /etc/bash-completion.d/petstore-cli +# ! +# ! +# ! User home installation (add this line to .bash_profile): +# ! +# ! [ -r ~/petstore-cli.bash-completion ] && source ~/petstore-cli.bash-completion +# ! +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +declare -A mime_type_abbreviations +# text/* +mime_type_abbreviations["text"]="text/plain" +mime_type_abbreviations["html"]="text/html" +mime_type_abbreviations["md"]="text/x-markdown" +mime_type_abbreviations["csv"]="text/csv" +mime_type_abbreviations["css"]="text/css" +mime_type_abbreviations["rtf"]="text/rtf" +# application/* +mime_type_abbreviations["json"]="application/json" +mime_type_abbreviations["xml"]="application/xml" +mime_type_abbreviations["yaml"]="application/yaml" +mime_type_abbreviations["js"]="application/javascript" +mime_type_abbreviations["bin"]="application/octet-stream" +mime_type_abbreviations["rdf"]="application/rdf+xml" +# image/* +mime_type_abbreviations["jpg"]="image/jpeg" +mime_type_abbreviations["png"]="image/png" +mime_type_abbreviations["gif"]="image/gif" +mime_type_abbreviations["bmp"]="image/bmp" +mime_type_abbreviations["tiff"]="image/tiff" + + + +__osx_init_completion() +{ + COMPREPLY=() + _get_comp_words_by_ref cur prev words cword +} + + +_petstore-cli() +{ + local cur + local prev + local words + local cword + + #words="${COMP_WORDS}" + #cword="${COMP_CWORD}" + #prev="${COMP_WORDS[COMP_CWORD-1]}" + #cur="${COMP_WORDS[COMP_CWORD]}" + + # The reference of currently selected REST operation + local operation="" + + # The list of available operation in the REST service + # It's modelled as an associative array for efficient key lookup + declare -A operations + operations["testClientModel"]=1 + operations["testEndpointParameters"]=1 + operations["testEnumParameters"]=1 + operations["addPet"]=1 + operations["deletePet"]=1 + operations["findPetsByStatus"]=1 + operations["findPetsByTags"]=1 + operations["getPetById"]=1 + operations["updatePet"]=1 + operations["updatePetWithForm"]=1 + operations["uploadFile"]=1 + operations["deleteOrder"]=1 + operations["getInventory"]=1 + operations["getOrderById"]=1 + operations["placeOrder"]=1 + operations["createUser"]=1 + operations["createUsersWithArrayInput"]=1 + operations["createUsersWithListInput"]=1 + operations["deleteUser"]=1 + operations["getUserByName"]=1 + operations["loginUser"]=1 + operations["logoutUser"]=1 + operations["updateUser"]=1 + + # An associative array of operations to their parameters + # Only include path, query and header parameters + declare -A operation_parameters + operation_parameters["testClientModel"]="" + operation_parameters["testEndpointParameters"]="" + operation_parameters["testEnumParameters"]="enum_query_string_array= enum_query_string= enum_query_integer= enum_header_string_array: enum_header_string: " + operation_parameters["addPet"]="" + operation_parameters["deletePet"]="petId= api_key: " + operation_parameters["findPetsByStatus"]="status= " + operation_parameters["findPetsByTags"]="tags= " + operation_parameters["getPetById"]="petId= " + operation_parameters["updatePet"]="" + operation_parameters["updatePetWithForm"]="petId= " + operation_parameters["uploadFile"]="petId= " + operation_parameters["deleteOrder"]="orderId= " + operation_parameters["getInventory"]="" + operation_parameters["getOrderById"]="orderId= " + operation_parameters["placeOrder"]="" + operation_parameters["createUser"]="" + operation_parameters["createUsersWithArrayInput"]="" + operation_parameters["createUsersWithListInput"]="" + operation_parameters["deleteUser"]="username= " + operation_parameters["getUserByName"]="username= " + operation_parameters["loginUser"]="username= password= " + operation_parameters["logoutUser"]="" + operation_parameters["updateUser"]="username= " + + # An associative array of possible values for enum parameters + declare -A operation_parameters_enum_values + + # + # Check if the _init_completion function is available, which is + # available since bash-completion 1.4 + # + if declare -F _init_completions >/dev/null 2>&1; then + _init_completion -s || return + else + __osx_init_completion || return + fi + + + # Check if operation is already in the command line provided + for word in "${words[@]}"; do + if [[ -n $word && ${operations[$word]} ]]; then + operation="${word}" + fi + done + + if [[ -z $operation ]]; then + case $prev in + --ciphers|--connect-timeout|-C|--continue-at|-F|--form|--form-string|\ + --ftp-account|--ftp-alternative-to-user|-P|--ftp-port|-H|--header|-h|\ + --help|--hostpubmd5|--keepalive-time|--krb|--limit-rate|--local-port|\ + --mail-from|--mail-rcpt|--max-filesize|--max-redirs|-m|--max-time|\ + --pass|--proto|--proto-redir|--proxy-user|--proxy1.0|-Q|--quote|-r|\ + --range|-X|--request|--retry|--retry-delay|--retry-max-time|\ + --socks5-gssapi-service|-t|--telnet-option|--tftp-blksize|-z|\ + --time-cond|--url|-u|--user|-A|--user-agent|-V|--version|-w|\ + --write-out|--resolve|--tlsuser|--tlspassword|--about) + return + ;; + -K|--config|-b|--cookie|-c|--cookie-jar|-D|--dump-header|--egd-file|\ + --key|--libcurl|-o|--output|--random-file|-T|--upload-file|--trace|\ + --trace-ascii|--netrc-file) + _filedir + return + ;; + --cacert|-E|--cert) + _filedir '@(c?(e)rt|cer|pem|der)' + return + ;; + --capath) + _filedir -d + return + ;; + --cert-type|--key-type) + COMPREPLY=( $( compgen -W 'DER PEM ENG' -- "$cur" ) ) + return + ;; + --crlfile) + _filedir crl + return + ;; + -d|--data|--data-ascii|--data-binary|--data-urlencode) + if [[ $cur == \@* ]]; then + cur=${cur:1} + _filedir + COMPREPLY=( "${COMPREPLY[@]/#/@}" ) + fi + return + ;; + --delegation) + COMPREPLY=( $( compgen -W 'none policy always' -- "$cur" ) ) + return + ;; + --engine) + COMPREPLY=( $( compgen -W 'list' -- "$cur" ) ) + return + ;; + --ftp-method) + COMPREPLY=( $( compgen -W 'multicwd nocwd singlecwd' -- "$cur" ) ) + return + ;; + --ftp-ssl-ccc-mode) + COMPREPLY=( $( compgen -W 'active passive' -- "$cur" ) ) + return + ;; + --interface) + _available_interfaces -a + return + ;; + -x|--proxy|--socks4|--socks4a|--socks5|--socks5-hostname) + _known_hosts_real + return + ;; + --pubkey) + _filedir pub + return + ;; + --stderr) + COMPREPLY=( $( compgen -W '-' -- "$cur" ) ) + _filedir + return + ;; + --tlsauthtype) + COMPREPLY=( $( compgen -W 'SRP' -- "$cur" ) ) + return + ;; + --host) + COMPREPLY=( $( compgen -W 'http:// https://' -- "$cur" ) ) + return + ;; + -ct|--content-type|-ac|--accept) + COMPREPLY=( $( compgen -W '${!mime_type_abbreviations[*]}' -- "$cur" ) ) + return + ;; + esac + fi + + # + # Complete the server address based on ~/.ssh/known_hosts + # and ~/.ssh/config + # + # \todo Fix - cur matches only '//' when $prev is ':' + # + if [[ "$cur" == "http://" || "$cur" == "https://" ]]; then + COMPREPLY=() + local comp_ssh_hosts=`cat ~/.ssh/known_hosts | \ + cut -f 1 -d ' ' | \ + sed -e s/,.*//g | \ + grep -v ^# | \ + uniq | \ + grep -v "\[" ; + cat ~/.ssh/config | \ + grep "^Host " | \ + awk '{print $2}'` + COMPREPLY=( $(compgen -W "${comp_ssh_hosts}" -- $cur)) + return + fi + + # + # Complete the petstore-cli and cURL's arguments + # + if [[ $cur == -* ]]; then + COMPREPLY=( $( compgen -W '$(_parse_help curl) $(_parse_help $1)' -- "$cur" ) ) + return + fi + + # + # If the argument starts with a letter this could be either an operation + # or an operation parameter + # When $cur is empty, suggest the list of operations by default + # + if [[ $cur =~ ^[A-Za-z_0-9]* ]]; then + # If operation has not been yet selected, suggest the list of operations + # otherwise suggest arguments of this operation as declared in the + # Swagger specification + if [[ -z $operation ]]; then + COMPREPLY=( $(compgen -W '${!operations[*]}' -- ${cur}) ) + else + COMPREPLY=( $(compgen -W '${operation_parameters[$operation]}' -- ${cur}) ) + fi + return + fi + +} && +complete -F _petstore-cli petstore-cli + +# ex: ts=4 sw=4 et filetype=sh \ No newline at end of file diff --git a/samples/client/petstore/bash/pom.xml b/samples/client/petstore/bash/pom.xml new file mode 100644 index 00000000000..fc8237d186c --- /dev/null +++ b/samples/client/petstore/bash/pom.xml @@ -0,0 +1,47 @@ + + 4.0.0 + io.swagger + BashPetstoreClientTests + pom + 1.0-SNAPSHOT + Bash Swagger Petstore Client + + + + maven-dependency-plugin + + + package + + copy-dependencies + + + ${project.build.directory} + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.2.1 + + + bats-test + integration-test + + exec + + + bats + + --tap + tests/petstore_test.sh + + + + + + + + diff --git a/samples/client/petstore/bash/tests/petstore_test.sh b/samples/client/petstore/bash/tests/petstore_test.sh new file mode 100644 index 00000000000..139679eb3ee --- /dev/null +++ b/samples/client/petstore/bash/tests/petstore_test.sh @@ -0,0 +1,102 @@ +#!/usr/bin/env bats + + +export PETSTORE_CLI="petstore-cli" + +export PETSTORE_HOST="http://petstore.swagger.io" + + +# +# Tests for parameter handling and validation +# +@test "addPet without host" { + unset PETSTORE_HOST + run bash $PETSTORE_CLI -ac xml -ct json \ + addPet id:=123321 name==lucky status==available + [[ "$output" =~ "Error: No hostname provided!!!" ]] +} + +@test "addPet without content type" { + run bash $PETSTORE_CLI -ac xml --host $PETSTORE_HOST \ + addPet id:=123321 name==lucky status==available + [[ "$output" =~ "Error: Request's content-type not specified!" ]] +} + +@test "fakeOperation invalid operation name" { + run bash \ + -c "bash $PETSTORE_CLI --host http://petstore.swagger.io fakeOperation" + [[ "$output" =~ "Error: No operation specified!" ]] +} + +@test "findPetsByStatus basic auth" { + run bash \ + -c "bash $PETSTORE_CLI -u alice:secret --host http://petstore.swagger.io findPetsByStatus status=s1 --dry-run" + [[ "$output" =~ "-u alice:secret" ]] +} + +@test "findPetsByStatus api key" { + run bash \ + -c "bash $PETSTORE_CLI --host http://petstore.swagger.io findPetsByStatus status=s1 api_key:1234 --dry-run" + [[ "$output" =~ "-H \"api_key: 1234\"" ]] +} + +@test "findPetsByStatus empty api key" { + run bash \ + -c "bash $PETSTORE_CLI --host http://petstore.swagger.io findPetsByStatus status=s1 --dry-run" + [[ ! "$output" =~ "-H \"api_key:" ]] +} + + + + +@test "findPetsByStatus too few values" { + run bash \ + -c "bash $PETSTORE_CLI --host http://petstore.swagger.io findPetsByStatus" + [[ "$output" =~ "Error: Too few values" ]] +} + +@test "findPetsByTags too few values" { + run bash \ + -c "bash $PETSTORE_CLI --host http://petstore.swagger.io findPetsByTags" + [[ "$output" =~ "Error: Too few values" ]] +} + +@test "findPetsByStatus status with space" { + run bash \ + -c "bash $PETSTORE_CLI --host http://petstore.swagger.io findPetsByStatus \ + status=available status=\"gone test\" --dry-run" + [[ "$output" =~ "status=available,gone%20test" ]] +} + +@test "findPetsByStatus collection csv" { + run bash \ + -c "bash $PETSTORE_CLI --host http://petstore.swagger.io findPetsByTags \ + tags=TAG1 tags=TAG2 --dry-run" + [[ "$output" =~ "tags=TAG1,TAG2" ]] +} + +@test "findPetsByStatus collection csv with space and question mark" { + run bash \ + -c "bash $PETSTORE_CLI --host http://petstore.swagger.io findPetsByTags \ + tags=TAG1 tags=\"TAG2 TEST\" tags=TAG3?TEST --dry-run" + [[ "$output" =~ "tags=TAG1,TAG2%20TEST,TAG3%3FTEST" ]] +} + +# +# Operations calling the service and checking result +# +@test "addPet from parameters" { + run bash $PETSTORE_CLI -ct json -ac xml \ + addPet id:=123321 name==lucky status==available + [[ "$output" =~ "123321" ]] +} + +@test "addPet from pipe" { + run bash \ + -c "echo '{\"id\": 37567, \"name\": \"lucky\", \"status\": \"available\"}' | \ + bash $PETSTORE_CLI -ct json -ac xml addPet -" + [[ "$output" =~ "37567" ]] +} + + +