diff --git a/README.md b/README.md index 2ebccc7307b..fc54e05c347 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ OpenAPI Generator allows generation of API client libraries (SDK generation), se | | Languages/Frameworks | |-|-| -**API clients** | **ActionScript**, **Ada**, **Apex**, **Bash**, **C**, **C#** (.net 2.0, 3.5 or later, .NET Standard 1.3 - 2.0, .NET Core 2.0), **C++** (cpp-restsdk, Qt5, Tizen), **Clojure**, **Dart (1.x, 2.x)**, **Elixir**, **Elm**, **Eiffel**, **Erlang**, **Go**, **Groovy**, **Haskell** (http-client, Servant), **Java** (Jersey1.x, Jersey2.x, OkHttp, Retrofit1.x, Retrofit2.x, Feign, RestTemplate, RESTEasy, Vertx, Google API Client Library for Java, Rest-assured, Spring 5 Web Client), **Kotlin**, **Lua**, **Node.js/JavaScript** (ES5, ES6, AngularJS with Google Closure Compiler annotations, Flow types), **Objective-C**, **OCaml**, **Perl**, **PHP**, **PowerShell**, **Python**, **R**, **Ruby**, **Rust** (rust, rust-server), **Scala** (akka, http4s, scalaz, swagger-async-httpclient), **Swift** (2.x, 3.x, 4.x), **Typescript** (AngularJS, Angular (2.x - 8.x), Aurelia, Axios, Fetch, Inversify, jQuery, Node, Rxjs) +**API clients** | **ActionScript**, **Ada**, **Apex**, **Bash**, **C**, **C#** (.net 2.0, 3.5 or later, .NET Standard 1.3 - 2.0, .NET Core 2.0), **C++** (cpp-restsdk, Qt5, Tizen), **Clojure**, **Dart (1.x, 2.x)**, **Elixir**, **Elm**, **Eiffel**, **Erlang**, **Go**, **Groovy**, **Haskell** (http-client, Servant), **Java** (Jersey1.x, Jersey2.x, OkHttp, Retrofit1.x, Retrofit2.x, Feign, RestTemplate, RESTEasy, Vertx, Google API Client Library for Java, Rest-assured, Spring 5 Web Client), **Kotlin**, **Lua**, **Nim**, **Node.js/JavaScript** (ES5, ES6, AngularJS with Google Closure Compiler annotations, Flow types), **Objective-C**, **OCaml**, **Perl**, **PHP**, **PowerShell**, **Python**, **R**, **Ruby**, **Rust** (rust, rust-server), **Scala** (akka, http4s, scalaz, swagger-async-httpclient), **Swift** (2.x, 3.x, 4.x), **Typescript** (AngularJS, Angular (2.x - 8.x), Aurelia, Axios, Fetch, Inversify, jQuery, Node, Rxjs) **Server stubs** | **Ada**, **C#** (ASP.NET Core, NancyFx), **C++** (Pistache, Restbed, Qt5 QHTTPEngine), **Erlang**, **F#** (Giraffe), **Go** (net/http, Gin), **Haskell** (Servant), **Java** (MSF4J, Spring, Undertow, JAX-RS: CDI, CXF, Inflector, Jersey, RestEasy, Play Framework, [PKMST](https://github.com/ProKarma-Inc/pkmst-getting-started-examples)), **Kotlin** (Spring Boot, Ktor), **PHP** (Laravel, Lumen, Slim, Silex, [Symfony](https://symfony.com/), [Zend Expressive](https://github.com/zendframework/zend-expressive)), **Python** (Flask), **NodeJS**, **Ruby** (Sinatra, Rails5), **Rust** (rust-server), **Scala** ([Finch](https://github.com/finagle/finch), [Lagom](https://github.com/lagom/lagom), [Play](https://www.playframework.com/), Scalatra) **API documentation generators** | **HTML**, **Confluence Wiki** **Configuration files** | [**Apache2**](https://httpd.apache.org/) @@ -699,6 +699,7 @@ Here is a list of template creators: * JMeter: @davidkiss * Kotlin: @jimschubert [:heart:](https://www.patreon.com/jimschubert) * Lua: @daurnimator + * Nim: @hokamoto * OCaml: @cgensoul * Perl: @wing328 [:heart:](https://www.patreon.com/wing328) * PHP (Guzzle): @baartosz @@ -825,6 +826,7 @@ If you want to join the committee, please kindly apply by sending an email to te | Java | @bbdouglas (2017/07) @sreeshas (2017/08) @jfiala (2017/08) @lukoyanov (2017/09) @cbornet (2017/09) @jeff9finger (2018/01) @karismann (2019/03) @Zomzog (2019/04) | | Kotlin | @jimschubert (2017/09) [:heart:](https://www.patreon.com/jimschubert), @dr4ke616 (2018/08) @karismann (2019/03) @Zomzog (2019/04) | | Lua | @daurnimator (2017/08) | +| Nim | | | NodeJS/Javascript | @CodeNinjai (2017/07) @frol (2017/07) @cliffano (2017/07) | | ObjC | | | OCaml | @cgensoul (2019/08) | diff --git a/bin/nim-client-petstore.sh b/bin/nim-client-petstore.sh new file mode 100755 index 00000000000..43eb2f3e3a5 --- /dev/null +++ b/bin/nim-client-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/openapi-generator-cli/target/openapi-generator-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} -Xmx1024M -DloggerPath=conf/log4j.properties" +ags="$@ generate -t modules/openapi-generator/src/main/resources/nim-client -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml --additional-properties packageName=petstore -g nim -o samples/client/petstore/nim" + +java ${JAVA_OPTS} -jar ${executable} ${ags} diff --git a/bin/utils/ensure-up-to-date b/bin/utils/ensure-up-to-date index f31a7601fa2..e8716d8020f 100755 --- a/bin/utils/ensure-up-to-date +++ b/bin/utils/ensure-up-to-date @@ -28,6 +28,7 @@ declare -a scripts=( "./bin/kotlin-springboot-petstore-server.sh" "./bin/kotlin-springboot-petstore-server-reactive.sh" "./bin/mysql-schema-petstore.sh" +"./bin/nim-client-petstore.sh" "./bin/python-petstore-all.sh" "./bin/openapi3/python-petstore.sh" "./bin/php-petstore.sh" diff --git a/bin/windows/nim-client-petstore.bat b/bin/windows/nim-client-petstore.bat new file mode 100644 index 00000000000..875bff9fe8b --- /dev/null +++ b/bin/windows/nim-client-petstore.bat @@ -0,0 +1,10 @@ +set executable=.\modules\openapi-generator-cli\target\openapi-generator-cli.jar + +If Not Exist %executable% ( + mvn clean package +) + +REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M -DloggerPath=conf/log4j.properties +set ags=generate --artifact-id "nim-petstore-client" -i modules\openapi-generator\src\test\resources\2_0\petstore.yaml --additional-properties packageName=petstore -g nim -o samples\client\petstore\nim + +java %JAVA_OPTS% -jar %executable% %ags% diff --git a/docs/generators.md b/docs/generators.md index ad165bd203e..f8b4f930461 100644 --- a/docs/generators.md +++ b/docs/generators.md @@ -38,6 +38,7 @@ The following generators are available: * [jmeter](generators/jmeter) * [kotlin](generators/kotlin) * [lua](generators/lua) +* [nim](generators/nim) * [objc](generators/objc) * [ocaml](generators/ocaml) * [perl](generators/perl) diff --git a/docs/generators/nim.md b/docs/generators/nim.md new file mode 100644 index 00000000000..228226876af --- /dev/null +++ b/docs/generators/nim.md @@ -0,0 +1,13 @@ + +--- +id: generator-opts-client-nim +title: Config Options for nim +sidebar_label: nim +--- + +| Option | Description | Values | Default | +| ------ | ----------- | ------ | ------- | +|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true| +|ensureUniqueParams|Whether to ensure parameter names are unique in an operation (rename parameters that are not).| |true| +|allowUnicodeIdentifiers|boolean, toggles whether unicode identifiers are allowed in names or not, default is false| |false| +|prependFormOrBodyParameters|Add form or body parameters to the beginning of the parameter list.| |false| diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/NimClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/NimClientCodegen.java new file mode 100644 index 00000000000..577a9c857f3 --- /dev/null +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/NimClientCodegen.java @@ -0,0 +1,309 @@ +package org.openapitools.codegen.languages; + +import io.swagger.v3.oas.models.media.ArraySchema; +import io.swagger.v3.oas.models.media.Schema; +import io.swagger.v3.oas.models.media.StringSchema; +import org.openapitools.codegen.*; +import org.openapitools.codegen.utils.ModelUtils; +import org.openapitools.codegen.utils.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.util.*; + +import static org.openapitools.codegen.utils.StringUtils.camelize; +import static org.openapitools.codegen.utils.StringUtils.underscore; + +public class NimClientCodegen extends DefaultCodegen implements CodegenConfig { + static Logger LOGGER = LoggerFactory.getLogger(NimClientCodegen.class); + + public static final String PROJECT_NAME = "projectName"; + + protected String packageName = "openapiclient"; + protected String packageVersion = "1.0.0"; + + public CodegenType getTag() { + return CodegenType.CLIENT; + } + + public String getName() { + return "nim"; + } + + public String getHelp() { + return "Generates a nim client."; + } + + public NimClientCodegen() { + super(); + + outputFolder = "generated-code" + File.separator + "nim"; + modelTemplateFiles.put("model.mustache", ".nim"); + apiTemplateFiles.put("api.mustache", ".nim"); + embeddedTemplateDir = templateDir = "nim-client"; + apiPackage = File.separator + packageName + File.separator + "apis"; + modelPackage = File.separator + packageName + File.separator + "models"; + supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")); + supportingFiles.add(new SupportingFile("sample_client.mustache", "", "sample_client.nim")); + supportingFiles.add(new SupportingFile("config.mustache", "", "config.nim")); + + setReservedWordsLowerCase( + Arrays.asList( + "addr", "and", "as", "asm", + "bind", "block", "break", + "case", "cast", "concept", "const", "continue", "converter", + "defer", "discard", "distinct", "div", "do", + "elif", "else", "end", "enum", "except", "export", + "finally", "for", "from", "func", + "if", "import", "in", "include", "interface", "is", "isnot", "iterator", + "let", + "macro", "method", "mixin", "mod", + "nil", "not", "notin", + "object", "of", "or", "out", + "proc", "ptr", + "raise", "ref", "return", + "shl", "shr", "static", + "template", "try", "tuple", "type", + "using", + "var", + "when", "while", + "xor", + "yield" + ) + ); + + defaultIncludes = new HashSet( + Arrays.asList( + "array" + ) + ); + + languageSpecificPrimitives = new HashSet( + Arrays.asList( + "int", + "int8", + "int16", + "int32", + "int64", + "uint", + "uint8", + "uint16", + "uint32", + "uint64", + "float", + "float32", + "float64", + "bool", + "char", + "string", + "cstring", + "pointer") + ); + + typeMapping.clear(); + typeMapping.put("integer", "int"); + typeMapping.put("long", "int64"); + typeMapping.put("number", "float"); + typeMapping.put("float", "float"); + typeMapping.put("double", "float64"); + typeMapping.put("boolean", "bool"); + typeMapping.put("UUID", "string"); + typeMapping.put("URI", "string"); + typeMapping.put("date", "string"); + typeMapping.put("DateTime", "string"); + typeMapping.put("password", "string"); + typeMapping.put("file", "string"); + } + + public void setPackageName(String packageName) { + this.packageName = packageName; + } + + public void setPackageVersion(String packageVersion) { + this.packageVersion = packageVersion; + } + + @Override + public Map postProcessModels(Map objs) { + return postProcessModelsEnum(objs); + } + + @Override + public void processOpts() { + super.processOpts(); + + if (additionalProperties.containsKey(CodegenConstants.PACKAGE_NAME)) { + setPackageName((String) additionalProperties.get(CodegenConstants.PACKAGE_NAME)); + } + + if (additionalProperties.containsKey(CodegenConstants.PACKAGE_VERSION)) { + setPackageVersion((String) additionalProperties.get(CodegenConstants.PACKAGE_VERSION)); + } + + additionalProperties.put(CodegenConstants.PACKAGE_NAME, packageName); + additionalProperties.put(CodegenConstants.PACKAGE_VERSION, packageVersion); + + apiPackage = File.separator + packageName + File.separator + "apis"; + modelPackage = File.separator + packageName + File.separator + "models"; + supportingFiles.add(new SupportingFile("lib.mustache", "", packageName + ".nim")); + } + + @Override + public String escapeReservedWord(String name) { + LOGGER.warn("A reserved word \"" + name + "\" is used. Consider renaming the field name"); + if (this.reservedWordsMappings().containsKey(name)) { + return this.reservedWordsMappings().get(name); + } + return "`" + name + "`"; + } + + @Override + public String escapeQuotationMark(String input) { + return input.replace("\"", ""); + } + + @Override + public String escapeUnsafeCharacters(String input) { + return input.replace("*/", "*_/").replace("/*", "/_*"); + } + + @Override + public String toModelImport(String name) { + name = name.replaceAll("-", "_"); + if (importMapping.containsKey(name)) { + return "model_" + StringUtils.underscore(importMapping.get(name)); + } else { + return "model_" + StringUtils.underscore(name); + } + } + + @Override + public String toApiImport(String name) { + name = name.replaceAll("-", "_"); + if (importMapping.containsKey(name)) { + return "api_" + StringUtils.underscore(importMapping.get(name)); + } else { + return "api_" + StringUtils.underscore(name); + } + } + + @Override + public String toModelFilename(String name) { + name = name.replaceAll("-", "_"); + return "model_" + StringUtils.underscore(name); + } + + @Override + public String toApiFilename(String name) { + name = name.replaceAll("-", "_"); + return "api_" + StringUtils.underscore(name); + } + + @Override + public String toOperationId(String operationId) { + String sanitizedOperationId = sanitizeName(operationId); + + if (isReservedWord(sanitizedOperationId)) { + sanitizedOperationId = "call" + StringUtils.camelize(sanitizedOperationId, false); + } + + return StringUtils.camelize(sanitizedOperationId, true); + } + + @Override + public Map postProcessOperationsWithModels(Map objs, List allModels) { + @SuppressWarnings("unchecked") + Map objectMap = (Map) objs.get("operations"); + @SuppressWarnings("unchecked") + List operations = (List) objectMap.get("operation"); + for (CodegenOperation operation : operations) { + operation.httpMethod = operation.httpMethod.toLowerCase(Locale.ROOT); + } + + return objs; + } + + @Override + public String getTypeDeclaration(Schema p) { + if (ModelUtils.isArraySchema(p)) { + ArraySchema ap = (ArraySchema) p; + Schema inner = ap.getItems(); + if (inner == null) { + return null; + } + return "seq[" + getTypeDeclaration(inner) + "]"; + } else if (ModelUtils.isMapSchema(p)) { + Schema inner = ModelUtils.getAdditionalProperties(p); + if (inner == null) { + inner = new StringSchema(); + } + return "Table[string, " + getTypeDeclaration(inner) + "]"; + } + + String schemaType = getSchemaType(p); + if (typeMapping.containsKey(schemaType)) { + return typeMapping.get(schemaType); + } + + if (schemaType.matches("\\d.*")) { // starts with number + return "`" + schemaType + "`"; + } else { + return schemaType; + } + } + + @Override + public String toVarName(String name) { + if (isReservedWord(name)) { + name = escapeReservedWord(name); + } + + if (name.matches("^\\d.*")) { + name = "`" + name + "`"; + } + + return name; + } + + @Override + public String toParamName(String name) { + return toVarName(name); + } + + @Override + protected boolean needToImport(String type) { + if (defaultIncludes.contains(type)) { + return false; + } else if (languageSpecificPrimitives.contains(type)) { + return false; + } else if (typeMapping.containsKey(type) && languageSpecificPrimitives.contains(typeMapping.get(type))) { + return false; + } + + return true; + } + + @Override + public String toEnumName(CodegenProperty property) { + String name = StringUtils.camelize(property.name, false); + + if (name.matches("\\d.*")) { // starts with number + return "`" + name + "`"; + } else { + return name; + } + } + + @Override + public String toEnumVarName(String name, String datatype) { + name = name.replace(" ", "_"); + name = StringUtils.camelize(name, false); + + if (name.matches("\\d.*")) { // starts with number + return "`" + name + "`"; + } else { + return name; + } + } +} diff --git a/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig b/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig index 2f58fc98525..912a2976301 100644 --- a/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig +++ b/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig @@ -61,6 +61,7 @@ org.openapitools.codegen.languages.JavascriptClosureAngularClientCodegen org.openapitools.codegen.languages.JMeterClientCodegen org.openapitools.codegen.languages.LuaClientCodegen org.openapitools.codegen.languages.MysqlSchemaCodegen +org.openapitools.codegen.languages.NimClientCodegen org.openapitools.codegen.languages.NodeJSServerCodegen org.openapitools.codegen.languages.NodeJSExpressServerCodegen org.openapitools.codegen.languages.ObjcClientCodegen diff --git a/modules/openapi-generator/src/main/resources/nim-client/README.mustache b/modules/openapi-generator/src/main/resources/nim-client/README.mustache new file mode 100644 index 00000000000..f879aee9e0a --- /dev/null +++ b/modules/openapi-generator/src/main/resources/nim-client/README.mustache @@ -0,0 +1,43 @@ +# Nim API client for {{{appName}}} (Package: {{{packageName}}}) + +{{#appDescription}} +{{{appDescription}}} +{{/appDescription}} + +## Overview + +This API client was generated by the [OpenAPI Generator](https://openapi-generator.tech) project. By using the [openapi-spec](https://openapis.org) from a remote server, you can easily generate an API client. + +- API version: {{{appVersion}}} +- Package version: {{{packageVersion}}} +{{^hideGenerationTimestamp}} + - Build date: {{{generatedDate}}} +{{/hideGenerationTimestamp}} +- Build package: {{{generatorClass}}} +{{#infoUrl}} + For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}}) +{{/infoUrl}} + +## Installation + +Put the package under your project folder and add the following to the nimble file of your project: + +``` +import {{{packageName}}} +``` + +## Documentation for API Endpoints + +All URIs are relative to *{{{basePath}}}* + +Module | Proc | HTTP request | Description +------------ | ------------- | ------------- | ------------- +{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}{{{classFilename}}} | {{{operationId}}} | **{{#lambda.uppercase}}{{{httpMethod}}}{{/lambda.uppercase}}** {{{path}}} | {{#summary}}{{{summary}}}{{/summary}} +{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} + +To generate documentation with Nim DocGen, use: + +``` +nim doc --project --index:on {{{packageName}}}.nim +``` + diff --git a/modules/openapi-generator/src/main/resources/nim-client/api.mustache b/modules/openapi-generator/src/main/resources/nim-client/api.mustache new file mode 100644 index 00000000000..1fcd06f7cfd --- /dev/null +++ b/modules/openapi-generator/src/main/resources/nim-client/api.mustache @@ -0,0 +1,55 @@ +{{>header}} +import httpclient +import json +import logging +import marshal +import options +import strformat +import strutils +import tables +import typetraits +import uri + +{{#imports}}import ../models/{{import}} +{{/imports}} +{{#description}}# {{{description}}}{{/description}} +const basepath = "{{{basePath}}}" + +template constructResult[T](response: Response): untyped = + if response.code in {Http200, Http201, Http202, Http204, Http206}: + try: + when name(stripGenericParams(T.typedesc).typedesc) == name(Table): + (some(json.to(parseJson(response.body), T.typedesc)), response) + else: + (some(marshal.to[T](response.body)), response) + except JsonParsingError: + # The server returned a malformed response though the response code is 2XX + # TODO: need better error handling + error("JsonParsingError") + (none(T.typedesc), response) + else: + (none(T.typedesc), response) + +{{#operations}}{{#operation}} +proc {{{operationId}}}*(httpClient: HttpClient{{#allParams}}, {{{paramName}}}: {{#isString}}string{{/isString}}{{#isUuid}}string{{/isUuid}}{{^isString}}{{^isUuid}}{{^isPrimitiveType}}{{^isContainer}}{{/isContainer}}{{/isPrimitiveType}}{{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{dataType}}}{{/datatypeWithEnum}}{{/isUuid}}{{/isString}}{{/allParams}}): {{^returnType}}Response{{/returnType}}{{#returnType}}(Option[{{{returnType}}}], Response){{/returnType}}{{#isDeprecated}} {.deprecated.}{{/isDeprecated}} = + ## {{{summary}}}{{#hasBodyParam}} + httpClient.headers["Content-Type"] = "application/json"{{/hasBodyParam}}{{#hasFormParams}}{{^isMultipart}} + httpClient.headers["Content-Type"] = "application/x-www-form-urlencoded"{{/isMultipart}}{{#isMultipart}} + httpClient.headers["Content-Type"] = "multipart/form-data"{{/isMultipart}}{{/hasFormParams}}{{#hasHeaderParams}}{{#headerParams}} + httpClient.headers["{{{baseName}}}"] = {{{paramName}}}{{#isListContainer}}.join(","){{/isListContainer}}{{/headerParams}}{{#description}} ## {{{description}}}{{/description}}{{/hasHeaderParams}}{{#hasQueryParams}} + let query_for_api_call = encodeQuery([{{#queryParams}} + ("{{{baseName}}}", ${{{paramName}}}{{#isListContainer}}.join(","){{/isListContainer}}), # {{{description}}}{{/queryParams}} + ]){{/hasQueryParams}}{{#hasFormParams}}{{^isMultipart}} + let query_for_api_call = encodeQuery([{{#formParams}} + ("{{{baseName}}}", ${{{paramName}}}{{#isListContainer}}.join(","){{/isListContainer}}), # {{{description}}}{{/formParams}} + ]){{/isMultipart}}{{#isMultipart}} + let query_for_api_call = newMultipartData({ +{{#formParams}} "{{{baseName}}}": ${{{paramName}}}{{#isListContainer}}.join(","){{/isListContainer}}, # {{{description}}} +{{/formParams}} + }){{/isMultipart}}{{/hasFormParams}}{{#returnType}} + + let response = httpClient.{{{httpMethod}}}(basepath & {{^pathParams}}"{{{path}}}"{{/pathParams}}{{#pathParams}}fmt"{{{path}}}"{{/pathParams}}{{#hasQueryParams}} & "?" & query_for_api_call{{/hasQueryParams}}{{#hasBodyParam}}{{#bodyParams}}, $(%{{{paramName}}}){{/bodyParams}}{{/hasBodyParam}}{{#hasFormParams}}, {{^isMultipart}}$query_for_api_call{{/isMultipart}}{{#isMultipart}}multipart=query_for_api_call{{/isMultipart}}{{/hasFormParams}}) + constructResult[{{{returnType}}}](response){{/returnType}}{{^returnType}} + httpClient.{{{httpMethod}}}(basepath & {{^pathParams}}"{{{path}}}"{{/pathParams}}{{#pathParams}}fmt"{{{path}}}"{{/pathParams}}{{#hasQueryParams}} & "?" & query_for_api_call{{/hasQueryParams}}{{#hasBodyParam}}{{#bodyParams}}, $(%{{{paramName}}}){{/bodyParams}}{{/hasBodyParam}}{{#hasFormParams}}, {{^isMultipart}}$query_for_api_call{{/isMultipart}}{{#isMultipart}}multipart=query_for_api_call{{/isMultipart}}{{/hasFormParams}}){{/returnType}} + +{{/operation}}{{/operations}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/nim-client/config.mustache b/modules/openapi-generator/src/main/resources/nim-client/config.mustache new file mode 100644 index 00000000000..0bc5445daa3 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/nim-client/config.mustache @@ -0,0 +1 @@ +const useragent* = "{{#httpUserAgent}}Some("{{{.}}}".to_owned()){{/httpUserAgent}}{{^httpUserAgent}}OpenAPI-Generator/{{{version}}}/nim"{{/httpUserAgent}} diff --git a/modules/openapi-generator/src/main/resources/nim-client/header.mustache b/modules/openapi-generator/src/main/resources/nim-client/header.mustache new file mode 100644 index 00000000000..6418a7495c4 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/nim-client/header.mustache @@ -0,0 +1,8 @@ +#{{#appName}} +# {{{appName}}}{{/appName}} +# {{#appDescription}} +# {{{appDescription}}}{{/appDescription}} +# {{#version}}The version of the OpenAPI document: {{{version}}}{{/version}} +# {{#infoEmail}}Contact: {{{infoEmail}}}{{/infoEmail}} +# Generated by: https://openapi-generator.tech +# diff --git a/modules/openapi-generator/src/main/resources/nim-client/lib.mustache b/modules/openapi-generator/src/main/resources/nim-client/lib.mustache new file mode 100644 index 00000000000..3876476cbf7 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/nim-client/lib.mustache @@ -0,0 +1,11 @@ +{{>header}} +# Models +{{#models}}{{#model}}import {{packageName}}/models/{{classFilename}} +{{/model}}{{/models}}{{#models}} +{{#model}}export {{classFilename}}{{/model}}{{/models}} + +# APIs +{{#apiInfo}}{{#apis}}import {{packageName}}/apis/{{classFilename}} +{{/apis}}{{/apiInfo}}{{#apiInfo}} +{{#apis}}export {{classFilename}} +{{/apis}}{{/apiInfo}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/nim-client/model.mustache b/modules/openapi-generator/src/main/resources/nim-client/model.mustache new file mode 100644 index 00000000000..9595469d3fd --- /dev/null +++ b/modules/openapi-generator/src/main/resources/nim-client/model.mustache @@ -0,0 +1,23 @@ +{{>header}} +import json +import tables + +{{#imports}}import {{import}} +{{/imports}}{{#models}}{{#model}}{{#vars}}{{#isEnum}} +type {{{enumName}}}* {.pure.} = enum{{#allowableValues}}{{#enumVars}} + {{{name}}}{{/enumVars}}{{/allowableValues}} +{{/isEnum}}{{/vars}} +type {{{classname}}}* = object + ## {{{description}}}{{#vars}} + {{{name}}}*: {{#isEnum}}{{{enumName}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{#description}} ## {{{description}}}{{/description}}{{/vars}} +{{#vars}}{{#isEnum}} +func `%`*(v: {{{enumName}}}): JsonNode = + let str = case v:{{#allowableValues}}{{#enumVars}} + of {{{enumName}}}.{{{name}}}: {{{value}}}{{/enumVars}}{{/allowableValues}} + + JsonNode(kind: JString, str: str) + +func `$`*(v: {{{enumName}}}): string = + result = case v:{{#allowableValues}}{{#enumVars}} + of {{{enumName}}}.{{{name}}}: {{{value}}}{{/enumVars}}{{/allowableValues}} +{{/isEnum}}{{/vars}}{{/model}}{{/models}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/nim-client/sample_client.mustache b/modules/openapi-generator/src/main/resources/nim-client/sample_client.mustache new file mode 100644 index 00000000000..9504d5c0db6 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/nim-client/sample_client.mustache @@ -0,0 +1,14 @@ +{{>header}} +import httpclient +import logging +import options + +import {{{packageName}}} + +import config + +let logger = newConsoleLogger() +addHandler(logger) + +let client = newHttpClient() +client.headers["User-Agent"] = config.useragent diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/nim/NimClientCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/nim/NimClientCodegenTest.java new file mode 100644 index 00000000000..ea0ab8297b7 --- /dev/null +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/nim/NimClientCodegenTest.java @@ -0,0 +1,38 @@ +package org.openapitools.codegen.nim; + +import org.openapitools.codegen.*; +import org.openapitools.codegen.languages.NimClientCodegen; +import org.testng.Assert; +import org.testng.annotations.Test; + +public class NimClientCodegenTest { + + @Test + public void testInitialConfigValues() throws Exception { + final NimClientCodegen codegen = new NimClientCodegen(); + codegen.processOpts(); + + Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.HIDE_GENERATION_TIMESTAMP), Boolean.TRUE); + Assert.assertEquals(codegen.isHideGenerationTimestamp(), true); + } + + @Test + public void testSettersForConfigValues() throws Exception { + final NimClientCodegen codegen = new NimClientCodegen(); + codegen.setHideGenerationTimestamp(false); + codegen.processOpts(); + + Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.HIDE_GENERATION_TIMESTAMP), Boolean.FALSE); + Assert.assertEquals(codegen.isHideGenerationTimestamp(), false); + } + + @Test + public void testAdditionalPropertiesPutForConfigValues() throws Exception { + final NimClientCodegen codegen = new NimClientCodegen(); + codegen.additionalProperties().put(CodegenConstants.HIDE_GENERATION_TIMESTAMP, false); + codegen.processOpts(); + + Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.HIDE_GENERATION_TIMESTAMP), Boolean.FALSE); + Assert.assertEquals(codegen.isHideGenerationTimestamp(), false); + } +} diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/NimClientCodegenOptionsProvider.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/NimClientCodegenOptionsProvider.java new file mode 100644 index 00000000000..24cad9416a5 --- /dev/null +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/NimClientCodegenOptionsProvider.java @@ -0,0 +1,31 @@ +package org.openapitools.codegen.options; + +import org.openapitools.codegen.CodegenConstants; +import org.openapitools.codegen.languages.NimClientCodegen; + +import com.google.common.collect.ImmutableMap; + +import java.util.Map; + +public class NimClientCodegenOptionsProvider implements OptionsProvider { + public static final String PROJECT_NAME_VALUE = "OpenAPI"; + + @Override + public String getLanguage() { + return "nim"; + } + + @Override + public Map createOptions() { + ImmutableMap.Builder builder = new ImmutableMap.Builder(); + return builder + .put(NimClientCodegen.PROJECT_NAME, PROJECT_NAME_VALUE) + .build(); + } + + @Override + public boolean isServer() { + return false; + } +} + diff --git a/samples/client/petstore/nim/.openapi-generator-ignore b/samples/client/petstore/nim/.openapi-generator-ignore new file mode 100644 index 00000000000..7484ee590a3 --- /dev/null +++ b/samples/client/petstore/nim/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/client/petstore/nim/.openapi-generator/VERSION b/samples/client/petstore/nim/.openapi-generator/VERSION new file mode 100644 index 00000000000..0e97bd19efb --- /dev/null +++ b/samples/client/petstore/nim/.openapi-generator/VERSION @@ -0,0 +1 @@ +4.1.3-SNAPSHOT \ No newline at end of file diff --git a/samples/client/petstore/nim/README.md b/samples/client/petstore/nim/README.md new file mode 100644 index 00000000000..11a5499e00e --- /dev/null +++ b/samples/client/petstore/nim/README.md @@ -0,0 +1,54 @@ +# Nim API client for OpenAPI Petstore (Package: petstore) + +This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. + +## Overview + +This API client was generated by the [OpenAPI Generator](https://openapi-generator.tech) project. By using the [openapi-spec](https://openapis.org) from a remote server, you can easily generate an API client. + +- API version: 1.0.0 +- Package version: 1.0.0 +- Build package: org.openapitools.codegen.languages.NimClientCodegen + +## Installation + +Put the package under your project folder and add the following to the nimble file of your project: + +``` +import petstore +``` + +## Documentation for API Endpoints + +All URIs are relative to *http://petstore.swagger.io/v2* + +Module | Proc | HTTP request | Description +------------ | ------------- | ------------- | ------------- +api_pet | addPet | **POST** /pet | Add a new pet to the store +api_pet | deletePet | **DELETE** /pet/{petId} | Deletes a pet +api_pet | findPetsByStatus | **GET** /pet/findByStatus | Finds Pets by status +api_pet | findPetsByTags | **GET** /pet/findByTags | Finds Pets by tags +api_pet | getPetById | **GET** /pet/{petId} | Find pet by ID +api_pet | updatePet | **PUT** /pet | Update an existing pet +api_pet | updatePetWithForm | **POST** /pet/{petId} | Updates a pet in the store with form data +api_pet | uploadFile | **POST** /pet/{petId}/uploadImage | uploads an image +api_store | deleteOrder | **DELETE** /store/order/{orderId} | Delete purchase order by ID +api_store | getInventory | **GET** /store/inventory | Returns pet inventories by status +api_store | getOrderById | **GET** /store/order/{orderId} | Find purchase order by ID +api_store | placeOrder | **POST** /store/order | Place an order for a pet +api_user | createUser | **POST** /user | Create user +api_user | createUsersWithArrayInput | **POST** /user/createWithArray | Creates list of users with given input array +api_user | createUsersWithListInput | **POST** /user/createWithList | Creates list of users with given input array +api_user | deleteUser | **DELETE** /user/{username} | Delete user +api_user | getUserByName | **GET** /user/{username} | Get user by user name +api_user | loginUser | **GET** /user/login | Logs user into the system +api_user | logoutUser | **GET** /user/logout | Logs out current logged in user session +api_user | updateUser | **PUT** /user/{username} | Updated user + + +To generate documentation with Nim DocGen, use: + +``` +nim doc --project --index:on petstore.nim +``` + diff --git a/samples/client/petstore/nim/config.nim b/samples/client/petstore/nim/config.nim new file mode 100644 index 00000000000..a0790844b38 --- /dev/null +++ b/samples/client/petstore/nim/config.nim @@ -0,0 +1 @@ +const useragent* = "OpenAPI-Generator/1.0.0/nim" diff --git a/samples/client/petstore/nim/petstore.nim b/samples/client/petstore/nim/petstore.nim new file mode 100644 index 00000000000..21f854f172b --- /dev/null +++ b/samples/client/petstore/nim/petstore.nim @@ -0,0 +1,32 @@ +# +# OpenAPI Petstore +# +# This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. +# The version of the OpenAPI document: 1.0.0 +# +# Generated by: https://openapi-generator.tech +# + +# Models +import petstore/models/model_api_response +import petstore/models/model_category +import petstore/models/model_order +import petstore/models/model_pet +import petstore/models/model_tag +import petstore/models/model_user + +export model_api_response +export model_category +export model_order +export model_pet +export model_tag +export model_user + +# APIs +import petstore/apis/api_pet +import petstore/apis/api_store +import petstore/apis/api_user + +export api_pet +export api_store +export api_user diff --git a/samples/client/petstore/nim/petstore/apis/api_pet.nim b/samples/client/petstore/nim/petstore/apis/api_pet.nim new file mode 100644 index 00000000000..9858c523647 --- /dev/null +++ b/samples/client/petstore/nim/petstore/apis/api_pet.nim @@ -0,0 +1,107 @@ +# +# OpenAPI Petstore +# +# This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. +# The version of the OpenAPI document: 1.0.0 +# +# Generated by: https://openapi-generator.tech +# + +import httpclient +import json +import logging +import marshal +import options +import strformat +import strutils +import tables +import typetraits +import uri + +import ../models/model_api_response +import ../models/model_pet + +const basepath = "http://petstore.swagger.io/v2" + +template constructResult[T](response: Response): untyped = + if response.code in {Http200, Http201, Http202, Http204, Http206}: + try: + when name(stripGenericParams(T.typedesc).typedesc) == name(Table): + (some(json.to(parseJson(response.body), T.typedesc)), response) + else: + (some(marshal.to[T](response.body)), response) + except JsonParsingError: + # The server returned a malformed response though the response code is 2XX + # TODO: need better error handling + error("JsonParsingError") + (none(T.typedesc), response) + else: + (none(T.typedesc), response) + + +proc addPet*(httpClient: HttpClient, body: Pet): Response = + ## Add a new pet to the store + httpClient.headers["Content-Type"] = "application/json" + httpClient.post(basepath & "/pet", $(%body)) + + +proc deletePet*(httpClient: HttpClient, petId: int64, api_key: string): Response = + ## Deletes a pet + httpClient.headers["api_key"] = api_key + httpClient.delete(basepath & fmt"/pet/{petId}") + + +proc findPetsByStatus*(httpClient: HttpClient, status: seq[Status]): (Option[seq[Pet]], Response) = + ## Finds Pets by status + let query_for_api_call = encodeQuery([ + ("status", $status.join(",")), # Status values that need to be considered for filter + ]) + + let response = httpClient.get(basepath & "/pet/findByStatus" & "?" & query_for_api_call) + constructResult[seq[Pet]](response) + + +proc findPetsByTags*(httpClient: HttpClient, tags: seq[string]): (Option[seq[Pet]], Response) {.deprecated.} = + ## Finds Pets by tags + let query_for_api_call = encodeQuery([ + ("tags", $tags.join(",")), # Tags to filter by + ]) + + let response = httpClient.get(basepath & "/pet/findByTags" & "?" & query_for_api_call) + constructResult[seq[Pet]](response) + + +proc getPetById*(httpClient: HttpClient, petId: int64): (Option[Pet], Response) = + ## Find pet by ID + + let response = httpClient.get(basepath & fmt"/pet/{petId}") + constructResult[Pet](response) + + +proc updatePet*(httpClient: HttpClient, body: Pet): Response = + ## Update an existing pet + httpClient.headers["Content-Type"] = "application/json" + httpClient.put(basepath & "/pet", $(%body)) + + +proc updatePetWithForm*(httpClient: HttpClient, petId: int64, name: string, status: string): Response = + ## Updates a pet in the store with form data + httpClient.headers["Content-Type"] = "application/x-www-form-urlencoded" + let query_for_api_call = encodeQuery([ + ("name", $name), # Updated name of the pet + ("status", $status), # Updated status of the pet + ]) + httpClient.post(basepath & fmt"/pet/{petId}", $query_for_api_call) + + +proc uploadFile*(httpClient: HttpClient, petId: int64, additionalMetadata: string, file: string): (Option[ApiResponse], Response) = + ## uploads an image + httpClient.headers["Content-Type"] = "multipart/form-data" + let query_for_api_call = newMultipartData({ + "additionalMetadata": $additionalMetadata, # Additional data to pass to server + "file": $file, # file to upload + }) + + let response = httpClient.post(basepath & fmt"/pet/{petId}/uploadImage", multipart=query_for_api_call) + constructResult[ApiResponse](response) + diff --git a/samples/client/petstore/nim/petstore/apis/api_store.nim b/samples/client/petstore/nim/petstore/apis/api_store.nim new file mode 100644 index 00000000000..3c518e8dd31 --- /dev/null +++ b/samples/client/petstore/nim/petstore/apis/api_store.nim @@ -0,0 +1,66 @@ +# +# OpenAPI Petstore +# +# This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. +# The version of the OpenAPI document: 1.0.0 +# +# Generated by: https://openapi-generator.tech +# + +import httpclient +import json +import logging +import marshal +import options +import strformat +import strutils +import tables +import typetraits +import uri + +import ../models/model_order + +const basepath = "http://petstore.swagger.io/v2" + +template constructResult[T](response: Response): untyped = + if response.code in {Http200, Http201, Http202, Http204, Http206}: + try: + when name(stripGenericParams(T.typedesc).typedesc) == name(Table): + (some(json.to(parseJson(response.body), T.typedesc)), response) + else: + (some(marshal.to[T](response.body)), response) + except JsonParsingError: + # The server returned a malformed response though the response code is 2XX + # TODO: need better error handling + error("JsonParsingError") + (none(T.typedesc), response) + else: + (none(T.typedesc), response) + + +proc deleteOrder*(httpClient: HttpClient, orderId: string): Response = + ## Delete purchase order by ID + httpClient.delete(basepath & fmt"/store/order/{orderId}") + + +proc getInventory*(httpClient: HttpClient): (Option[Table[string, int]], Response) = + ## Returns pet inventories by status + + let response = httpClient.get(basepath & "/store/inventory") + constructResult[Table[string, int]](response) + + +proc getOrderById*(httpClient: HttpClient, orderId: int64): (Option[Order], Response) = + ## Find purchase order by ID + + let response = httpClient.get(basepath & fmt"/store/order/{orderId}") + constructResult[Order](response) + + +proc placeOrder*(httpClient: HttpClient, body: Order): (Option[Order], Response) = + ## Place an order for a pet + httpClient.headers["Content-Type"] = "application/json" + + let response = httpClient.post(basepath & "/store/order", $(%body)) + constructResult[Order](response) + diff --git a/samples/client/petstore/nim/petstore/apis/api_user.nim b/samples/client/petstore/nim/petstore/apis/api_user.nim new file mode 100644 index 00000000000..87bef06818e --- /dev/null +++ b/samples/client/petstore/nim/petstore/apis/api_user.nim @@ -0,0 +1,91 @@ +# +# OpenAPI Petstore +# +# This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. +# The version of the OpenAPI document: 1.0.0 +# +# Generated by: https://openapi-generator.tech +# + +import httpclient +import json +import logging +import marshal +import options +import strformat +import strutils +import tables +import typetraits +import uri + +import ../models/model_user + +const basepath = "http://petstore.swagger.io/v2" + +template constructResult[T](response: Response): untyped = + if response.code in {Http200, Http201, Http202, Http204, Http206}: + try: + when name(stripGenericParams(T.typedesc).typedesc) == name(Table): + (some(json.to(parseJson(response.body), T.typedesc)), response) + else: + (some(marshal.to[T](response.body)), response) + except JsonParsingError: + # The server returned a malformed response though the response code is 2XX + # TODO: need better error handling + error("JsonParsingError") + (none(T.typedesc), response) + else: + (none(T.typedesc), response) + + +proc createUser*(httpClient: HttpClient, body: User): Response = + ## Create user + httpClient.headers["Content-Type"] = "application/json" + httpClient.post(basepath & "/user", $(%body)) + + +proc createUsersWithArrayInput*(httpClient: HttpClient, body: seq[User]): Response = + ## Creates list of users with given input array + httpClient.headers["Content-Type"] = "application/json" + httpClient.post(basepath & "/user/createWithArray", $(%body)) + + +proc createUsersWithListInput*(httpClient: HttpClient, body: seq[User]): Response = + ## Creates list of users with given input array + httpClient.headers["Content-Type"] = "application/json" + httpClient.post(basepath & "/user/createWithList", $(%body)) + + +proc deleteUser*(httpClient: HttpClient, username: string): Response = + ## Delete user + httpClient.delete(basepath & fmt"/user/{username}") + + +proc getUserByName*(httpClient: HttpClient, username: string): (Option[User], Response) = + ## Get user by user name + + let response = httpClient.get(basepath & fmt"/user/{username}") + constructResult[User](response) + + +proc loginUser*(httpClient: HttpClient, username: string, password: string): (Option[string], Response) = + ## Logs user into the system + let query_for_api_call = encodeQuery([ + ("username", $username), # The user name for login + ("password", $password), # The password for login in clear text + ]) + + let response = httpClient.get(basepath & "/user/login" & "?" & query_for_api_call) + constructResult[string](response) + + +proc logoutUser*(httpClient: HttpClient): Response = + ## Logs out current logged in user session + httpClient.get(basepath & "/user/logout") + + +proc updateUser*(httpClient: HttpClient, username: string, body: User): Response = + ## Updated user + httpClient.headers["Content-Type"] = "application/json" + httpClient.put(basepath & fmt"/user/{username}", $(%body)) + diff --git a/samples/client/petstore/nim/petstore/models/model_api_response.nim b/samples/client/petstore/nim/petstore/models/model_api_response.nim new file mode 100644 index 00000000000..78f22e081ca --- /dev/null +++ b/samples/client/petstore/nim/petstore/models/model_api_response.nim @@ -0,0 +1,18 @@ +# +# OpenAPI Petstore +# +# This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. +# The version of the OpenAPI document: 1.0.0 +# +# Generated by: https://openapi-generator.tech +# + +import json +import tables + + +type ApiResponse* = object + ## Describes the result of uploading an image resource + code*: int + `type`*: string + message*: string diff --git a/samples/client/petstore/nim/petstore/models/model_category.nim b/samples/client/petstore/nim/petstore/models/model_category.nim new file mode 100644 index 00000000000..a1331c1ef41 --- /dev/null +++ b/samples/client/petstore/nim/petstore/models/model_category.nim @@ -0,0 +1,17 @@ +# +# OpenAPI Petstore +# +# This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. +# The version of the OpenAPI document: 1.0.0 +# +# Generated by: https://openapi-generator.tech +# + +import json +import tables + + +type Category* = object + ## A category for a pet + id*: int64 + name*: string diff --git a/samples/client/petstore/nim/petstore/models/model_order.nim b/samples/client/petstore/nim/petstore/models/model_order.nim new file mode 100644 index 00000000000..e2bb9e9cd7c --- /dev/null +++ b/samples/client/petstore/nim/petstore/models/model_order.nim @@ -0,0 +1,40 @@ +# +# OpenAPI Petstore +# +# This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. +# The version of the OpenAPI document: 1.0.0 +# +# Generated by: https://openapi-generator.tech +# + +import json +import tables + + +type Status* {.pure.} = enum + Placed + Approved + Delivered + +type Order* = object + ## An order for a pets from the pet store + id*: int64 + petId*: int64 + quantity*: int + shipDate*: string + status*: Status ## Order Status + complete*: bool + +func `%`*(v: Status): JsonNode = + let str = case v: + of Status.Placed: "placed" + of Status.Approved: "approved" + of Status.Delivered: "delivered" + + JsonNode(kind: JString, str: str) + +func `$`*(v: Status): string = + result = case v: + of Status.Placed: "placed" + of Status.Approved: "approved" + of Status.Delivered: "delivered" diff --git a/samples/client/petstore/nim/petstore/models/model_pet.nim b/samples/client/petstore/nim/petstore/models/model_pet.nim new file mode 100644 index 00000000000..c2431a743c6 --- /dev/null +++ b/samples/client/petstore/nim/petstore/models/model_pet.nim @@ -0,0 +1,42 @@ +# +# OpenAPI Petstore +# +# This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. +# The version of the OpenAPI document: 1.0.0 +# +# Generated by: https://openapi-generator.tech +# + +import json +import tables + +import model_category +import model_tag + +type Status* {.pure.} = enum + Available + Pending + Sold + +type Pet* = object + ## A pet for sale in the pet store + id*: int64 + category*: Category + name*: string + photoUrls*: seq[string] + tags*: seq[Tag] + status*: Status ## pet status in the store + +func `%`*(v: Status): JsonNode = + let str = case v: + of Status.Available: "available" + of Status.Pending: "pending" + of Status.Sold: "sold" + + JsonNode(kind: JString, str: str) + +func `$`*(v: Status): string = + result = case v: + of Status.Available: "available" + of Status.Pending: "pending" + of Status.Sold: "sold" diff --git a/samples/client/petstore/nim/petstore/models/model_tag.nim b/samples/client/petstore/nim/petstore/models/model_tag.nim new file mode 100644 index 00000000000..28f518d6b6c --- /dev/null +++ b/samples/client/petstore/nim/petstore/models/model_tag.nim @@ -0,0 +1,17 @@ +# +# OpenAPI Petstore +# +# This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. +# The version of the OpenAPI document: 1.0.0 +# +# Generated by: https://openapi-generator.tech +# + +import json +import tables + + +type Tag* = object + ## A tag for a pet + id*: int64 + name*: string diff --git a/samples/client/petstore/nim/petstore/models/model_user.nim b/samples/client/petstore/nim/petstore/models/model_user.nim new file mode 100644 index 00000000000..e487793080e --- /dev/null +++ b/samples/client/petstore/nim/petstore/models/model_user.nim @@ -0,0 +1,23 @@ +# +# OpenAPI Petstore +# +# This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. +# The version of the OpenAPI document: 1.0.0 +# +# Generated by: https://openapi-generator.tech +# + +import json +import tables + + +type User* = object + ## A User who is purchasing from the pet store + id*: int64 + username*: string + firstName*: string + lastName*: string + email*: string + password*: string + phone*: string + userStatus*: int ## User Status diff --git a/samples/client/petstore/nim/sample_client.nim b/samples/client/petstore/nim/sample_client.nim new file mode 100644 index 00000000000..6340c902e6e --- /dev/null +++ b/samples/client/petstore/nim/sample_client.nim @@ -0,0 +1,22 @@ +# +# OpenAPI Petstore +# +# This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. +# The version of the OpenAPI document: 1.0.0 +# +# Generated by: https://openapi-generator.tech +# + +import httpclient +import logging +import options + +import petstore + +import config + +let logger = newConsoleLogger() +addHandler(logger) + +let client = newHttpClient() +client.headers["User-Agent"] = config.useragent