forked from loafle/openapi-generator-original
Scala Cask oneOf support (#20051)
* added support for 'oneOf' types represented as unions also updated libs and an 'errors' field rename to address name clashes with likely/popular field names * Created cask-specific petstore example which Includes a oneOf and allOf example
This commit is contained in:
parent
bfcfc6ff25
commit
6792218775
@ -1,6 +1,6 @@
|
|||||||
generatorName: scala-cask
|
generatorName: scala-cask
|
||||||
outputDir: samples/server/petstore/scala-cask
|
outputDir: samples/server/petstore/scala-cask
|
||||||
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
|
inputSpec: modules/openapi-generator/src/test/resources/3_0/scala-cask/petstore.yaml
|
||||||
templateDir: modules/openapi-generator/src/main/resources/scala-cask
|
templateDir: modules/openapi-generator/src/main/resources/scala-cask
|
||||||
additionalProperties:
|
additionalProperties:
|
||||||
hideGenerationTimestamp: "true"
|
hideGenerationTimestamp: "true"
|
||||||
|
@ -18,6 +18,7 @@ package org.openapitools.codegen.languages;
|
|||||||
|
|
||||||
import io.swagger.v3.oas.models.OpenAPI;
|
import io.swagger.v3.oas.models.OpenAPI;
|
||||||
import io.swagger.v3.oas.models.media.Schema;
|
import io.swagger.v3.oas.models.media.Schema;
|
||||||
|
import io.swagger.v3.oas.models.parameters.RequestBody;
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.openapitools.codegen.*;
|
import org.openapitools.codegen.*;
|
||||||
import org.openapitools.codegen.model.ModelMap;
|
import org.openapitools.codegen.model.ModelMap;
|
||||||
@ -394,6 +395,12 @@ public class ScalaCaskServerCodegen extends AbstractScalaCodegen implements Code
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is used in pathExtractorParams.mustache.
|
||||||
|
*
|
||||||
|
* It exposes some methods which make it more readable
|
||||||
|
* for that mustache snippet, and also isolates the logic needed for the path extractors
|
||||||
|
*/
|
||||||
public static class ParamPart {
|
public static class ParamPart {
|
||||||
final CodegenParameter param;
|
final CodegenParameter param;
|
||||||
final String name;
|
final String name;
|
||||||
@ -416,7 +423,9 @@ public class ScalaCaskServerCodegen extends AbstractScalaCodegen implements Code
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cask will compile but 'initialize' can throw a route overlap exception:
|
* This data structure is here to manually identify and fix routes which will overlap (e.g. GET /foo/bar and GET /foo/bazz)
|
||||||
|
*
|
||||||
|
* If we added these as individual routes, then Cask itself will compile, but calling 'initialize' throws a route overlap exception:
|
||||||
* <p>
|
* <p>
|
||||||
* {{{
|
* {{{
|
||||||
* Routes overlap with wildcards: get /user/logout, get /user/:username, get /user/login
|
* Routes overlap with wildcards: get /user/logout, get /user/:username, get /user/login
|
||||||
@ -672,9 +681,12 @@ public class ScalaCaskServerCodegen extends AbstractScalaCodegen implements Code
|
|||||||
|
|
||||||
model.getVars().forEach(this::postProcessProperty);
|
model.getVars().forEach(this::postProcessProperty);
|
||||||
model.getAllVars().forEach(this::postProcessProperty);
|
model.getAllVars().forEach(this::postProcessProperty);
|
||||||
|
|
||||||
|
|
||||||
|
model.vendorExtensions.put("x-has-one-of", model.oneOf != null && !model.oneOf.isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void postProcessOperation(CodegenOperation op) {
|
private static void postProcessOperation(final CodegenOperation op) {
|
||||||
// force http method to lower case
|
// force http method to lower case
|
||||||
op.httpMethod = op.httpMethod.toLowerCase(Locale.ROOT);
|
op.httpMethod = op.httpMethod.toLowerCase(Locale.ROOT);
|
||||||
|
|
||||||
@ -710,9 +722,33 @@ public class ScalaCaskServerCodegen extends AbstractScalaCodegen implements Code
|
|||||||
.collect(Collectors.toCollection(LinkedHashSet::new));
|
.collect(Collectors.toCollection(LinkedHashSet::new));
|
||||||
|
|
||||||
var responseType = responses.isEmpty() ? "Unit" : String.join(" | ", responses);
|
var responseType = responses.isEmpty() ? "Unit" : String.join(" | ", responses);
|
||||||
|
op.vendorExtensions.put("x-import-response-implicits", importResponseImplicits(op));
|
||||||
op.vendorExtensions.put("x-response-type", responseType);
|
op.vendorExtensions.put("x-response-type", responseType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We need to bring the response type into scope in order to use the upickle implicits
|
||||||
|
* only if the response type has a 'oneOf' type, which means it's a union type with a
|
||||||
|
* companion object containing the ReadWriter
|
||||||
|
*
|
||||||
|
* @param op
|
||||||
|
* @return true if we need to provide an import
|
||||||
|
*/
|
||||||
|
private static boolean importResponseImplicits(final CodegenOperation op) {
|
||||||
|
final Set<String> importBlacklist = Set.of("File");
|
||||||
|
|
||||||
|
boolean doImport = false;
|
||||||
|
for (var response : op.responses) {
|
||||||
|
// we should ignore generic types like Seq[...] or Map[..] types
|
||||||
|
var isPolymorphic = response.dataType != null && response.dataType.contains("[");
|
||||||
|
if (response.isModel && !importBlacklist.contains(response.dataType) && !isPolymorphic) {
|
||||||
|
doImport = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return doImport;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* primitive or enum types don't have Data representations
|
* primitive or enum types don't have Data representations
|
||||||
* @param p the property
|
* @param p the property
|
||||||
@ -747,6 +783,10 @@ public class ScalaCaskServerCodegen extends AbstractScalaCodegen implements Code
|
|||||||
return "byte".equalsIgnoreCase(p.dataFormat); // &&
|
return "byte".equalsIgnoreCase(p.dataFormat); // &&
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean wrapInOptional(CodegenProperty p) {
|
||||||
|
return !p.required && !p.isArray && !p.isMap;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* this parameter is used to create the function:
|
* this parameter is used to create the function:
|
||||||
* {{{
|
* {{{
|
||||||
@ -761,19 +801,18 @@ public class ScalaCaskServerCodegen extends AbstractScalaCodegen implements Code
|
|||||||
* and then back again
|
* and then back again
|
||||||
*/
|
*/
|
||||||
private static String asDataCode(final CodegenProperty p, final Set<String> typesWhichDoNotNeedMapping) {
|
private static String asDataCode(final CodegenProperty p, final Set<String> typesWhichDoNotNeedMapping) {
|
||||||
final var wrapInOptional = !p.required && !p.isArray && !p.isMap;
|
|
||||||
String code = "";
|
String code = "";
|
||||||
|
|
||||||
String dv = defaultValueNonOption(p, p.defaultValue);
|
String dv = defaultValueNonOption(p, p.defaultValue);
|
||||||
|
|
||||||
if (doesNotNeedMapping(p, typesWhichDoNotNeedMapping)) {
|
if (doesNotNeedMapping(p, typesWhichDoNotNeedMapping)) {
|
||||||
if (wrapInOptional) {
|
if (wrapInOptional(p)) {
|
||||||
code = String.format(Locale.ROOT, "%s.getOrElse(%s) /* 1 */", p.name, dv);
|
code = String.format(Locale.ROOT, "%s.getOrElse(%s) /* 1 */", p.name, dv);
|
||||||
} else {
|
} else {
|
||||||
code = String.format(Locale.ROOT, "%s /* 2 */", p.name);
|
code = String.format(Locale.ROOT, "%s /* 2 */", p.name);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (wrapInOptional) {
|
if (wrapInOptional(p)) {
|
||||||
if (isByteArray(p)) {
|
if (isByteArray(p)) {
|
||||||
code = String.format(Locale.ROOT, "%s.getOrElse(%s) /* 3 */", p.name, dv);
|
code = String.format(Locale.ROOT, "%s.getOrElse(%s) /* 3 */", p.name, dv);
|
||||||
} else {
|
} else {
|
||||||
@ -782,11 +821,15 @@ public class ScalaCaskServerCodegen extends AbstractScalaCodegen implements Code
|
|||||||
} else if (p.isArray) {
|
} else if (p.isArray) {
|
||||||
if (isByteArray(p)) {
|
if (isByteArray(p)) {
|
||||||
code = String.format(Locale.ROOT, "%s /* 5 */", p.name);
|
code = String.format(Locale.ROOT, "%s /* 5 */", p.name);
|
||||||
|
} else if (!isObjectArray(p)) {
|
||||||
|
code = String.format(Locale.ROOT, "%s /* 5.1 */", p.name);
|
||||||
} else {
|
} else {
|
||||||
code = String.format(Locale.ROOT, "%s.map(_.asData) /* 6 */", p.name);
|
code = String.format(Locale.ROOT, "%s.map(_.asData) /* 6 */", p.name);
|
||||||
}
|
}
|
||||||
|
} else if (p.isMap) {
|
||||||
|
code = String.format(Locale.ROOT, "%s /* 7 */", p.name);
|
||||||
} else {
|
} else {
|
||||||
code = String.format(Locale.ROOT, "%s.asData /* 7 */", p.name);
|
code = String.format(Locale.ROOT, "%s.asData /* 8 */", p.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return code;
|
return code;
|
||||||
@ -807,17 +850,16 @@ public class ScalaCaskServerCodegen extends AbstractScalaCodegen implements Code
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private static String asModelCode(final CodegenProperty p, final Set<String> typesWhichDoNotNeedMapping) {
|
private static String asModelCode(final CodegenProperty p, final Set<String> typesWhichDoNotNeedMapping) {
|
||||||
final var wrapInOptional = !p.required && !p.isArray && !p.isMap;
|
|
||||||
String code = "";
|
String code = "";
|
||||||
|
|
||||||
if (doesNotNeedMapping(p, typesWhichDoNotNeedMapping)) {
|
if (doesNotNeedMapping(p, typesWhichDoNotNeedMapping)) {
|
||||||
if (wrapInOptional) {
|
if (wrapInOptional(p)) {
|
||||||
code = String.format(Locale.ROOT, "Option(%s) /* 1 */", p.name);
|
code = String.format(Locale.ROOT, "Option(%s) /* 1 */", p.name);
|
||||||
} else {
|
} else {
|
||||||
code = String.format(Locale.ROOT, "%s /* 2 */", p.name);
|
code = String.format(Locale.ROOT, "%s /* 2 */", p.name);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (wrapInOptional) {
|
if (wrapInOptional(p)) {
|
||||||
if (isByteArray(p)) {
|
if (isByteArray(p)) {
|
||||||
code = String.format(Locale.ROOT, "Option(%s) /* 3 */", p.name);
|
code = String.format(Locale.ROOT, "Option(%s) /* 3 */", p.name);
|
||||||
} else {
|
} else {
|
||||||
@ -825,6 +867,8 @@ public class ScalaCaskServerCodegen extends AbstractScalaCodegen implements Code
|
|||||||
}
|
}
|
||||||
} else if (p.isArray) {
|
} else if (p.isArray) {
|
||||||
code = String.format(Locale.ROOT, "%s.map(_.asModel) /* 5 */", p.name);
|
code = String.format(Locale.ROOT, "%s.map(_.asModel) /* 5 */", p.name);
|
||||||
|
} else if (p.isMap) {
|
||||||
|
code = String.format(Locale.ROOT, "%s /* 5.1 */", p.name);
|
||||||
} else {
|
} else {
|
||||||
code = String.format(Locale.ROOT, "%s.asModel /* 6 */", p.name);
|
code = String.format(Locale.ROOT, "%s.asModel /* 6 */", p.name);
|
||||||
}
|
}
|
||||||
@ -863,8 +907,17 @@ public class ScalaCaskServerCodegen extends AbstractScalaCodegen implements Code
|
|||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean hasItemModel(final CodegenProperty p) {
|
||||||
|
return p.items != null && p.items.isModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isObjectArray(final CodegenProperty p) {
|
||||||
|
return p.isArray && hasItemModel(p);
|
||||||
|
}
|
||||||
|
|
||||||
private void postProcessProperty(final CodegenProperty p) {
|
private void postProcessProperty(final CodegenProperty p) {
|
||||||
p.vendorExtensions.put("x-datatype-model", asScalaDataType(p, p.required, false));
|
|
||||||
|
p.vendorExtensions.put("x-datatype-model", asScalaDataType(p, p.required, false, wrapInOptional(p)));
|
||||||
p.vendorExtensions.put("x-defaultValue-model", defaultValue(p, p.required, p.defaultValue));
|
p.vendorExtensions.put("x-defaultValue-model", defaultValue(p, p.required, p.defaultValue));
|
||||||
final String dataTypeData = asScalaDataType(p, p.required, true);
|
final String dataTypeData = asScalaDataType(p, p.required, true);
|
||||||
p.vendorExtensions.put("x-datatype-data", dataTypeData);
|
p.vendorExtensions.put("x-datatype-data", dataTypeData);
|
||||||
@ -878,7 +931,7 @@ public class ScalaCaskServerCodegen extends AbstractScalaCodegen implements Code
|
|||||||
p._enum = p._enum.stream().map(this::ensureNonKeyword).collect(Collectors.toList());
|
p._enum = p._enum.stream().map(this::ensureNonKeyword).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* This is a fix for the enum property "type" declared like this:
|
* This is a fix for the enum property "type" declared like this:
|
||||||
* {{{
|
* {{{
|
||||||
* type:
|
* type:
|
||||||
@ -908,6 +961,9 @@ public class ScalaCaskServerCodegen extends AbstractScalaCodegen implements Code
|
|||||||
)).collect(Collectors.toSet());
|
)).collect(Collectors.toSet());
|
||||||
typesWhichShouldNotBeMapped.add("byte");
|
typesWhichShouldNotBeMapped.add("byte");
|
||||||
|
|
||||||
|
// when deserialising map objects, the logic is tricky.
|
||||||
|
p.vendorExtensions.put("x-deserialize-asModelMap", p.isMap && hasItemModel(p));
|
||||||
|
|
||||||
// the 'asModel' logic for modelData.mustache
|
// the 'asModel' logic for modelData.mustache
|
||||||
//
|
//
|
||||||
// if it's optional (not required), then wrap the value in Option()
|
// if it's optional (not required), then wrap the value in Option()
|
||||||
@ -916,16 +972,6 @@ public class ScalaCaskServerCodegen extends AbstractScalaCodegen implements Code
|
|||||||
p.vendorExtensions.put("x-asData", asDataCode(p, typesWhichShouldNotBeMapped));
|
p.vendorExtensions.put("x-asData", asDataCode(p, typesWhichShouldNotBeMapped));
|
||||||
p.vendorExtensions.put("x-asModel", asModelCode(p, typesWhichShouldNotBeMapped));
|
p.vendorExtensions.put("x-asModel", asModelCode(p, typesWhichShouldNotBeMapped));
|
||||||
|
|
||||||
// if it's an array or optional, we need to map it as a model -- unless it's a map,
|
|
||||||
// in which case we have to map the values
|
|
||||||
boolean hasItemModel = p.items != null && p.items.isModel;
|
|
||||||
boolean isObjectArray = p.isArray && hasItemModel;
|
|
||||||
boolean isOptionalObj = !p.required && p.isModel;
|
|
||||||
p.vendorExtensions.put("x-map-asModel", (isOptionalObj || isObjectArray) && !p.isMap);
|
|
||||||
|
|
||||||
// when deserialising map objects, the logic is tricky.
|
|
||||||
p.vendorExtensions.put("x-deserialize-asModelMap", p.isMap && hasItemModel);
|
|
||||||
|
|
||||||
// for some reason, an openapi spec with pattern field like this:
|
// for some reason, an openapi spec with pattern field like this:
|
||||||
// pattern: '^[A-Za-z]+$'
|
// pattern: '^[A-Za-z]+$'
|
||||||
// will result in the pattern property text of
|
// will result in the pattern property text of
|
||||||
@ -934,6 +980,20 @@ public class ScalaCaskServerCodegen extends AbstractScalaCodegen implements Code
|
|||||||
p.pattern = p.pattern.substring(1, p.pattern.length() - 1);
|
p.pattern = p.pattern.substring(1, p.pattern.length() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// in our model class definition laid out in modelClass.mustache, we use 'Option' for non-required
|
||||||
|
// properties only when they don't have a sensible 'empty' value (e.g. maps and lists).
|
||||||
|
//
|
||||||
|
// that is to say, we're trying to avoid having:
|
||||||
|
//
|
||||||
|
// someOptionalField : Option[Seq[Foo]]
|
||||||
|
//
|
||||||
|
// when we could just have e.g.
|
||||||
|
//
|
||||||
|
// someOptionalField : Seq[Foo]
|
||||||
|
//
|
||||||
|
// with an empty value
|
||||||
|
p.vendorExtensions.put("x-model-needs-option", wrapInOptional(p));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,6 +45,10 @@ class {{classname}}Routes(service : {{classname}}Service[Try]) extends cask.Rout
|
|||||||
|
|
||||||
val result = {{>parseHttpParams}}
|
val result = {{>parseHttpParams}}
|
||||||
|
|
||||||
|
{{#vendorExtensions.x-import-response-implicits}}
|
||||||
|
import {{vendorExtensions.x-response-type}}.{given, *} // this brings in upickle in the case of union (oneOf) types
|
||||||
|
{{/vendorExtensions.x-import-response-implicits}}
|
||||||
|
|
||||||
(result : @unchecked) match {
|
(result : @unchecked) match {
|
||||||
case Left(error) => cask.Response(error, 500)
|
case Left(error) => cask.Response(error, 500)
|
||||||
{{#responses}}
|
{{#responses}}
|
||||||
|
@ -13,12 +13,24 @@ import upickle.default.*
|
|||||||
{{#models}}
|
{{#models}}
|
||||||
{{#model}}
|
{{#model}}
|
||||||
|
|
||||||
{{#isEnum}}
|
{{#vendorExtensions.x-has-one-of}}
|
||||||
{{>modelEnum}}
|
|
||||||
{{/isEnum}}
|
type {{classname}} = {{#oneOf}}{{{.}}}{{^-last}} | {{/-last}}{{/oneOf}}
|
||||||
{{^isEnum}}
|
object {{{classname}}} {
|
||||||
{{>modelClass}}
|
|
||||||
{{/isEnum}}
|
given RW[{{{classname}}}] = RW.merge({{#oneOf}}summon[RW[{{{.}}}]]{{^-last}}, {{/-last}}{{/oneOf}})
|
||||||
|
}
|
||||||
|
|
||||||
|
{{/vendorExtensions.x-has-one-of}}
|
||||||
|
{{^vendorExtensions.x-has-one-of}}
|
||||||
|
{{#isEnum}}
|
||||||
|
{{>modelEnum}}
|
||||||
|
{{/isEnum}}
|
||||||
|
{{^isEnum}}
|
||||||
|
{{>modelClass}}
|
||||||
|
{{/isEnum}}
|
||||||
|
{{/vendorExtensions.x-has-one-of}}
|
||||||
|
|
||||||
|
|
||||||
{{/model}}
|
{{/model}}
|
||||||
{{/models}}
|
{{/models}}
|
||||||
|
@ -4,7 +4,7 @@ case class {{classname}}(
|
|||||||
{{#description}}
|
{{#description}}
|
||||||
/* {{{description}}} */
|
/* {{{description}}} */
|
||||||
{{/description}}
|
{{/description}}
|
||||||
{{name}}: {{#isEnum}}{{^required}}Option[{{/required}}{{classname}}.{{datatypeWithEnum}}{{^required}}]{{/required}}{{/isEnum}}{{^isEnum}}{{{vendorExtensions.x-datatype-model}}}{{/isEnum}}{{^required}} = {{{vendorExtensions.x-defaultValue-model}}} {{/required}}{{^-last}},{{/-last}}
|
{{name}}: {{#isEnum}}{{#vendorExtensions.x-model-needs-option}}Option[{{/vendorExtensions.x-model-needs-option}}{{classname}}.{{datatypeWithEnum}}{{#vendorExtensions.x-model-needs-option}}]{{/vendorExtensions.x-model-needs-option}}{{/isEnum}}{{^isEnum}}{{{vendorExtensions.x-datatype-model}}}{{/isEnum}}{{^required}} = {{{vendorExtensions.x-defaultValue-model}}} {{/required}}{{^-last}},{{/-last}}
|
||||||
{{/vars}}
|
{{/vars}}
|
||||||
|
|
||||||
{{#isAdditionalPropertiesTrue}}, additionalProperties : ujson.Value = ujson.Null{{/isAdditionalPropertiesTrue}}
|
{{#isAdditionalPropertiesTrue}}, additionalProperties : ujson.Value = ujson.Null{{/isAdditionalPropertiesTrue}}
|
||||||
|
@ -13,11 +13,40 @@ import upickle.default.*
|
|||||||
{{#models}}
|
{{#models}}
|
||||||
{{#model}}
|
{{#model}}
|
||||||
|
|
||||||
|
{{#vendorExtensions.x-has-one-of}}
|
||||||
|
type {{{classname}}}Data = {{#oneOf}}{{{.}}}Data{{^-last}} | {{/-last}}{{/oneOf}}
|
||||||
|
|
||||||
|
object {{{classname}}}Data {
|
||||||
|
|
||||||
|
def validated(d8a : {{{classname}}}Data, failFast: Boolean) : Try[{{{classname}}}] = {
|
||||||
|
d8a match {
|
||||||
|
{{#oneOf}}
|
||||||
|
case value : {{{.}}}Data => value.validated(failFast)
|
||||||
|
{{/oneOf}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def fromJsonString(jason : String) = fromJson {
|
||||||
|
try {
|
||||||
|
read[ujson.Value](jason)
|
||||||
|
} catch {
|
||||||
|
case NonFatal(e) => sys.error(s"Error parsing json '$jason': $e")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def fromJson(jason : ujson.Value) : {{{classname}}}Data = {
|
||||||
|
val attempt = {{#oneOf}}{{^-first}}.orElse({{/-first}} Try({{{.}}}Data.fromJson(jason)) {{^-first}}) /* not first */{{/-first}} {{/oneOf}}
|
||||||
|
attempt.get
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{{/vendorExtensions.x-has-one-of}}
|
||||||
|
{{^vendorExtensions.x-has-one-of}}
|
||||||
{{#isEnum}}
|
{{#isEnum}}
|
||||||
{{>modelDataEnum}}
|
{{>modelDataEnum}}
|
||||||
{{/isEnum}}
|
{{/isEnum}}
|
||||||
{{^isEnum}}
|
{{^isEnum}}
|
||||||
{{>modelDataClass}}
|
{{>modelDataClass}}
|
||||||
{{/isEnum}}
|
{{/isEnum}}
|
||||||
|
{{/vendorExtensions.x-has-one-of}}
|
||||||
{{/model}}
|
{{/model}}
|
||||||
{{/models}}
|
{{/models}}
|
||||||
|
@ -26,73 +26,73 @@ case class {{classname}}Data(
|
|||||||
}
|
}
|
||||||
|
|
||||||
def validationErrors(path : Seq[Field], failFast : Boolean) : Seq[ValidationError] = {
|
def validationErrors(path : Seq[Field], failFast : Boolean) : Seq[ValidationError] = {
|
||||||
val errors = scala.collection.mutable.ListBuffer[ValidationError]()
|
val _allValidationErrors = scala.collection.mutable.ListBuffer[ValidationError]()
|
||||||
{{#vars}}
|
{{#vars}}
|
||||||
// ================== {{name}} validation ==================
|
// ================== {{name}} validation ==================
|
||||||
{{#pattern}}
|
{{#pattern}}
|
||||||
// validate against pattern '{{{pattern}}}'
|
// validate against pattern '{{{pattern}}}'
|
||||||
if (errors.isEmpty || !failFast) {
|
if (_allValidationErrors.isEmpty || !failFast) {
|
||||||
val regex = """{{{pattern}}}"""
|
val regex = """{{{pattern}}}"""
|
||||||
if {{name}} == null || !regex.r.matches({{name}}) then
|
if {{name}} == null || !regex.r.matches({{name}}) then
|
||||||
errors += ValidationError(path :+ {{classname}}.Fields.{{name}}, s"value '${{name}}' doesn't match pattern $regex")
|
_allValidationErrors += ValidationError(path :+ {{classname}}.Fields.{{name}}, s"value '${{name}}' doesn't match pattern $regex")
|
||||||
}
|
}
|
||||||
{{/pattern}}
|
{{/pattern}}
|
||||||
{{#minimum}}
|
{{#minimum}}
|
||||||
// validate against {{#exclusiveMinimum}}exclusive {{/exclusiveMinimum}}minimum {{minimum}}
|
// validate against {{#exclusiveMinimum}}exclusive {{/exclusiveMinimum}}minimum {{minimum}}
|
||||||
if (errors.isEmpty || !failFast) {
|
if (_allValidationErrors.isEmpty || !failFast) {
|
||||||
if !({{name}} >{{^exclusiveMinimum}}={{/exclusiveMinimum}} {{minimum}}) then
|
if !({{name}} >{{^exclusiveMinimum}}={{/exclusiveMinimum}} {{minimum}}) then
|
||||||
errors += ValidationError(path :+ {{classname}}.Fields.{{name}}, s"value '${{name}}' is not greater than the {{#exclusiveMinimum}}exclusive {{/exclusiveMinimum}}minimum value {{minimum}}")
|
_allValidationErrors += ValidationError(path :+ {{classname}}.Fields.{{name}}, s"value '${{name}}' is not greater than the {{#exclusiveMinimum}}exclusive {{/exclusiveMinimum}}minimum value {{minimum}}")
|
||||||
}
|
}
|
||||||
{{/minimum}}
|
{{/minimum}}
|
||||||
{{#maximum}}
|
{{#maximum}}
|
||||||
// validate against {{#exclusiveMaximum}}exclusive {{/exclusiveMaximum}}maximum {{maximum}}
|
// validate against {{#exclusiveMaximum}}exclusive {{/exclusiveMaximum}}maximum {{maximum}}
|
||||||
if (errors.isEmpty || !failFast) {
|
if (_allValidationErrors.isEmpty || !failFast) {
|
||||||
if !({{name}} <{{^exclusiveMaximum}}={{/exclusiveMaximum}} {{maximum}}) then
|
if !({{name}} <{{^exclusiveMaximum}}={{/exclusiveMaximum}} {{maximum}}) then
|
||||||
errors += ValidationError(path :+ {{classname}}.Fields.{{name}}, s"value '${{name}}' is not greater than the {{#exclusiveMaximum}}exclusive {{/exclusiveMaximum}}maximum value {{maximum}}")
|
_allValidationErrors += ValidationError(path :+ {{classname}}.Fields.{{name}}, s"value '${{name}}' is not greater than the {{#exclusiveMaximum}}exclusive {{/exclusiveMaximum}}maximum value {{maximum}}")
|
||||||
}
|
}
|
||||||
{{/maximum}}
|
{{/maximum}}
|
||||||
{{#minLength}}
|
{{#minLength}}
|
||||||
// validate min length {{minLength}}
|
// validate min length {{minLength}}
|
||||||
if (errors.isEmpty || !failFast) {
|
if (_allValidationErrors.isEmpty || !failFast) {
|
||||||
val len = if {{name}} == null then 0 else {{name}}.length
|
val len = if {{name}} == null then 0 else {{name}}.length
|
||||||
if (len < {{minLength}}) {
|
if (len < {{minLength}}) {
|
||||||
errors += ValidationError(path :+ {{classname}}.Fields.{{name}}, s"length $len is shorter than the min length {{minLength}}")
|
_allValidationErrors += ValidationError(path :+ {{classname}}.Fields.{{name}}, s"length $len is shorter than the min length {{minLength}}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{{/minLength}}
|
{{/minLength}}
|
||||||
{{#maxLength}}
|
{{#maxLength}}
|
||||||
// validate max length {{maxLength}}
|
// validate max length {{maxLength}}
|
||||||
if (errors.isEmpty || !failFast) {
|
if (_allValidationErrors.isEmpty || !failFast) {
|
||||||
val len = if {{name}} == null then 0 else {{name}}.length
|
val len = if {{name}} == null then 0 else {{name}}.length
|
||||||
if (len < {{maxLength}}) {
|
if (len < {{maxLength}}) {
|
||||||
errors += ValidationError(path :+ {{classname}}.Fields.{{name}}, s"length $len is longer than the max length {{maxLength}}")
|
_allValidationErrors += ValidationError(path :+ {{classname}}.Fields.{{name}}, s"length $len is longer than the max length {{maxLength}}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{{/maxLength}}
|
{{/maxLength}}
|
||||||
{{#isEmail}}
|
{{#isEmail}}
|
||||||
// validate {{name}} is a valid email address
|
// validate {{name}} is a valid email address
|
||||||
if (errors.isEmpty || !failFast) {
|
if (_allValidationErrors.isEmpty || !failFast) {
|
||||||
val emailRegex = """^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"""
|
val emailRegex = """^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"""
|
||||||
// validate {{name}} is email
|
// validate {{name}} is email
|
||||||
if ({{name}} == null || !emailRegex.r.matches({{name}})) {
|
if ({{name}} == null || !emailRegex.r.matches({{name}})) {
|
||||||
errors += ValidationError(path :+ {{classname}}.Fields.{{name}}, s"${{name}} is not a valid email address according to the pattern $emailRegex")
|
_allValidationErrors += ValidationError(path :+ {{classname}}.Fields.{{name}}, s"${{name}} is not a valid email address according to the pattern $emailRegex")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{{/isEmail}}
|
{{/isEmail}}
|
||||||
{{#required}}{{^isPrimitiveType}}
|
{{#required}}{{^isPrimitiveType}}
|
||||||
if (errors.isEmpty || !failFast) {
|
if (_allValidationErrors.isEmpty || !failFast) {
|
||||||
if ({{name}} == null) {
|
if ({{name}} == null) {
|
||||||
errors += ValidationError(path :+ {{classname}}.Fields.{{name}}, "{{name}} is a required field and cannot be null")
|
_allValidationErrors += ValidationError(path :+ {{classname}}.Fields.{{name}}, "{{name}} is a required field and cannot be null")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{{/isPrimitiveType}}{{/required}}
|
{{/isPrimitiveType}}{{/required}}
|
||||||
{{#uniqueItems}}
|
{{#uniqueItems}}
|
||||||
// validate {{name}} has unique items
|
// validate {{name}} has unique items
|
||||||
if (errors.isEmpty || !failFast) {
|
if (_allValidationErrors.isEmpty || !failFast) {
|
||||||
if ({{name}} != null) {
|
if ({{name}} != null) {
|
||||||
{{name}}.foldLeft(Set[{{{vendorExtensions.x-containertype-data}}}]()) {
|
{{name}}.foldLeft(Set[{{{vendorExtensions.x-containertype-data}}}]()) {
|
||||||
case (set, next) if set.contains(next) =>
|
case (set, next) if set.contains(next) =>
|
||||||
errors += ValidationError(
|
_allValidationErrors += ValidationError(
|
||||||
path :+ {{classname}}.Fields.{{name}},
|
path :+ {{classname}}.Fields.{{name}},
|
||||||
s"duplicate value: $next"
|
s"duplicate value: $next"
|
||||||
)
|
)
|
||||||
@ -103,10 +103,10 @@ case class {{classname}}Data(
|
|||||||
}
|
}
|
||||||
{{/uniqueItems}}
|
{{/uniqueItems}}
|
||||||
{{#multipleOf}}
|
{{#multipleOf}}
|
||||||
if (errors.isEmpty || !failFast) {
|
if (_allValidationErrors.isEmpty || !failFast) {
|
||||||
// validate {{name}} multiple of {{multipleOf}}
|
// validate {{name}} multiple of {{multipleOf}}
|
||||||
if ({{name}} % {{multipleOf}} != 0) {
|
if ({{name}} % {{multipleOf}} != 0) {
|
||||||
errors += ValidationError(
|
_allValidationErrors += ValidationError(
|
||||||
path :+ {{classname}}.Fields.{{name}},
|
path :+ {{classname}}.Fields.{{name}},
|
||||||
s"${{name}} is not a multiple of {{multipleOf}}"
|
s"${{name}} is not a multiple of {{multipleOf}}"
|
||||||
)
|
)
|
||||||
@ -115,30 +115,30 @@ case class {{classname}}Data(
|
|||||||
{{/multipleOf}}
|
{{/multipleOf}}
|
||||||
{{#minItems}}
|
{{#minItems}}
|
||||||
// validate min items {{minItems}}
|
// validate min items {{minItems}}
|
||||||
if (errors.isEmpty || !failFast) {
|
if (_allValidationErrors.isEmpty || !failFast) {
|
||||||
val len = if {{name}} == null then 0 else {{name}}.size
|
val len = if {{name}} == null then 0 else {{name}}.size
|
||||||
if (len < {{minItems}}) {
|
if (len < {{minItems}}) {
|
||||||
errors += ValidationError(path :+ {{classname}}.Fields.{{name}}, s"{{name}} has $len, which is less than the min items {{minItems}}")
|
_allValidationErrors += ValidationError(path :+ {{classname}}.Fields.{{name}}, s"{{name}} has $len, which is less than the min items {{minItems}}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{{/minItems}}
|
{{/minItems}}
|
||||||
{{#maxItems}}
|
{{#maxItems}}
|
||||||
// validate min items {{maxItems}}
|
// validate min items {{maxItems}}
|
||||||
if (errors.isEmpty || !failFast) {
|
if (_allValidationErrors.isEmpty || !failFast) {
|
||||||
val len = if {{name}} == null then 0 else {{name}}.size
|
val len = if {{name}} == null then 0 else {{name}}.size
|
||||||
if (len > {{maxItems}}) {
|
if (len > {{maxItems}}) {
|
||||||
errors += ValidationError(path :+ {{classname}}.Fields.{{name}}, s"{{name}} has $len, which is greater than the max items {{maxItems}}")
|
_allValidationErrors += ValidationError(path :+ {{classname}}.Fields.{{name}}, s"{{name}} has $len, which is greater than the max items {{maxItems}}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{{/maxItems}}
|
{{/maxItems}}
|
||||||
{{#minProperties}} TODO - minProperties {{/minProperties}}
|
{{#minProperties}} TODO - minProperties {{/minProperties}}
|
||||||
{{#maxProperties}} TODO - maxProperties {{/maxProperties}}
|
{{#maxProperties}} TODO - maxProperties {{/maxProperties}}
|
||||||
{{#items}}{{#isModel}}
|
{{#items}}{{#isModel}}
|
||||||
if (errors.isEmpty || !failFast) {
|
if (_allValidationErrors.isEmpty || !failFast) {
|
||||||
if ({{name}} != null) {
|
if ({{name}} != null) {
|
||||||
{{name}}.zipWithIndex.foreach {
|
{{name}}.zipWithIndex.foreach {
|
||||||
case (value, i) if errors.isEmpty || !failFast =>
|
case (value, i) if _allValidationErrors.isEmpty || !failFast =>
|
||||||
errors ++= value.validationErrors(
|
_allValidationErrors ++= value.validationErrors(
|
||||||
path :+ {{classname}}.Fields.{{name}} :+ Field(i.toString),
|
path :+ {{classname}}.Fields.{{name}} :+ Field(i.toString),
|
||||||
failFast)
|
failFast)
|
||||||
case (value, i) =>
|
case (value, i) =>
|
||||||
@ -148,13 +148,13 @@ case class {{classname}}Data(
|
|||||||
{{/isModel}}{{/items}}
|
{{/isModel}}{{/items}}
|
||||||
{{#isModel}}
|
{{#isModel}}
|
||||||
// validating {{name}}
|
// validating {{name}}
|
||||||
if (errors.isEmpty || !failFast) {
|
if (_allValidationErrors.isEmpty || !failFast) {
|
||||||
if {{name}} != null then errors ++= {{name}}.validationErrors(path :+ {{classname}}.Fields.{{name}}, failFast)
|
if {{name}} != null then _allValidationErrors ++= {{name}}.validationErrors(path :+ {{classname}}.Fields.{{name}}, failFast)
|
||||||
}
|
}
|
||||||
{{/isModel}}
|
{{/isModel}}
|
||||||
|
|
||||||
{{/vars}}
|
{{/vars}}
|
||||||
errors.toSeq
|
_allValidationErrors.toSeq
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -180,6 +180,8 @@ case class {{classname}}Data(
|
|||||||
|
|
||||||
object {{classname}}Data {
|
object {{classname}}Data {
|
||||||
|
|
||||||
|
def validated(d8a : {{classname}}Data, failFast : Boolean) : scala.util.Try[{{classname}}] = d8a.validated(failFast)
|
||||||
|
|
||||||
def fromJson(jason : ujson.Value) : {{classname}}Data = try {
|
def fromJson(jason : ujson.Value) : {{classname}}Data = try {
|
||||||
val data = read[{{classname}}Data](jason)
|
val data = read[{{classname}}Data](jason)
|
||||||
{{^isAdditionalPropertiesTrue}}
|
{{^isAdditionalPropertiesTrue}}
|
||||||
|
@ -28,7 +28,8 @@ class {{classname}}Test extends AnyWordSpec with Matchers {
|
|||||||
err.getMessage should startWith ("Error parsing json 'invalid jason'")
|
err.getMessage should startWith ("Error parsing json 'invalid jason'")
|
||||||
}
|
}
|
||||||
"""parse {{example}}""" ignore {
|
"""parse {{example}}""" ignore {
|
||||||
val Failure(err : ValidationErrors) = {{classname}}Data.fromJsonString("""{{example}}""").validated()
|
val d8a = {{classname}}Data.fromJsonString("""{{example}}""")
|
||||||
|
val Failure(err : ValidationErrors) = {{classname}}Data.validated(d8a, true)
|
||||||
|
|
||||||
sys.error("TODO")
|
sys.error("TODO")
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,10 @@
|
|||||||
{{^isMap}}
|
{{^isMap}}
|
||||||
{{paramName}}Json <- Parsed.fromTry(request.bodyAsJson)
|
{{paramName}}Json <- Parsed.fromTry(request.bodyAsJson)
|
||||||
{{paramName}}Data <- Parsed.eval({{vendorExtensions.x-container-type}}Data.fromJson({{paramName}}Json)) /* not array or map */
|
{{paramName}}Data <- Parsed.eval({{vendorExtensions.x-container-type}}Data.fromJson({{paramName}}Json)) /* not array or map */
|
||||||
{{paramName}} <- Parsed.fromTry({{paramName}}Data.validated(failFast))
|
{{paramName}}{{^required}}Opt{{/required}} <- Parsed.fromTry({{vendorExtensions.x-container-type}}Data.validated({{paramName}}Data, failFast))
|
||||||
|
{{^required}}
|
||||||
|
{{paramName}} = Option({{paramName}}Opt)
|
||||||
|
{{/required}}
|
||||||
{{/isMap}}
|
{{/isMap}}
|
||||||
{{/isArray}}
|
{{/isArray}}
|
||||||
{{/vendorExtensions.x-consumes-json}}
|
{{/vendorExtensions.x-consumes-json}}
|
||||||
|
@ -1 +1 @@
|
|||||||
sbt.version=1.9.9
|
sbt.version=1.10.3
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.6")
|
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.6")
|
||||||
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "1.2.0")
|
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "1.2.0")
|
||||||
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.16.0")
|
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.17.0")
|
||||||
addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.2.0")
|
addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.2.0")
|
@ -0,0 +1,905 @@
|
|||||||
|
openapi: 3.0.0
|
||||||
|
servers:
|
||||||
|
- url: 'http://petstore.swagger.io/v2'
|
||||||
|
info:
|
||||||
|
description: >-
|
||||||
|
This is a sample server Petstore server. For this sample, you can use the api key
|
||||||
|
`special-key` to test the authorization filters.
|
||||||
|
version: 1.0.0
|
||||||
|
title: OpenAPI Petstore
|
||||||
|
license:
|
||||||
|
name: Apache-2.0
|
||||||
|
url: 'https://www.apache.org/licenses/LICENSE-2.0.html'
|
||||||
|
tags:
|
||||||
|
- name: pet
|
||||||
|
description: Everything about your Pets
|
||||||
|
- name: store
|
||||||
|
description: Access to Petstore orders
|
||||||
|
- name: user
|
||||||
|
description: Operations about user
|
||||||
|
paths:
|
||||||
|
/complex-types:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- complexRoute
|
||||||
|
operationId: oneOfRequestAndResponse
|
||||||
|
summary: Example route with 'oneOf' content and response
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
oneOf:
|
||||||
|
- $ref: '#/components/schemas/ComplexRequest'
|
||||||
|
- $ref: '#/components/schemas/AllOfRequest'
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Success
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
oneOf:
|
||||||
|
- $ref: '#/components/schemas/SomeResponse1'
|
||||||
|
- $ref: '#/components/schemas/SomeResponse2'
|
||||||
|
/pet:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- pet
|
||||||
|
summary: Add a new pet to the store
|
||||||
|
description: ''
|
||||||
|
operationId: addPet
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
content:
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Pet'
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Pet'
|
||||||
|
'405':
|
||||||
|
description: Invalid input
|
||||||
|
security:
|
||||||
|
- petstore_auth:
|
||||||
|
- 'write:pets'
|
||||||
|
- 'read:pets'
|
||||||
|
requestBody:
|
||||||
|
$ref: '#/components/requestBodies/Pet'
|
||||||
|
put:
|
||||||
|
tags:
|
||||||
|
- pet
|
||||||
|
summary: Update an existing pet
|
||||||
|
description: ''
|
||||||
|
operationId: updatePet
|
||||||
|
externalDocs:
|
||||||
|
url: "http://petstore.swagger.io/v2/doc/updatePet"
|
||||||
|
description: "API documentation for the updatePet operation"
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
content:
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Pet'
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Pet'
|
||||||
|
'400':
|
||||||
|
description: Invalid ID supplied
|
||||||
|
'404':
|
||||||
|
description: Pet not found
|
||||||
|
'405':
|
||||||
|
description: Validation exception
|
||||||
|
security:
|
||||||
|
- petstore_auth:
|
||||||
|
- 'write:pets'
|
||||||
|
- 'read:pets'
|
||||||
|
requestBody:
|
||||||
|
$ref: '#/components/requestBodies/Pet'
|
||||||
|
/pet/findByStatus:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- pet
|
||||||
|
summary: Finds Pets by status
|
||||||
|
description: Multiple status values can be provided with comma separated strings
|
||||||
|
operationId: findPetsByStatus
|
||||||
|
parameters:
|
||||||
|
- name: status
|
||||||
|
in: query
|
||||||
|
description: Status values that need to be considered for filter
|
||||||
|
required: true
|
||||||
|
style: form
|
||||||
|
explode: false
|
||||||
|
deprecated: true
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- available
|
||||||
|
- pending
|
||||||
|
- sold
|
||||||
|
default: available
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
content:
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/Pet'
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/Pet'
|
||||||
|
'400':
|
||||||
|
description: Invalid status value
|
||||||
|
security:
|
||||||
|
- petstore_auth:
|
||||||
|
- 'read:pets'
|
||||||
|
/pet/findByTags:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- pet
|
||||||
|
summary: Finds Pets by tags
|
||||||
|
description: >-
|
||||||
|
Multiple tags can be provided with comma separated strings. Use tag1,
|
||||||
|
tag2, tag3 for testing.
|
||||||
|
operationId: findPetsByTags
|
||||||
|
parameters:
|
||||||
|
- name: tags
|
||||||
|
in: query
|
||||||
|
description: Tags to filter by
|
||||||
|
required: true
|
||||||
|
style: form
|
||||||
|
explode: false
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
content:
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/Pet'
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/Pet'
|
||||||
|
'400':
|
||||||
|
description: Invalid tag value
|
||||||
|
security:
|
||||||
|
- petstore_auth:
|
||||||
|
- 'read:pets'
|
||||||
|
deprecated: true
|
||||||
|
'/pet/{petId}':
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- pet
|
||||||
|
summary: Find pet by ID
|
||||||
|
description: Returns a single pet
|
||||||
|
operationId: getPetById
|
||||||
|
parameters:
|
||||||
|
- name: petId
|
||||||
|
in: path
|
||||||
|
description: ID of pet to return
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
content:
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Pet'
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Pet'
|
||||||
|
'400':
|
||||||
|
description: Invalid ID supplied
|
||||||
|
'404':
|
||||||
|
description: Pet not found
|
||||||
|
security:
|
||||||
|
- api_key: []
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- pet
|
||||||
|
summary: Updates a pet in the store with form data
|
||||||
|
description: ''
|
||||||
|
operationId: updatePetWithForm
|
||||||
|
parameters:
|
||||||
|
- name: petId
|
||||||
|
in: path
|
||||||
|
description: ID of pet that needs to be updated
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
responses:
|
||||||
|
'405':
|
||||||
|
description: Invalid input
|
||||||
|
security:
|
||||||
|
- petstore_auth:
|
||||||
|
- 'write:pets'
|
||||||
|
- 'read:pets'
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/x-www-form-urlencoded:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
description: Updated name of the pet
|
||||||
|
type: string
|
||||||
|
status:
|
||||||
|
description: Updated status of the pet
|
||||||
|
type: string
|
||||||
|
delete:
|
||||||
|
tags:
|
||||||
|
- pet
|
||||||
|
summary: Deletes a pet
|
||||||
|
description: ''
|
||||||
|
operationId: deletePet
|
||||||
|
parameters:
|
||||||
|
- name: api_key
|
||||||
|
in: header
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: petId
|
||||||
|
in: path
|
||||||
|
description: Pet id to delete
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
responses:
|
||||||
|
'400':
|
||||||
|
description: Invalid pet value
|
||||||
|
security:
|
||||||
|
- petstore_auth:
|
||||||
|
- 'write:pets'
|
||||||
|
- 'read:pets'
|
||||||
|
'/pet/{petId}/uploadImage':
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- pet
|
||||||
|
summary: uploads an image
|
||||||
|
description: ''
|
||||||
|
operationId: uploadFile
|
||||||
|
parameters:
|
||||||
|
- name: petId
|
||||||
|
in: path
|
||||||
|
description: ID of pet to update
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/ApiResponse'
|
||||||
|
security:
|
||||||
|
- petstore_auth:
|
||||||
|
- 'write:pets'
|
||||||
|
- 'read:pets'
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
multipart/form-data:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
additionalMetadata:
|
||||||
|
description: Additional data to pass to server
|
||||||
|
type: string
|
||||||
|
file:
|
||||||
|
description: file to upload
|
||||||
|
type: string
|
||||||
|
format: binary
|
||||||
|
/store/inventory:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- store
|
||||||
|
summary: Returns pet inventories by status
|
||||||
|
description: Returns a map of status codes to quantities
|
||||||
|
operationId: getInventory
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
additionalProperties:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
security:
|
||||||
|
- api_key: []
|
||||||
|
/store/order:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- store
|
||||||
|
summary: Place an order for a pet
|
||||||
|
description: ''
|
||||||
|
operationId: placeOrder
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
content:
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Order'
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Order'
|
||||||
|
'400':
|
||||||
|
description: Invalid Order
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Order'
|
||||||
|
description: order placed for purchasing the pet
|
||||||
|
required: true
|
||||||
|
'/store/order/{orderId}':
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- store
|
||||||
|
summary: Find purchase order by ID
|
||||||
|
description: >-
|
||||||
|
For valid response try integer IDs with value <= 5 or > 10. Other values
|
||||||
|
will generate exceptions
|
||||||
|
operationId: getOrderById
|
||||||
|
parameters:
|
||||||
|
- name: orderId
|
||||||
|
in: path
|
||||||
|
description: ID of pet that needs to be fetched
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
minimum: 1
|
||||||
|
maximum: 5
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
content:
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Order'
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Order'
|
||||||
|
'400':
|
||||||
|
description: Invalid ID supplied
|
||||||
|
'404':
|
||||||
|
description: Order not found
|
||||||
|
delete:
|
||||||
|
tags:
|
||||||
|
- store
|
||||||
|
summary: Delete purchase order by ID
|
||||||
|
description: >-
|
||||||
|
For valid response try integer IDs with value < 1000. Anything above
|
||||||
|
1000 or nonintegers will generate API errors
|
||||||
|
operationId: deleteOrder
|
||||||
|
parameters:
|
||||||
|
- name: orderId
|
||||||
|
in: path
|
||||||
|
description: ID of the order that needs to be deleted
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'400':
|
||||||
|
description: Invalid ID supplied
|
||||||
|
'404':
|
||||||
|
description: Order not found
|
||||||
|
/user:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- user
|
||||||
|
summary: Create user
|
||||||
|
description: This can only be done by the logged in user.
|
||||||
|
operationId: createUser
|
||||||
|
responses:
|
||||||
|
default:
|
||||||
|
description: successful operation
|
||||||
|
security:
|
||||||
|
- api_key: []
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/User'
|
||||||
|
description: Created user object
|
||||||
|
required: true
|
||||||
|
/user/createWithArray:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- user
|
||||||
|
summary: Creates list of users with given input array
|
||||||
|
description: ''
|
||||||
|
operationId: createUsersWithArrayInput
|
||||||
|
responses:
|
||||||
|
default:
|
||||||
|
description: successful operation
|
||||||
|
security:
|
||||||
|
- api_key: []
|
||||||
|
requestBody:
|
||||||
|
$ref: '#/components/requestBodies/UserArray'
|
||||||
|
/user/createWithList:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- user
|
||||||
|
summary: Creates list of users with given input array
|
||||||
|
description: ''
|
||||||
|
operationId: createUsersWithListInput
|
||||||
|
responses:
|
||||||
|
default:
|
||||||
|
description: successful operation
|
||||||
|
security:
|
||||||
|
- api_key: []
|
||||||
|
requestBody:
|
||||||
|
$ref: '#/components/requestBodies/UserArray'
|
||||||
|
/user/login:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- user
|
||||||
|
summary: Logs user into the system
|
||||||
|
description: ''
|
||||||
|
operationId: loginUser
|
||||||
|
parameters:
|
||||||
|
- name: username
|
||||||
|
in: query
|
||||||
|
description: The user name for login
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
pattern: '^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$'
|
||||||
|
- name: password
|
||||||
|
in: query
|
||||||
|
description: The password for login in clear text
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
headers:
|
||||||
|
Set-Cookie:
|
||||||
|
description: >-
|
||||||
|
Cookie authentication key for use with the `api_key`
|
||||||
|
apiKey authentication.
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
example: AUTH_KEY=abcde12345; Path=/; HttpOnly
|
||||||
|
X-Rate-Limit:
|
||||||
|
description: calls per hour allowed by the user
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
X-Expires-After:
|
||||||
|
description: date in UTC when token expires
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
content:
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
'400':
|
||||||
|
description: Invalid username/password supplied
|
||||||
|
/user/logout:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- user
|
||||||
|
summary: Logs out current logged in user session
|
||||||
|
description: ''
|
||||||
|
operationId: logoutUser
|
||||||
|
responses:
|
||||||
|
default:
|
||||||
|
description: successful operation
|
||||||
|
security:
|
||||||
|
- api_key: []
|
||||||
|
'/user/{username}':
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- user
|
||||||
|
summary: Get user by user name
|
||||||
|
description: ''
|
||||||
|
operationId: getUserByName
|
||||||
|
parameters:
|
||||||
|
- name: username
|
||||||
|
in: path
|
||||||
|
description: The name that needs to be fetched. Use user1 for testing.
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
content:
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/User'
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/User'
|
||||||
|
'400':
|
||||||
|
description: Invalid username supplied
|
||||||
|
'404':
|
||||||
|
description: User not found
|
||||||
|
put:
|
||||||
|
tags:
|
||||||
|
- user
|
||||||
|
summary: Updated user
|
||||||
|
description: This can only be done by the logged in user.
|
||||||
|
operationId: updateUser
|
||||||
|
parameters:
|
||||||
|
- name: username
|
||||||
|
in: path
|
||||||
|
description: name that need to be deleted
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'400':
|
||||||
|
description: Invalid user supplied
|
||||||
|
'404':
|
||||||
|
description: User not found
|
||||||
|
security:
|
||||||
|
- api_key: []
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/User'
|
||||||
|
description: Updated user object
|
||||||
|
required: true
|
||||||
|
delete:
|
||||||
|
tags:
|
||||||
|
- user
|
||||||
|
summary: Delete user
|
||||||
|
description: This can only be done by the logged in user.
|
||||||
|
operationId: deleteUser
|
||||||
|
parameters:
|
||||||
|
- name: username
|
||||||
|
in: path
|
||||||
|
description: The name that needs to be deleted
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'400':
|
||||||
|
description: Invalid username supplied
|
||||||
|
'404':
|
||||||
|
description: User not found
|
||||||
|
security:
|
||||||
|
- api_key: []
|
||||||
|
externalDocs:
|
||||||
|
description: Find out more about Swagger
|
||||||
|
url: 'http://swagger.io'
|
||||||
|
components:
|
||||||
|
requestBodies:
|
||||||
|
UserArray:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/User'
|
||||||
|
description: List of user object
|
||||||
|
required: true
|
||||||
|
Pet:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Pet'
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Pet'
|
||||||
|
description: Pet object that needs to be added to the store
|
||||||
|
required: true
|
||||||
|
securitySchemes:
|
||||||
|
petstore_auth:
|
||||||
|
type: oauth2
|
||||||
|
flows:
|
||||||
|
implicit:
|
||||||
|
authorizationUrl: 'http://petstore.swagger.io/api/oauth/dialog'
|
||||||
|
scopes:
|
||||||
|
'write:pets': modify pets in your account
|
||||||
|
'read:pets': read your pets
|
||||||
|
api_key:
|
||||||
|
type: apiKey
|
||||||
|
name: api_key
|
||||||
|
in: header
|
||||||
|
schemas:
|
||||||
|
Order:
|
||||||
|
title: Pet Order
|
||||||
|
description: An order for a pets from the pet store
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
petId:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
quantity:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
shipDate:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
description: Order Status
|
||||||
|
enum:
|
||||||
|
- placed
|
||||||
|
- approved
|
||||||
|
- delivered
|
||||||
|
complete:
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
xml:
|
||||||
|
name: Order
|
||||||
|
Category:
|
||||||
|
title: Pet category
|
||||||
|
description: A category for a pet
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
pattern: '^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$'
|
||||||
|
xml:
|
||||||
|
name: Category
|
||||||
|
User:
|
||||||
|
title: a User
|
||||||
|
description: A User who is purchasing from the pet store
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
username:
|
||||||
|
type: string
|
||||||
|
firstName:
|
||||||
|
type: string
|
||||||
|
lastName:
|
||||||
|
type: string
|
||||||
|
email:
|
||||||
|
type: string
|
||||||
|
password:
|
||||||
|
type: string
|
||||||
|
phone:
|
||||||
|
type: string
|
||||||
|
userStatus:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
description: User Status
|
||||||
|
xml:
|
||||||
|
name: User
|
||||||
|
Tag:
|
||||||
|
title: Pet Tag
|
||||||
|
description: A tag for a pet
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
xml:
|
||||||
|
name: Tag
|
||||||
|
Pet:
|
||||||
|
title: a Pet
|
||||||
|
description: A pet for sale in the pet store
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- name
|
||||||
|
- photoUrls
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
category:
|
||||||
|
$ref: '#/components/schemas/Category'
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
example: doggie
|
||||||
|
photoUrls:
|
||||||
|
type: array
|
||||||
|
xml:
|
||||||
|
name: photoUrl
|
||||||
|
wrapped: true
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
tags:
|
||||||
|
type: array
|
||||||
|
xml:
|
||||||
|
name: tag
|
||||||
|
wrapped: true
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/Tag'
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
description: pet status in the store
|
||||||
|
deprecated: true
|
||||||
|
enum:
|
||||||
|
- available
|
||||||
|
- pending
|
||||||
|
- sold
|
||||||
|
xml:
|
||||||
|
name: Pet
|
||||||
|
ApiResponse:
|
||||||
|
title: An uploaded response
|
||||||
|
description: Describes the result of uploading an image resource
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
code:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
type:
|
||||||
|
type: string
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
ComplexRequest:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- type
|
||||||
|
- requiredField
|
||||||
|
properties:
|
||||||
|
type:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- someEnum
|
||||||
|
requiredField:
|
||||||
|
type: string
|
||||||
|
description: A required string field
|
||||||
|
stringField:
|
||||||
|
type: string
|
||||||
|
minLength: 5
|
||||||
|
maxLength: 100
|
||||||
|
description: String with length constraints
|
||||||
|
integerField:
|
||||||
|
type: integer
|
||||||
|
minimum: 1
|
||||||
|
maximum: 100
|
||||||
|
description: Integer with a range from 1 to 100
|
||||||
|
numberField:
|
||||||
|
type: number
|
||||||
|
exclusiveMinimum: 0.0
|
||||||
|
exclusiveMaximum: 100.0
|
||||||
|
description: Number with exclusive minimum and maximum constraints
|
||||||
|
booleanField:
|
||||||
|
type: boolean
|
||||||
|
description: A boolean field
|
||||||
|
emailField:
|
||||||
|
type: string
|
||||||
|
format: email
|
||||||
|
description: A valid email address
|
||||||
|
uuidField:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
description: A valid UUID
|
||||||
|
dateField:
|
||||||
|
type: string
|
||||||
|
format: date
|
||||||
|
description: A date field (YYYY-MM-DD)
|
||||||
|
dateTimeField:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
description: A date-time field (RFC 3339 format)
|
||||||
|
arrayField:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
minItems: 1
|
||||||
|
maxItems: 10
|
||||||
|
description: An array of strings with min and max items constraints
|
||||||
|
enumField:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- value1
|
||||||
|
- value2
|
||||||
|
- value3
|
||||||
|
description: A string field with enum validation
|
||||||
|
nestedObject:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
nestedField1:
|
||||||
|
type: string
|
||||||
|
description: A field within a nested object
|
||||||
|
nestedField2:
|
||||||
|
type: integer
|
||||||
|
description: Another field in a nested object
|
||||||
|
arrayOfObjectsField:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
objectField1:
|
||||||
|
type: string
|
||||||
|
objectField2:
|
||||||
|
type: integer
|
||||||
|
description: An array of objects
|
||||||
|
patternField:
|
||||||
|
type: string
|
||||||
|
pattern: '^[a-zA-Z0-9]{3,10}$'
|
||||||
|
description: A string field with regex pattern validation
|
||||||
|
nullableField:
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
|
description: A string field that allows null values
|
||||||
|
additionalProperties:
|
||||||
|
type: object
|
||||||
|
description: Additional properties are allowed beyond the defined fields
|
||||||
|
|
||||||
|
AllOfRequest:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
age:
|
||||||
|
type: integer
|
||||||
|
details:
|
||||||
|
allOf:
|
||||||
|
- type: object
|
||||||
|
properties:
|
||||||
|
address:
|
||||||
|
type: string
|
||||||
|
- type: object
|
||||||
|
properties:
|
||||||
|
contact_number:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- name
|
||||||
|
- age
|
||||||
|
SomeResponse1:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- status
|
||||||
|
- message
|
||||||
|
|
||||||
|
SomeResponse2:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: string
|
||||||
|
created_at:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
details:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
description:
|
||||||
|
type: string
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- id
|
||||||
|
- created_at
|
@ -10,6 +10,8 @@ example/Server.scala
|
|||||||
jvm/src/main/scala/sample/cask/AppRoutes.scala
|
jvm/src/main/scala/sample/cask/AppRoutes.scala
|
||||||
jvm/src/main/scala/sample/cask/BaseApp.scala
|
jvm/src/main/scala/sample/cask/BaseApp.scala
|
||||||
jvm/src/main/scala/sample/cask/ExampleApp.scala
|
jvm/src/main/scala/sample/cask/ExampleApp.scala
|
||||||
|
jvm/src/main/scala/sample/cask/api/ComplexRouteRoutes.scala
|
||||||
|
jvm/src/main/scala/sample/cask/api/ComplexRouteRoutes.scala
|
||||||
jvm/src/main/scala/sample/cask/api/OpenApiRoutes.scala
|
jvm/src/main/scala/sample/cask/api/OpenApiRoutes.scala
|
||||||
jvm/src/main/scala/sample/cask/api/PetRoutes.scala
|
jvm/src/main/scala/sample/cask/api/PetRoutes.scala
|
||||||
jvm/src/main/scala/sample/cask/api/PetRoutes.scala
|
jvm/src/main/scala/sample/cask/api/PetRoutes.scala
|
||||||
@ -19,19 +21,50 @@ jvm/src/main/scala/sample/cask/api/UserRoutes.scala
|
|||||||
jvm/src/main/scala/sample/cask/api/UserRoutes.scala
|
jvm/src/main/scala/sample/cask/api/UserRoutes.scala
|
||||||
jvm/src/main/scala/sample/cask/api/package.scala
|
jvm/src/main/scala/sample/cask/api/package.scala
|
||||||
jvm/src/main/scala/sample/cask/package.scala
|
jvm/src/main/scala/sample/cask/package.scala
|
||||||
|
jvm/src/test/scala/sample/cask/model/AllOfRequestDetailsTest.scala
|
||||||
|
jvm/src/test/scala/sample/cask/model/AllOfRequestTest.scala
|
||||||
|
jvm/src/test/scala/sample/cask/model/ComplexRequestArrayOfObjectsFieldInnerTest.scala
|
||||||
|
jvm/src/test/scala/sample/cask/model/ComplexRequestNestedObjectTest.scala
|
||||||
|
jvm/src/test/scala/sample/cask/model/ComplexRequestTest.scala
|
||||||
|
jvm/src/test/scala/sample/cask/model/OneOfRequestAndResponse200ResponseTest.scala
|
||||||
|
jvm/src/test/scala/sample/cask/model/OneOfRequestAndResponseRequestTest.scala
|
||||||
|
jvm/src/test/scala/sample/cask/model/SomeResponse1Test.scala
|
||||||
|
jvm/src/test/scala/sample/cask/model/SomeResponse2DetailsTest.scala
|
||||||
|
jvm/src/test/scala/sample/cask/model/SomeResponse2Test.scala
|
||||||
project/build.properties
|
project/build.properties
|
||||||
project/plugins.sbt
|
project/plugins.sbt
|
||||||
|
shared/src/main/scala/sample/cask/api/ComplexRouteService.scala
|
||||||
shared/src/main/scala/sample/cask/api/PetService.scala
|
shared/src/main/scala/sample/cask/api/PetService.scala
|
||||||
shared/src/main/scala/sample/cask/api/StoreService.scala
|
shared/src/main/scala/sample/cask/api/StoreService.scala
|
||||||
shared/src/main/scala/sample/cask/api/UserService.scala
|
shared/src/main/scala/sample/cask/api/UserService.scala
|
||||||
|
shared/src/main/scala/sample/cask/model/AllOfRequest.scala
|
||||||
|
shared/src/main/scala/sample/cask/model/AllOfRequestData.scala
|
||||||
|
shared/src/main/scala/sample/cask/model/AllOfRequestDetails.scala
|
||||||
|
shared/src/main/scala/sample/cask/model/AllOfRequestDetailsData.scala
|
||||||
shared/src/main/scala/sample/cask/model/ApiResponse.scala
|
shared/src/main/scala/sample/cask/model/ApiResponse.scala
|
||||||
shared/src/main/scala/sample/cask/model/ApiResponseData.scala
|
shared/src/main/scala/sample/cask/model/ApiResponseData.scala
|
||||||
shared/src/main/scala/sample/cask/model/Category.scala
|
shared/src/main/scala/sample/cask/model/Category.scala
|
||||||
shared/src/main/scala/sample/cask/model/CategoryData.scala
|
shared/src/main/scala/sample/cask/model/CategoryData.scala
|
||||||
|
shared/src/main/scala/sample/cask/model/ComplexRequest.scala
|
||||||
|
shared/src/main/scala/sample/cask/model/ComplexRequestArrayOfObjectsFieldInner.scala
|
||||||
|
shared/src/main/scala/sample/cask/model/ComplexRequestArrayOfObjectsFieldInnerData.scala
|
||||||
|
shared/src/main/scala/sample/cask/model/ComplexRequestData.scala
|
||||||
|
shared/src/main/scala/sample/cask/model/ComplexRequestNestedObject.scala
|
||||||
|
shared/src/main/scala/sample/cask/model/ComplexRequestNestedObjectData.scala
|
||||||
|
shared/src/main/scala/sample/cask/model/OneOfRequestAndResponse200Response.scala
|
||||||
|
shared/src/main/scala/sample/cask/model/OneOfRequestAndResponse200ResponseData.scala
|
||||||
|
shared/src/main/scala/sample/cask/model/OneOfRequestAndResponseRequest.scala
|
||||||
|
shared/src/main/scala/sample/cask/model/OneOfRequestAndResponseRequestData.scala
|
||||||
shared/src/main/scala/sample/cask/model/Order.scala
|
shared/src/main/scala/sample/cask/model/Order.scala
|
||||||
shared/src/main/scala/sample/cask/model/OrderData.scala
|
shared/src/main/scala/sample/cask/model/OrderData.scala
|
||||||
shared/src/main/scala/sample/cask/model/Pet.scala
|
shared/src/main/scala/sample/cask/model/Pet.scala
|
||||||
shared/src/main/scala/sample/cask/model/PetData.scala
|
shared/src/main/scala/sample/cask/model/PetData.scala
|
||||||
|
shared/src/main/scala/sample/cask/model/SomeResponse1.scala
|
||||||
|
shared/src/main/scala/sample/cask/model/SomeResponse1Data.scala
|
||||||
|
shared/src/main/scala/sample/cask/model/SomeResponse2.scala
|
||||||
|
shared/src/main/scala/sample/cask/model/SomeResponse2Data.scala
|
||||||
|
shared/src/main/scala/sample/cask/model/SomeResponse2Details.scala
|
||||||
|
shared/src/main/scala/sample/cask/model/SomeResponse2DetailsData.scala
|
||||||
shared/src/main/scala/sample/cask/model/Tag.scala
|
shared/src/main/scala/sample/cask/model/Tag.scala
|
||||||
shared/src/main/scala/sample/cask/model/TagData.scala
|
shared/src/main/scala/sample/cask/model/TagData.scala
|
||||||
shared/src/main/scala/sample/cask/model/User.scala
|
shared/src/main/scala/sample/cask/model/User.scala
|
||||||
|
@ -47,6 +47,7 @@ import sample.cask.model.*
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
// TODO - write your business logic for your services here (the defaults all return 'not implemented'):
|
// TODO - write your business logic for your services here (the defaults all return 'not implemented'):
|
||||||
|
val myComplexRouteService : ComplexRouteService = ComplexRouteService() // <-- replace this with your implementation
|
||||||
val myPetService : PetService = PetService() // <-- replace this with your implementation
|
val myPetService : PetService = PetService() // <-- replace this with your implementation
|
||||||
val myStoreService : StoreService = StoreService() // <-- replace this with your implementation
|
val myStoreService : StoreService = StoreService() // <-- replace this with your implementation
|
||||||
val myUserService : UserService = UserService() // <-- replace this with your implementation
|
val myUserService : UserService = UserService() // <-- replace this with your implementation
|
||||||
@ -54,7 +55,8 @@ val myUserService : UserService = UserService() // <-- replace this with your im
|
|||||||
/** This is your main entry point for your REST service
|
/** This is your main entry point for your REST service
|
||||||
* It extends BaseApp which defines the business logic for your services
|
* It extends BaseApp which defines the business logic for your services
|
||||||
*/
|
*/
|
||||||
object Server extends BaseApp(appPetService = myPetService,
|
object Server extends BaseApp(appComplexRouteService = myComplexRouteService,
|
||||||
|
appPetService = myPetService,
|
||||||
appStoreService = myStoreService,
|
appStoreService = myStoreService,
|
||||||
appUserService = myUserService):
|
appUserService = myUserService):
|
||||||
start()
|
start()
|
||||||
|
@ -27,6 +27,35 @@
|
|||||||
"name" : "user"
|
"name" : "user"
|
||||||
} ],
|
} ],
|
||||||
"paths" : {
|
"paths" : {
|
||||||
|
"/complex-types" : {
|
||||||
|
"post" : {
|
||||||
|
"operationId" : "oneOfRequestAndResponse",
|
||||||
|
"requestBody" : {
|
||||||
|
"content" : {
|
||||||
|
"application/json" : {
|
||||||
|
"schema" : {
|
||||||
|
"$ref" : "#/components/schemas/oneOfRequestAndResponse_request"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required" : true
|
||||||
|
},
|
||||||
|
"responses" : {
|
||||||
|
"200" : {
|
||||||
|
"content" : {
|
||||||
|
"application/json" : {
|
||||||
|
"schema" : {
|
||||||
|
"$ref" : "#/components/schemas/oneOfRequestAndResponse_200_response"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"description" : "Success"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"summary" : "Example route with 'oneOf' content and response",
|
||||||
|
"tags" : [ "complexRoute" ]
|
||||||
|
}
|
||||||
|
},
|
||||||
"/pet" : {
|
"/pet" : {
|
||||||
"post" : {
|
"post" : {
|
||||||
"description" : "",
|
"description" : "",
|
||||||
@ -981,6 +1010,154 @@
|
|||||||
"title" : "An uploaded response",
|
"title" : "An uploaded response",
|
||||||
"type" : "object"
|
"type" : "object"
|
||||||
},
|
},
|
||||||
|
"ComplexRequest" : {
|
||||||
|
"additionalProperties" : {
|
||||||
|
"description" : "Additional properties are allowed beyond the defined fields",
|
||||||
|
"type" : "object"
|
||||||
|
},
|
||||||
|
"properties" : {
|
||||||
|
"type" : {
|
||||||
|
"enum" : [ "someEnum" ],
|
||||||
|
"type" : "string"
|
||||||
|
},
|
||||||
|
"requiredField" : {
|
||||||
|
"description" : "A required string field",
|
||||||
|
"type" : "string"
|
||||||
|
},
|
||||||
|
"stringField" : {
|
||||||
|
"description" : "String with length constraints",
|
||||||
|
"maxLength" : 100,
|
||||||
|
"minLength" : 5,
|
||||||
|
"type" : "string"
|
||||||
|
},
|
||||||
|
"integerField" : {
|
||||||
|
"description" : "Integer with a range from 1 to 100",
|
||||||
|
"maximum" : 100,
|
||||||
|
"minimum" : 1,
|
||||||
|
"type" : "integer"
|
||||||
|
},
|
||||||
|
"numberField" : {
|
||||||
|
"description" : "Number with exclusive minimum and maximum constraints",
|
||||||
|
"type" : "number"
|
||||||
|
},
|
||||||
|
"booleanField" : {
|
||||||
|
"description" : "A boolean field",
|
||||||
|
"type" : "boolean"
|
||||||
|
},
|
||||||
|
"emailField" : {
|
||||||
|
"description" : "A valid email address",
|
||||||
|
"format" : "email",
|
||||||
|
"type" : "string"
|
||||||
|
},
|
||||||
|
"uuidField" : {
|
||||||
|
"description" : "A valid UUID",
|
||||||
|
"format" : "uuid",
|
||||||
|
"type" : "string"
|
||||||
|
},
|
||||||
|
"dateField" : {
|
||||||
|
"description" : "A date field (YYYY-MM-DD)",
|
||||||
|
"format" : "date",
|
||||||
|
"type" : "string"
|
||||||
|
},
|
||||||
|
"dateTimeField" : {
|
||||||
|
"description" : "A date-time field (RFC 3339 format)",
|
||||||
|
"format" : "date-time",
|
||||||
|
"type" : "string"
|
||||||
|
},
|
||||||
|
"arrayField" : {
|
||||||
|
"description" : "An array of strings with min and max items constraints",
|
||||||
|
"items" : {
|
||||||
|
"type" : "string"
|
||||||
|
},
|
||||||
|
"maxItems" : 10,
|
||||||
|
"minItems" : 1,
|
||||||
|
"type" : "array"
|
||||||
|
},
|
||||||
|
"enumField" : {
|
||||||
|
"description" : "A string field with enum validation",
|
||||||
|
"enum" : [ "value1", "value2", "value3" ],
|
||||||
|
"type" : "string"
|
||||||
|
},
|
||||||
|
"nestedObject" : {
|
||||||
|
"$ref" : "#/components/schemas/ComplexRequest_nestedObject"
|
||||||
|
},
|
||||||
|
"arrayOfObjectsField" : {
|
||||||
|
"items" : {
|
||||||
|
"$ref" : "#/components/schemas/ComplexRequest_arrayOfObjectsField_inner"
|
||||||
|
},
|
||||||
|
"type" : "array"
|
||||||
|
},
|
||||||
|
"patternField" : {
|
||||||
|
"description" : "A string field with regex pattern validation",
|
||||||
|
"pattern" : "^[a-zA-Z0-9]{3,10}$",
|
||||||
|
"type" : "string"
|
||||||
|
},
|
||||||
|
"nullableField" : {
|
||||||
|
"description" : "A string field that allows null values",
|
||||||
|
"nullable" : true,
|
||||||
|
"type" : "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required" : [ "requiredField", "type" ],
|
||||||
|
"type" : "object"
|
||||||
|
},
|
||||||
|
"AllOfRequest" : {
|
||||||
|
"properties" : {
|
||||||
|
"name" : {
|
||||||
|
"type" : "string"
|
||||||
|
},
|
||||||
|
"age" : {
|
||||||
|
"type" : "integer"
|
||||||
|
},
|
||||||
|
"details" : {
|
||||||
|
"$ref" : "#/components/schemas/AllOfRequest_details"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required" : [ "age", "name" ],
|
||||||
|
"type" : "object"
|
||||||
|
},
|
||||||
|
"SomeResponse1" : {
|
||||||
|
"properties" : {
|
||||||
|
"status" : {
|
||||||
|
"type" : "string"
|
||||||
|
},
|
||||||
|
"message" : {
|
||||||
|
"type" : "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required" : [ "message", "status" ],
|
||||||
|
"type" : "object"
|
||||||
|
},
|
||||||
|
"SomeResponse2" : {
|
||||||
|
"properties" : {
|
||||||
|
"id" : {
|
||||||
|
"type" : "string"
|
||||||
|
},
|
||||||
|
"created_at" : {
|
||||||
|
"format" : "date-time",
|
||||||
|
"type" : "string"
|
||||||
|
},
|
||||||
|
"details" : {
|
||||||
|
"$ref" : "#/components/schemas/SomeResponse2_details"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required" : [ "created_at", "id" ],
|
||||||
|
"type" : "object"
|
||||||
|
},
|
||||||
|
"oneOfRequestAndResponse_request" : {
|
||||||
|
"oneOf" : [ {
|
||||||
|
"$ref" : "#/components/schemas/ComplexRequest"
|
||||||
|
}, {
|
||||||
|
"$ref" : "#/components/schemas/AllOfRequest"
|
||||||
|
} ]
|
||||||
|
},
|
||||||
|
"oneOfRequestAndResponse_200_response" : {
|
||||||
|
"oneOf" : [ {
|
||||||
|
"$ref" : "#/components/schemas/SomeResponse1"
|
||||||
|
}, {
|
||||||
|
"$ref" : "#/components/schemas/SomeResponse2"
|
||||||
|
} ]
|
||||||
|
},
|
||||||
"updatePetWithForm_request" : {
|
"updatePetWithForm_request" : {
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"name" : {
|
"name" : {
|
||||||
@ -1007,6 +1184,59 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"type" : "object"
|
"type" : "object"
|
||||||
|
},
|
||||||
|
"ComplexRequest_nestedObject" : {
|
||||||
|
"properties" : {
|
||||||
|
"nestedField1" : {
|
||||||
|
"description" : "A field within a nested object",
|
||||||
|
"type" : "string"
|
||||||
|
},
|
||||||
|
"nestedField2" : {
|
||||||
|
"description" : "Another field in a nested object",
|
||||||
|
"type" : "integer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type" : "object"
|
||||||
|
},
|
||||||
|
"ComplexRequest_arrayOfObjectsField_inner" : {
|
||||||
|
"description" : "An array of objects",
|
||||||
|
"properties" : {
|
||||||
|
"objectField1" : {
|
||||||
|
"type" : "string"
|
||||||
|
},
|
||||||
|
"objectField2" : {
|
||||||
|
"type" : "integer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type" : "object"
|
||||||
|
},
|
||||||
|
"AllOfRequest_details" : {
|
||||||
|
"allOf" : [ {
|
||||||
|
"properties" : {
|
||||||
|
"address" : {
|
||||||
|
"type" : "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type" : "object"
|
||||||
|
}, {
|
||||||
|
"properties" : {
|
||||||
|
"contact_number" : {
|
||||||
|
"type" : "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type" : "object"
|
||||||
|
} ]
|
||||||
|
},
|
||||||
|
"SomeResponse2_details" : {
|
||||||
|
"properties" : {
|
||||||
|
"description" : {
|
||||||
|
"type" : "string"
|
||||||
|
},
|
||||||
|
"status" : {
|
||||||
|
"type" : "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type" : "object"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"securitySchemes" : {
|
"securitySchemes" : {
|
||||||
|
@ -37,6 +37,9 @@ import _root_.sample.cask.api.*
|
|||||||
* More typically, however, you would extend the 'BaseApp' class
|
* More typically, however, you would extend the 'BaseApp' class
|
||||||
*/
|
*/
|
||||||
trait AppRoutes {
|
trait AppRoutes {
|
||||||
|
def appComplexRouteService : ComplexRouteService[Try] = ComplexRouteService()
|
||||||
|
def routeForComplexRoute : ComplexRouteRoutes = ComplexRouteRoutes(appComplexRouteService)
|
||||||
|
|
||||||
def appPetService : PetService[Try] = PetService()
|
def appPetService : PetService[Try] = PetService()
|
||||||
def routeForPet : PetRoutes = PetRoutes(appPetService)
|
def routeForPet : PetRoutes = PetRoutes(appPetService)
|
||||||
|
|
||||||
@ -48,6 +51,7 @@ trait AppRoutes {
|
|||||||
|
|
||||||
|
|
||||||
def appRoutes = Seq(
|
def appRoutes = Seq(
|
||||||
|
routeForComplexRoute ,
|
||||||
routeForPet ,
|
routeForPet ,
|
||||||
routeForStore ,
|
routeForStore ,
|
||||||
routeForUser
|
routeForUser
|
||||||
|
@ -27,6 +27,8 @@ import _root_.sample.cask.api.*
|
|||||||
* passing in the custom business logic services
|
* passing in the custom business logic services
|
||||||
*/
|
*/
|
||||||
class BaseApp(
|
class BaseApp(
|
||||||
|
override val appComplexRouteService : ComplexRouteService[Try] = ComplexRouteService(),
|
||||||
|
|
||||||
override val appPetService : PetService[Try] = PetService(),
|
override val appPetService : PetService[Try] = PetService(),
|
||||||
|
|
||||||
override val appStoreService : StoreService[Try] = StoreService(),
|
override val appStoreService : StoreService[Try] = StoreService(),
|
||||||
|
@ -0,0 +1,59 @@
|
|||||||
|
//> using scala "3.3.1"
|
||||||
|
//> using lib "com.lihaoyi::cask:0.8.3"
|
||||||
|
//> using lib "com.lihaoyi::scalatags:0.12.0"
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* OpenAPI spec version: 1.0.0
|
||||||
|
*
|
||||||
|
* Contact: team@openapitools.org
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||||
|
*
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// this is generated from apiRoutes.mustache
|
||||||
|
package sample.cask.api
|
||||||
|
|
||||||
|
import sample.cask.model.*
|
||||||
|
|
||||||
|
import upickle.default.{ReadWriter => RW, macroRW}
|
||||||
|
import upickle.default.*
|
||||||
|
import scala.util.Try
|
||||||
|
|
||||||
|
import sample.cask.model.OneOfRequestAndResponse200Response
|
||||||
|
import sample.cask.model.OneOfRequestAndResponseRequest
|
||||||
|
|
||||||
|
class ComplexRouteRoutes(service : ComplexRouteService[Try]) extends cask.Routes {
|
||||||
|
|
||||||
|
|
||||||
|
/** Example route with 'oneOf' content and response
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@cask.post("/complex-types")
|
||||||
|
def oneOfRequestAndResponse(request: cask.Request) = {
|
||||||
|
|
||||||
|
def failFast = request.queryParams.keySet.contains("failFast")
|
||||||
|
|
||||||
|
val result = for {
|
||||||
|
oneOfRequestAndResponseRequestJson <- Parsed.fromTry(request.bodyAsJson)
|
||||||
|
oneOfRequestAndResponseRequestData <- Parsed.eval(OneOfRequestAndResponseRequestData.fromJson(oneOfRequestAndResponseRequestJson)) /* not array or map */
|
||||||
|
oneOfRequestAndResponseRequest <- Parsed.fromTry(OneOfRequestAndResponseRequestData.validated(oneOfRequestAndResponseRequestData, failFast))
|
||||||
|
resultTry <- Parsed.eval(service.oneOfRequestAndResponse(oneOfRequestAndResponseRequest))
|
||||||
|
result <- Parsed.fromTry(resultTry)
|
||||||
|
} yield result
|
||||||
|
|
||||||
|
import OneOfRequestAndResponse200Response.{given, *} // this brings in upickle in the case of union (oneOf) types
|
||||||
|
|
||||||
|
(result : @unchecked) match {
|
||||||
|
case Left(error) => cask.Response(error, 500)
|
||||||
|
case Right(value : OneOfRequestAndResponse200Response) => cask.Response(data = write(value), 200, headers = Seq("Content-Type" -> "application/json"))
|
||||||
|
case Right(other) => cask.Response(s"$other", 200)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
initialize()
|
||||||
|
}
|
@ -63,11 +63,13 @@ class PetRoutes(service : PetService[Try]) extends cask.Routes {
|
|||||||
val result = for {
|
val result = for {
|
||||||
petJson <- Parsed.fromTry(request.bodyAsJson)
|
petJson <- Parsed.fromTry(request.bodyAsJson)
|
||||||
petData <- Parsed.eval(PetData.fromJson(petJson)) /* not array or map */
|
petData <- Parsed.eval(PetData.fromJson(petJson)) /* not array or map */
|
||||||
pet <- Parsed.fromTry(petData.validated(failFast))
|
pet <- Parsed.fromTry(PetData.validated(petData, failFast))
|
||||||
resultTry <- Parsed.eval(service.addPet(pet))
|
resultTry <- Parsed.eval(service.addPet(pet))
|
||||||
result <- Parsed.fromTry(resultTry)
|
result <- Parsed.fromTry(resultTry)
|
||||||
} yield result
|
} yield result
|
||||||
|
|
||||||
|
import Pet.{given, *} // this brings in upickle in the case of union (oneOf) types
|
||||||
|
|
||||||
(result : @unchecked) match {
|
(result : @unchecked) match {
|
||||||
case Left(error) => cask.Response(error, 500)
|
case Left(error) => cask.Response(error, 500)
|
||||||
case Right(value : Pet) => cask.Response(data = write(value), 200, headers = Seq("Content-Type" -> "application/json"))
|
case Right(value : Pet) => cask.Response(data = write(value), 200, headers = Seq("Content-Type" -> "application/json"))
|
||||||
@ -90,6 +92,7 @@ class PetRoutes(service : PetService[Try]) extends cask.Routes {
|
|||||||
result <- Parsed.fromTry(resultTry)
|
result <- Parsed.fromTry(resultTry)
|
||||||
} yield result
|
} yield result
|
||||||
|
|
||||||
|
|
||||||
(result : @unchecked) match {
|
(result : @unchecked) match {
|
||||||
case Left(error) => cask.Response(error, 500)
|
case Left(error) => cask.Response(error, 500)
|
||||||
case Right(other) => cask.Response(s"$other", 200)
|
case Right(other) => cask.Response(s"$other", 200)
|
||||||
@ -109,6 +112,7 @@ class PetRoutes(service : PetService[Try]) extends cask.Routes {
|
|||||||
result <- Parsed.fromTry(resultTry)
|
result <- Parsed.fromTry(resultTry)
|
||||||
} yield result
|
} yield result
|
||||||
|
|
||||||
|
|
||||||
(result : @unchecked) match {
|
(result : @unchecked) match {
|
||||||
case Left(error) => cask.Response(error, 500)
|
case Left(error) => cask.Response(error, 500)
|
||||||
case Right(value : List[Pet]) => cask.Response(data = write(value), 200, headers = Seq("Content-Type" -> "application/json"))
|
case Right(value : List[Pet]) => cask.Response(data = write(value), 200, headers = Seq("Content-Type" -> "application/json"))
|
||||||
@ -129,6 +133,7 @@ class PetRoutes(service : PetService[Try]) extends cask.Routes {
|
|||||||
result <- Parsed.fromTry(resultTry)
|
result <- Parsed.fromTry(resultTry)
|
||||||
} yield result
|
} yield result
|
||||||
|
|
||||||
|
|
||||||
(result : @unchecked) match {
|
(result : @unchecked) match {
|
||||||
case Left(error) => cask.Response(error, 500)
|
case Left(error) => cask.Response(error, 500)
|
||||||
case Right(value : List[Pet]) => cask.Response(data = write(value), 200, headers = Seq("Content-Type" -> "application/json"))
|
case Right(value : List[Pet]) => cask.Response(data = write(value), 200, headers = Seq("Content-Type" -> "application/json"))
|
||||||
@ -150,6 +155,8 @@ class PetRoutes(service : PetService[Try]) extends cask.Routes {
|
|||||||
result <- Parsed.fromTry(resultTry)
|
result <- Parsed.fromTry(resultTry)
|
||||||
} yield result
|
} yield result
|
||||||
|
|
||||||
|
import Pet.{given, *} // this brings in upickle in the case of union (oneOf) types
|
||||||
|
|
||||||
(result : @unchecked) match {
|
(result : @unchecked) match {
|
||||||
case Left(error) => cask.Response(error, 500)
|
case Left(error) => cask.Response(error, 500)
|
||||||
case Right(value : Pet) => cask.Response(data = write(value), 200, headers = Seq("Content-Type" -> "application/json"))
|
case Right(value : Pet) => cask.Response(data = write(value), 200, headers = Seq("Content-Type" -> "application/json"))
|
||||||
@ -168,11 +175,13 @@ class PetRoutes(service : PetService[Try]) extends cask.Routes {
|
|||||||
val result = for {
|
val result = for {
|
||||||
petJson <- Parsed.fromTry(request.bodyAsJson)
|
petJson <- Parsed.fromTry(request.bodyAsJson)
|
||||||
petData <- Parsed.eval(PetData.fromJson(petJson)) /* not array or map */
|
petData <- Parsed.eval(PetData.fromJson(petJson)) /* not array or map */
|
||||||
pet <- Parsed.fromTry(petData.validated(failFast))
|
pet <- Parsed.fromTry(PetData.validated(petData, failFast))
|
||||||
resultTry <- Parsed.eval(service.updatePet(pet))
|
resultTry <- Parsed.eval(service.updatePet(pet))
|
||||||
result <- Parsed.fromTry(resultTry)
|
result <- Parsed.fromTry(resultTry)
|
||||||
} yield result
|
} yield result
|
||||||
|
|
||||||
|
import Pet.{given, *} // this brings in upickle in the case of union (oneOf) types
|
||||||
|
|
||||||
(result : @unchecked) match {
|
(result : @unchecked) match {
|
||||||
case Left(error) => cask.Response(error, 500)
|
case Left(error) => cask.Response(error, 500)
|
||||||
case Right(value : Pet) => cask.Response(data = write(value), 200, headers = Seq("Content-Type" -> "application/json"))
|
case Right(value : Pet) => cask.Response(data = write(value), 200, headers = Seq("Content-Type" -> "application/json"))
|
||||||
@ -196,6 +205,7 @@ class PetRoutes(service : PetService[Try]) extends cask.Routes {
|
|||||||
result <- Parsed.fromTry(resultTry)
|
result <- Parsed.fromTry(resultTry)
|
||||||
} yield result
|
} yield result
|
||||||
|
|
||||||
|
|
||||||
(result : @unchecked) match {
|
(result : @unchecked) match {
|
||||||
case Left(error) => cask.Response(error, 500)
|
case Left(error) => cask.Response(error, 500)
|
||||||
case Right(other) => cask.Response(s"$other", 200)
|
case Right(other) => cask.Response(s"$other", 200)
|
||||||
@ -218,6 +228,8 @@ class PetRoutes(service : PetService[Try]) extends cask.Routes {
|
|||||||
result <- Parsed.fromTry(resultTry)
|
result <- Parsed.fromTry(resultTry)
|
||||||
} yield result
|
} yield result
|
||||||
|
|
||||||
|
import ApiResponse.{given, *} // this brings in upickle in the case of union (oneOf) types
|
||||||
|
|
||||||
(result : @unchecked) match {
|
(result : @unchecked) match {
|
||||||
case Left(error) => cask.Response(error, 500)
|
case Left(error) => cask.Response(error, 500)
|
||||||
case Right(value : ApiResponse) => cask.Response(data = write(value), 200, headers = Seq("Content-Type" -> "application/json"))
|
case Right(value : ApiResponse) => cask.Response(data = write(value), 200, headers = Seq("Content-Type" -> "application/json"))
|
||||||
|
@ -43,6 +43,7 @@ class StoreRoutes(service : StoreService[Try]) extends cask.Routes {
|
|||||||
result <- Parsed.fromTry(resultTry)
|
result <- Parsed.fromTry(resultTry)
|
||||||
} yield result
|
} yield result
|
||||||
|
|
||||||
|
|
||||||
(result : @unchecked) match {
|
(result : @unchecked) match {
|
||||||
case Left(error) => cask.Response(error, 500)
|
case Left(error) => cask.Response(error, 500)
|
||||||
case Right(other) => cask.Response(s"$other", 200)
|
case Right(other) => cask.Response(s"$other", 200)
|
||||||
@ -62,6 +63,7 @@ class StoreRoutes(service : StoreService[Try]) extends cask.Routes {
|
|||||||
result <- Parsed.fromTry(resultTry)
|
result <- Parsed.fromTry(resultTry)
|
||||||
} yield result
|
} yield result
|
||||||
|
|
||||||
|
|
||||||
(result : @unchecked) match {
|
(result : @unchecked) match {
|
||||||
case Left(error) => cask.Response(error, 500)
|
case Left(error) => cask.Response(error, 500)
|
||||||
case Right(value : Map[String, Int]) => cask.Response(data = write(value), 200, headers = Seq("Content-Type" -> "application/json"))
|
case Right(value : Map[String, Int]) => cask.Response(data = write(value), 200, headers = Seq("Content-Type" -> "application/json"))
|
||||||
@ -82,6 +84,8 @@ class StoreRoutes(service : StoreService[Try]) extends cask.Routes {
|
|||||||
result <- Parsed.fromTry(resultTry)
|
result <- Parsed.fromTry(resultTry)
|
||||||
} yield result
|
} yield result
|
||||||
|
|
||||||
|
import Order.{given, *} // this brings in upickle in the case of union (oneOf) types
|
||||||
|
|
||||||
(result : @unchecked) match {
|
(result : @unchecked) match {
|
||||||
case Left(error) => cask.Response(error, 500)
|
case Left(error) => cask.Response(error, 500)
|
||||||
case Right(value : Order) => cask.Response(data = write(value), 200, headers = Seq("Content-Type" -> "application/json"))
|
case Right(value : Order) => cask.Response(data = write(value), 200, headers = Seq("Content-Type" -> "application/json"))
|
||||||
@ -99,11 +103,13 @@ class StoreRoutes(service : StoreService[Try]) extends cask.Routes {
|
|||||||
val result = for {
|
val result = for {
|
||||||
orderJson <- Parsed.fromTry(request.bodyAsJson)
|
orderJson <- Parsed.fromTry(request.bodyAsJson)
|
||||||
orderData <- Parsed.eval(OrderData.fromJson(orderJson)) /* not array or map */
|
orderData <- Parsed.eval(OrderData.fromJson(orderJson)) /* not array or map */
|
||||||
order <- Parsed.fromTry(orderData.validated(failFast))
|
order <- Parsed.fromTry(OrderData.validated(orderData, failFast))
|
||||||
resultTry <- Parsed.eval(service.placeOrder(order))
|
resultTry <- Parsed.eval(service.placeOrder(order))
|
||||||
result <- Parsed.fromTry(resultTry)
|
result <- Parsed.fromTry(resultTry)
|
||||||
} yield result
|
} yield result
|
||||||
|
|
||||||
|
import Order.{given, *} // this brings in upickle in the case of union (oneOf) types
|
||||||
|
|
||||||
(result : @unchecked) match {
|
(result : @unchecked) match {
|
||||||
case Left(error) => cask.Response(error, 500)
|
case Left(error) => cask.Response(error, 500)
|
||||||
case Right(value : Order) => cask.Response(data = write(value), 200, headers = Seq("Content-Type" -> "application/json"))
|
case Right(value : Order) => cask.Response(data = write(value), 200, headers = Seq("Content-Type" -> "application/json"))
|
||||||
|
@ -52,11 +52,12 @@ class UserRoutes(service : UserService[Try]) extends cask.Routes {
|
|||||||
val result = for {
|
val result = for {
|
||||||
userJson <- Parsed.fromTry(request.bodyAsJson)
|
userJson <- Parsed.fromTry(request.bodyAsJson)
|
||||||
userData <- Parsed.eval(UserData.fromJson(userJson)) /* not array or map */
|
userData <- Parsed.eval(UserData.fromJson(userJson)) /* not array or map */
|
||||||
user <- Parsed.fromTry(userData.validated(failFast))
|
user <- Parsed.fromTry(UserData.validated(userData, failFast))
|
||||||
resultTry <- Parsed.eval(service.createUser(user))
|
resultTry <- Parsed.eval(service.createUser(user))
|
||||||
result <- Parsed.fromTry(resultTry)
|
result <- Parsed.fromTry(resultTry)
|
||||||
} yield result
|
} yield result
|
||||||
|
|
||||||
|
|
||||||
(result : @unchecked) match {
|
(result : @unchecked) match {
|
||||||
case Left(error) => cask.Response(error, 500)
|
case Left(error) => cask.Response(error, 500)
|
||||||
case Right(other) => cask.Response(s"$other", 200)
|
case Right(other) => cask.Response(s"$other", 200)
|
||||||
@ -77,6 +78,7 @@ class UserRoutes(service : UserService[Try]) extends cask.Routes {
|
|||||||
result <- Parsed.fromTry(resultTry)
|
result <- Parsed.fromTry(resultTry)
|
||||||
} yield result
|
} yield result
|
||||||
|
|
||||||
|
|
||||||
(result : @unchecked) match {
|
(result : @unchecked) match {
|
||||||
case Left(error) => cask.Response(error, 500)
|
case Left(error) => cask.Response(error, 500)
|
||||||
case Right(other) => cask.Response(s"$other", 200)
|
case Right(other) => cask.Response(s"$other", 200)
|
||||||
@ -97,6 +99,7 @@ class UserRoutes(service : UserService[Try]) extends cask.Routes {
|
|||||||
result <- Parsed.fromTry(resultTry)
|
result <- Parsed.fromTry(resultTry)
|
||||||
} yield result
|
} yield result
|
||||||
|
|
||||||
|
|
||||||
(result : @unchecked) match {
|
(result : @unchecked) match {
|
||||||
case Left(error) => cask.Response(error, 500)
|
case Left(error) => cask.Response(error, 500)
|
||||||
case Right(other) => cask.Response(s"$other", 200)
|
case Right(other) => cask.Response(s"$other", 200)
|
||||||
@ -117,6 +120,7 @@ class UserRoutes(service : UserService[Try]) extends cask.Routes {
|
|||||||
result <- Parsed.fromTry(resultTry)
|
result <- Parsed.fromTry(resultTry)
|
||||||
} yield result
|
} yield result
|
||||||
|
|
||||||
|
|
||||||
(result : @unchecked) match {
|
(result : @unchecked) match {
|
||||||
case Left(error) => cask.Response(error, 500)
|
case Left(error) => cask.Response(error, 500)
|
||||||
case Right(other) => cask.Response(s"$other", 200)
|
case Right(other) => cask.Response(s"$other", 200)
|
||||||
@ -136,6 +140,8 @@ class UserRoutes(service : UserService[Try]) extends cask.Routes {
|
|||||||
result <- Parsed.fromTry(resultTry)
|
result <- Parsed.fromTry(resultTry)
|
||||||
} yield result
|
} yield result
|
||||||
|
|
||||||
|
import User.{given, *} // this brings in upickle in the case of union (oneOf) types
|
||||||
|
|
||||||
(result : @unchecked) match {
|
(result : @unchecked) match {
|
||||||
case Left(error) => cask.Response(error, 500)
|
case Left(error) => cask.Response(error, 500)
|
||||||
case Right(value : User) => cask.Response(data = write(value), 200, headers = Seq("Content-Type" -> "application/json"))
|
case Right(value : User) => cask.Response(data = write(value), 200, headers = Seq("Content-Type" -> "application/json"))
|
||||||
@ -155,6 +161,7 @@ class UserRoutes(service : UserService[Try]) extends cask.Routes {
|
|||||||
result <- Parsed.fromTry(resultTry)
|
result <- Parsed.fromTry(resultTry)
|
||||||
} yield result
|
} yield result
|
||||||
|
|
||||||
|
|
||||||
(result : @unchecked) match {
|
(result : @unchecked) match {
|
||||||
case Left(error) => cask.Response(error, 500)
|
case Left(error) => cask.Response(error, 500)
|
||||||
case Right(value : String) => cask.Response(data = write(value), 200, headers = Seq("Content-Type" -> "application/json"))
|
case Right(value : String) => cask.Response(data = write(value), 200, headers = Seq("Content-Type" -> "application/json"))
|
||||||
@ -175,6 +182,7 @@ class UserRoutes(service : UserService[Try]) extends cask.Routes {
|
|||||||
result <- Parsed.fromTry(resultTry)
|
result <- Parsed.fromTry(resultTry)
|
||||||
} yield result
|
} yield result
|
||||||
|
|
||||||
|
|
||||||
(result : @unchecked) match {
|
(result : @unchecked) match {
|
||||||
case Left(error) => cask.Response(error, 500)
|
case Left(error) => cask.Response(error, 500)
|
||||||
case Right(other) => cask.Response(s"$other", 200)
|
case Right(other) => cask.Response(s"$other", 200)
|
||||||
@ -193,11 +201,12 @@ class UserRoutes(service : UserService[Try]) extends cask.Routes {
|
|||||||
username <- Parsed(username)
|
username <- Parsed(username)
|
||||||
userJson <- Parsed.fromTry(request.bodyAsJson)
|
userJson <- Parsed.fromTry(request.bodyAsJson)
|
||||||
userData <- Parsed.eval(UserData.fromJson(userJson)) /* not array or map */
|
userData <- Parsed.eval(UserData.fromJson(userJson)) /* not array or map */
|
||||||
user <- Parsed.fromTry(userData.validated(failFast))
|
user <- Parsed.fromTry(UserData.validated(userData, failFast))
|
||||||
resultTry <- Parsed.eval(service.updateUser(username, user))
|
resultTry <- Parsed.eval(service.updateUser(username, user))
|
||||||
result <- Parsed.fromTry(resultTry)
|
result <- Parsed.fromTry(resultTry)
|
||||||
} yield result
|
} yield result
|
||||||
|
|
||||||
|
|
||||||
(result : @unchecked) match {
|
(result : @unchecked) match {
|
||||||
case Left(error) => cask.Response(error, 500)
|
case Left(error) => cask.Response(error, 500)
|
||||||
case Right(other) => cask.Response(s"$other", 200)
|
case Right(other) => cask.Response(s"$other", 200)
|
||||||
|
@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* OpenAPI spec version: 1.0.0
|
||||||
|
*
|
||||||
|
* Contact: team@openapitools.org
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||||
|
*
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
*/
|
||||||
|
|
||||||
|
// this model was generated using modelTest.mustache
|
||||||
|
package sample.cask.model
|
||||||
|
|
||||||
|
import org.scalatest.matchers.should.Matchers
|
||||||
|
import org.scalatest.wordspec.AnyWordSpec
|
||||||
|
import scala.util.*
|
||||||
|
|
||||||
|
class AllOfRequestDetailsTest extends AnyWordSpec with Matchers {
|
||||||
|
|
||||||
|
|
||||||
|
"AllOfRequestDetails.fromJson" should {
|
||||||
|
"""not parse invalid json""" in {
|
||||||
|
val Failure(err) = Try(AllOfRequestDetailsData.fromJsonString("invalid jason"))
|
||||||
|
err.getMessage should startWith ("Error parsing json 'invalid jason'")
|
||||||
|
}
|
||||||
|
"""parse """ ignore {
|
||||||
|
val d8a = AllOfRequestDetailsData.fromJsonString("""""")
|
||||||
|
val Failure(err : ValidationErrors) = AllOfRequestDetailsData.validated(d8a, true)
|
||||||
|
|
||||||
|
sys.error("TODO")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* OpenAPI spec version: 1.0.0
|
||||||
|
*
|
||||||
|
* Contact: team@openapitools.org
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||||
|
*
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
*/
|
||||||
|
|
||||||
|
// this model was generated using modelTest.mustache
|
||||||
|
package sample.cask.model
|
||||||
|
|
||||||
|
import org.scalatest.matchers.should.Matchers
|
||||||
|
import org.scalatest.wordspec.AnyWordSpec
|
||||||
|
import scala.util.*
|
||||||
|
|
||||||
|
class AllOfRequestTest extends AnyWordSpec with Matchers {
|
||||||
|
|
||||||
|
|
||||||
|
"AllOfRequest.fromJson" should {
|
||||||
|
"""not parse invalid json""" in {
|
||||||
|
val Failure(err) = Try(AllOfRequestData.fromJsonString("invalid jason"))
|
||||||
|
err.getMessage should startWith ("Error parsing json 'invalid jason'")
|
||||||
|
}
|
||||||
|
"""parse """ ignore {
|
||||||
|
val d8a = AllOfRequestData.fromJsonString("""""")
|
||||||
|
val Failure(err : ValidationErrors) = AllOfRequestData.validated(d8a, true)
|
||||||
|
|
||||||
|
sys.error("TODO")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* OpenAPI spec version: 1.0.0
|
||||||
|
*
|
||||||
|
* Contact: team@openapitools.org
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||||
|
*
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
*/
|
||||||
|
|
||||||
|
// this model was generated using modelTest.mustache
|
||||||
|
package sample.cask.model
|
||||||
|
|
||||||
|
import org.scalatest.matchers.should.Matchers
|
||||||
|
import org.scalatest.wordspec.AnyWordSpec
|
||||||
|
import scala.util.*
|
||||||
|
|
||||||
|
class ComplexRequestArrayOfObjectsFieldInnerTest extends AnyWordSpec with Matchers {
|
||||||
|
|
||||||
|
|
||||||
|
"ComplexRequestArrayOfObjectsFieldInner.fromJson" should {
|
||||||
|
"""not parse invalid json""" in {
|
||||||
|
val Failure(err) = Try(ComplexRequestArrayOfObjectsFieldInnerData.fromJsonString("invalid jason"))
|
||||||
|
err.getMessage should startWith ("Error parsing json 'invalid jason'")
|
||||||
|
}
|
||||||
|
"""parse """ ignore {
|
||||||
|
val d8a = ComplexRequestArrayOfObjectsFieldInnerData.fromJsonString("""""")
|
||||||
|
val Failure(err : ValidationErrors) = ComplexRequestArrayOfObjectsFieldInnerData.validated(d8a, true)
|
||||||
|
|
||||||
|
sys.error("TODO")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* OpenAPI spec version: 1.0.0
|
||||||
|
*
|
||||||
|
* Contact: team@openapitools.org
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||||
|
*
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
*/
|
||||||
|
|
||||||
|
// this model was generated using modelTest.mustache
|
||||||
|
package sample.cask.model
|
||||||
|
|
||||||
|
import org.scalatest.matchers.should.Matchers
|
||||||
|
import org.scalatest.wordspec.AnyWordSpec
|
||||||
|
import scala.util.*
|
||||||
|
|
||||||
|
class ComplexRequestNestedObjectTest extends AnyWordSpec with Matchers {
|
||||||
|
|
||||||
|
|
||||||
|
"ComplexRequestNestedObject.fromJson" should {
|
||||||
|
"""not parse invalid json""" in {
|
||||||
|
val Failure(err) = Try(ComplexRequestNestedObjectData.fromJsonString("invalid jason"))
|
||||||
|
err.getMessage should startWith ("Error parsing json 'invalid jason'")
|
||||||
|
}
|
||||||
|
"""parse """ ignore {
|
||||||
|
val d8a = ComplexRequestNestedObjectData.fromJsonString("""""")
|
||||||
|
val Failure(err : ValidationErrors) = ComplexRequestNestedObjectData.validated(d8a, true)
|
||||||
|
|
||||||
|
sys.error("TODO")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* OpenAPI spec version: 1.0.0
|
||||||
|
*
|
||||||
|
* Contact: team@openapitools.org
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||||
|
*
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
*/
|
||||||
|
|
||||||
|
// this model was generated using modelTest.mustache
|
||||||
|
package sample.cask.model
|
||||||
|
import java.time.LocalDate
|
||||||
|
import java.time.OffsetDateTime
|
||||||
|
import java.util.UUID
|
||||||
|
import scala.math.BigDecimal
|
||||||
|
import ujson.Value
|
||||||
|
|
||||||
|
import org.scalatest.matchers.should.Matchers
|
||||||
|
import org.scalatest.wordspec.AnyWordSpec
|
||||||
|
import scala.util.*
|
||||||
|
|
||||||
|
class ComplexRequestTest extends AnyWordSpec with Matchers {
|
||||||
|
|
||||||
|
|
||||||
|
"ComplexRequest.fromJson" should {
|
||||||
|
"""not parse invalid json""" in {
|
||||||
|
val Failure(err) = Try(ComplexRequestData.fromJsonString("invalid jason"))
|
||||||
|
err.getMessage should startWith ("Error parsing json 'invalid jason'")
|
||||||
|
}
|
||||||
|
"""parse """ ignore {
|
||||||
|
val d8a = ComplexRequestData.fromJsonString("""""")
|
||||||
|
val Failure(err : ValidationErrors) = ComplexRequestData.validated(d8a, true)
|
||||||
|
|
||||||
|
sys.error("TODO")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
* OpenAPI Petstore
|
||||||
|
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
|
||||||
|
*
|
||||||
|
* OpenAPI spec version: 1.0.0
|
||||||
|
*
|
||||||
|
* Contact: team@openapitools.org
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||||
|
*
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
*/
|
||||||
|
|
||||||
|
// this model was generated using modelTest.mustache
|
||||||
|
package sample.cask.model
|
||||||
|
import java.time.OffsetDateTime
|
||||||
|
|
||||||
|
import org.scalatest.matchers.should.Matchers
|
||||||
|
import org.scalatest.wordspec.AnyWordSpec
|
||||||
|
import scala.util.*
|
||||||
|
|
||||||
|
class OneOfRequestAndResponse200ResponseTest extends AnyWordSpec with Matchers {
|
||||||
|
|
||||||
|
|
||||||
|
"OneOfRequestAndResponse200Response.fromJson" should {
|
||||||
|
"""not parse invalid json""" in {
|
||||||
|
val Failure(err) = Try(OneOfRequestAndResponse200ResponseData.fromJsonString("invalid jason"))
|
||||||
|
err.getMessage should startWith ("Error parsing json 'invalid jason'")
|
||||||
|
}
|
||||||
|
"""parse """ ignore {
|
||||||
|
val d8a = OneOfRequestAndResponse200ResponseData.fromJsonString("""""")
|
||||||
|
val Failure(err : ValidationErrors) = OneOfRequestAndResponse200ResponseData.validated(d8a, true)
|
||||||
|
|
||||||
|
sys.error("TODO")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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.
|
||||||
|
*
|
||||||
|
* OpenAPI spec version: 1.0.0
|
||||||
|
*
|
||||||
|
* Contact: team@openapitools.org
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||||
|
*
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
*/
|
||||||
|
|
||||||
|
// this model was generated using modelTest.mustache
|
||||||
|
package sample.cask.model
|
||||||
|
import java.time.LocalDate
|
||||||
|
import java.time.OffsetDateTime
|
||||||
|
import java.util.UUID
|
||||||
|
import scala.math.BigDecimal
|
||||||
|
|
||||||
|
import org.scalatest.matchers.should.Matchers
|
||||||
|
import org.scalatest.wordspec.AnyWordSpec
|
||||||
|
import scala.util.*
|
||||||
|
|
||||||
|
class OneOfRequestAndResponseRequestTest extends AnyWordSpec with Matchers {
|
||||||
|
|
||||||
|
|
||||||
|
"OneOfRequestAndResponseRequest.fromJson" should {
|
||||||
|
"""not parse invalid json""" in {
|
||||||
|
val Failure(err) = Try(OneOfRequestAndResponseRequestData.fromJsonString("invalid jason"))
|
||||||
|
err.getMessage should startWith ("Error parsing json 'invalid jason'")
|
||||||
|
}
|
||||||
|
"""parse """ ignore {
|
||||||
|
val d8a = OneOfRequestAndResponseRequestData.fromJsonString("""""")
|
||||||
|
val Failure(err : ValidationErrors) = OneOfRequestAndResponseRequestData.validated(d8a, true)
|
||||||
|
|
||||||
|
sys.error("TODO")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* OpenAPI spec version: 1.0.0
|
||||||
|
*
|
||||||
|
* Contact: team@openapitools.org
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||||
|
*
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
*/
|
||||||
|
|
||||||
|
// this model was generated using modelTest.mustache
|
||||||
|
package sample.cask.model
|
||||||
|
|
||||||
|
import org.scalatest.matchers.should.Matchers
|
||||||
|
import org.scalatest.wordspec.AnyWordSpec
|
||||||
|
import scala.util.*
|
||||||
|
|
||||||
|
class SomeResponse1Test extends AnyWordSpec with Matchers {
|
||||||
|
|
||||||
|
|
||||||
|
"SomeResponse1.fromJson" should {
|
||||||
|
"""not parse invalid json""" in {
|
||||||
|
val Failure(err) = Try(SomeResponse1Data.fromJsonString("invalid jason"))
|
||||||
|
err.getMessage should startWith ("Error parsing json 'invalid jason'")
|
||||||
|
}
|
||||||
|
"""parse """ ignore {
|
||||||
|
val d8a = SomeResponse1Data.fromJsonString("""""")
|
||||||
|
val Failure(err : ValidationErrors) = SomeResponse1Data.validated(d8a, true)
|
||||||
|
|
||||||
|
sys.error("TODO")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* OpenAPI spec version: 1.0.0
|
||||||
|
*
|
||||||
|
* Contact: team@openapitools.org
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||||
|
*
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
*/
|
||||||
|
|
||||||
|
// this model was generated using modelTest.mustache
|
||||||
|
package sample.cask.model
|
||||||
|
|
||||||
|
import org.scalatest.matchers.should.Matchers
|
||||||
|
import org.scalatest.wordspec.AnyWordSpec
|
||||||
|
import scala.util.*
|
||||||
|
|
||||||
|
class SomeResponse2DetailsTest extends AnyWordSpec with Matchers {
|
||||||
|
|
||||||
|
|
||||||
|
"SomeResponse2Details.fromJson" should {
|
||||||
|
"""not parse invalid json""" in {
|
||||||
|
val Failure(err) = Try(SomeResponse2DetailsData.fromJsonString("invalid jason"))
|
||||||
|
err.getMessage should startWith ("Error parsing json 'invalid jason'")
|
||||||
|
}
|
||||||
|
"""parse """ ignore {
|
||||||
|
val d8a = SomeResponse2DetailsData.fromJsonString("""""")
|
||||||
|
val Failure(err : ValidationErrors) = SomeResponse2DetailsData.validated(d8a, true)
|
||||||
|
|
||||||
|
sys.error("TODO")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
* OpenAPI Petstore
|
||||||
|
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
|
||||||
|
*
|
||||||
|
* OpenAPI spec version: 1.0.0
|
||||||
|
*
|
||||||
|
* Contact: team@openapitools.org
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||||
|
*
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
*/
|
||||||
|
|
||||||
|
// this model was generated using modelTest.mustache
|
||||||
|
package sample.cask.model
|
||||||
|
import java.time.OffsetDateTime
|
||||||
|
|
||||||
|
import org.scalatest.matchers.should.Matchers
|
||||||
|
import org.scalatest.wordspec.AnyWordSpec
|
||||||
|
import scala.util.*
|
||||||
|
|
||||||
|
class SomeResponse2Test extends AnyWordSpec with Matchers {
|
||||||
|
|
||||||
|
|
||||||
|
"SomeResponse2.fromJson" should {
|
||||||
|
"""not parse invalid json""" in {
|
||||||
|
val Failure(err) = Try(SomeResponse2Data.fromJsonString("invalid jason"))
|
||||||
|
err.getMessage should startWith ("Error parsing json 'invalid jason'")
|
||||||
|
}
|
||||||
|
"""parse """ ignore {
|
||||||
|
val d8a = SomeResponse2Data.fromJsonString("""""")
|
||||||
|
val Failure(err : ValidationErrors) = SomeResponse2Data.validated(d8a, true)
|
||||||
|
|
||||||
|
sys.error("TODO")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1 +1 @@
|
|||||||
sbt.version=1.9.9
|
sbt.version=1.10.3
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.6")
|
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.6")
|
||||||
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "1.2.0")
|
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "1.2.0")
|
||||||
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.16.0")
|
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.17.0")
|
||||||
addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.2.0")
|
addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.2.0")
|
@ -0,0 +1,118 @@
|
|||||||
|
//> using scala "3.3.1"
|
||||||
|
//> using lib "com.lihaoyi::cask:0.8.3"
|
||||||
|
//> using lib "com.lihaoyi::scalatags:0.12.0"
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* OpenAPI spec version: 1.0.0
|
||||||
|
*
|
||||||
|
* Contact: team@openapitools.org
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||||
|
*
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// generated from apiService.mustache
|
||||||
|
package sample.cask.api
|
||||||
|
|
||||||
|
import _root_.sample.cask.model.OneOfRequestAndResponse200Response
|
||||||
|
import _root_.sample.cask.model.OneOfRequestAndResponseRequest
|
||||||
|
import scala.util.Failure
|
||||||
|
import scala.util.Try
|
||||||
|
import _root_.sample.cask.model.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ComplexRouteService companion object.
|
||||||
|
*
|
||||||
|
* Use the ComplexRouteService() companion object to create an instance which returns a 'not implemented' error
|
||||||
|
* for each operation.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
object ComplexRouteService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The 'Handler' is an implementation of ComplexRouteService convenient for delegating or overriding individual functions
|
||||||
|
*/
|
||||||
|
case class Handler[F[_]](
|
||||||
|
oneOfRequestAndResponseHandler : (oneOfRequestAndResponseRequest : OneOfRequestAndResponseRequest) => F[OneOfRequestAndResponse200Response]
|
||||||
|
) extends ComplexRouteService[F] {
|
||||||
|
|
||||||
|
override def oneOfRequestAndResponse(oneOfRequestAndResponseRequest : OneOfRequestAndResponseRequest) : F[OneOfRequestAndResponse200Response] = {
|
||||||
|
oneOfRequestAndResponseHandler(oneOfRequestAndResponseRequest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def apply() : ComplexRouteService[Try] = ComplexRouteService.Handler[Try](
|
||||||
|
(_) => notImplemented("oneOfRequestAndResponse")
|
||||||
|
)
|
||||||
|
|
||||||
|
private def notImplemented(name : String) = Failure(new Exception(s"TODO: $name not implemented"))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ComplexRoute business-logic
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* The 'asHandler' will return an implementation which allows for easily overriding individual operations.
|
||||||
|
*
|
||||||
|
* equally there are "on<Function>" helper methods for easily overriding individual functions
|
||||||
|
*
|
||||||
|
* @tparam F the effect type (Future, Try, IO, ID, etc) of the operations
|
||||||
|
*/
|
||||||
|
trait ComplexRouteService[F[_]] {
|
||||||
|
/** Example route with 'oneOf' content and response
|
||||||
|
*
|
||||||
|
* @return OneOfRequestAndResponse200Response
|
||||||
|
*/
|
||||||
|
def oneOfRequestAndResponse(oneOfRequestAndResponseRequest : OneOfRequestAndResponseRequest) : F[OneOfRequestAndResponse200Response]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* override oneOfRequestAndResponse with the given handler
|
||||||
|
* @return a new implementation of ComplexRouteService[F] with oneOfRequestAndResponse overridden using the given handler
|
||||||
|
*/
|
||||||
|
final def onOneOfRequestAndResponse(handler : (oneOfRequestAndResponseRequest : OneOfRequestAndResponseRequest) => F[OneOfRequestAndResponse200Response]) : ComplexRouteService[F] = {
|
||||||
|
asHandler.copy(oneOfRequestAndResponseHandler = handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a Handler implementation of this service
|
||||||
|
*/
|
||||||
|
final def asHandler : ComplexRouteService.Handler[F] = this match {
|
||||||
|
case h : ComplexRouteService.Handler[F] => h
|
||||||
|
case _ =>
|
||||||
|
ComplexRouteService.Handler[F](
|
||||||
|
(oneOfRequestAndResponseRequest) => oneOfRequestAndResponse(oneOfRequestAndResponseRequest)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will change the effect type of this service.
|
||||||
|
*
|
||||||
|
* It's not unlike a typical map operation from A => B, except we're not mapping
|
||||||
|
* a type from A to B, but rather from F[A] => G[A] using the 'changeEffect' function.
|
||||||
|
*
|
||||||
|
* For, this could turn an asynchronous service (one which returns Future[_] types) into
|
||||||
|
* a synchronous one (one which returns Try[_] types) by awaiting on the Future.
|
||||||
|
*
|
||||||
|
* It could change an IO type (like cats effect or ZIO) into an ID[A] which is just:
|
||||||
|
* ```
|
||||||
|
* type ID[A] => A
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @tparam G the new "polymorphic" effect type
|
||||||
|
* @param changeEffect the "natural transformation" which can change one effect type into another
|
||||||
|
* @return a new ComplexRouteService service implementation with effect type [G]
|
||||||
|
*/
|
||||||
|
final def mapEffect[G[_]](changeEffect : [A] => F[A] => G[A]) : ComplexRouteService[G] = {
|
||||||
|
val self = this
|
||||||
|
|
||||||
|
new ComplexRouteService[G] {
|
||||||
|
override def oneOfRequestAndResponse(oneOfRequestAndResponseRequest : OneOfRequestAndResponseRequest) : G[OneOfRequestAndResponse200Response] = changeEffect {
|
||||||
|
self.oneOfRequestAndResponse(oneOfRequestAndResponseRequest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* OpenAPI spec version: 1.0.0
|
||||||
|
*
|
||||||
|
* Contact: team@openapitools.org
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||||
|
*
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
*/
|
||||||
|
|
||||||
|
// this model was generated using model.mustache
|
||||||
|
package sample.cask.model
|
||||||
|
|
||||||
|
import scala.util.control.NonFatal
|
||||||
|
|
||||||
|
// see https://com-lihaoyi.github.io/upickle/
|
||||||
|
import upickle.default.{ReadWriter => RW, macroRW}
|
||||||
|
import upickle.default.*
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
case class AllOfRequest(
|
||||||
|
name: String,
|
||||||
|
age: Int,
|
||||||
|
details: Option[AllOfRequestDetails] = None
|
||||||
|
|
||||||
|
|
||||||
|
) {
|
||||||
|
|
||||||
|
def asJsonString: String = asData.asJsonString
|
||||||
|
def asJson: ujson.Value = asData.asJson
|
||||||
|
|
||||||
|
def asData : AllOfRequestData = {
|
||||||
|
AllOfRequestData(
|
||||||
|
name = name /* 2 */,
|
||||||
|
age = age /* 2 */,
|
||||||
|
details = details.map(_.asData).getOrElse(null) /* 4 */
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object AllOfRequest {
|
||||||
|
given RW[AllOfRequest] = summon[RW[ujson.Value]].bimap[AllOfRequest](_.asJson, json => read[AllOfRequestData](json).asModel)
|
||||||
|
|
||||||
|
enum Fields(val fieldName : String) extends Field(fieldName) {
|
||||||
|
case name extends Fields("name")
|
||||||
|
case age extends Fields("age")
|
||||||
|
case details extends Fields("details")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,149 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* OpenAPI spec version: 1.0.0
|
||||||
|
*
|
||||||
|
* Contact: team@openapitools.org
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||||
|
*
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
*/
|
||||||
|
|
||||||
|
// this model was generated using modelData.mustache
|
||||||
|
package sample.cask.model
|
||||||
|
import scala.util.control.NonFatal
|
||||||
|
import scala.util.*
|
||||||
|
|
||||||
|
// see https://com-lihaoyi.github.io/upickle/
|
||||||
|
import upickle.default.{ReadWriter => RW, macroRW}
|
||||||
|
import upickle.default.*
|
||||||
|
|
||||||
|
|
||||||
|
/** AllOfRequestData a data transfer object, primarily for simple json serialisation.
|
||||||
|
* It has no validation - there may be nulls, values out of range, etc
|
||||||
|
*/
|
||||||
|
case class AllOfRequestData(
|
||||||
|
name: String,
|
||||||
|
age: Int,
|
||||||
|
details: AllOfRequestDetailsData = null
|
||||||
|
|
||||||
|
|
||||||
|
) derives RW {
|
||||||
|
|
||||||
|
def asJsonString: String = asJson.toString()
|
||||||
|
|
||||||
|
def asJson : ujson.Value = {
|
||||||
|
val jason = writeJs(this)
|
||||||
|
jason
|
||||||
|
}
|
||||||
|
|
||||||
|
def validationErrors(path : Seq[Field], failFast : Boolean) : Seq[ValidationError] = {
|
||||||
|
val _allValidationErrors = scala.collection.mutable.ListBuffer[ValidationError]()
|
||||||
|
// ================== name validation ==================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ================== age validation ==================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ================== details validation ==================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// validating details
|
||||||
|
if (_allValidationErrors.isEmpty || !failFast) {
|
||||||
|
if details != null then _allValidationErrors ++= details.validationErrors(path :+ AllOfRequest.Fields.details, failFast)
|
||||||
|
}
|
||||||
|
|
||||||
|
_allValidationErrors.toSeq
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the validated model within a Try (if successful)
|
||||||
|
*/
|
||||||
|
def validated(failFast : Boolean = false) : scala.util.Try[AllOfRequest] = {
|
||||||
|
validationErrors(Vector(), failFast) match {
|
||||||
|
case Seq() => Success(asModel)
|
||||||
|
case first +: theRest => Failure(ValidationErrors(first, theRest))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** use 'validated' to check validation */
|
||||||
|
def asModel : AllOfRequest = {
|
||||||
|
AllOfRequest(
|
||||||
|
name = name /* 2 */,
|
||||||
|
age = age /* 2 */,
|
||||||
|
details = Option(details).map(_.asModel) /* 4 */
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object AllOfRequestData {
|
||||||
|
|
||||||
|
def validated(d8a : AllOfRequestData, failFast : Boolean) : scala.util.Try[AllOfRequest] = d8a.validated(failFast)
|
||||||
|
|
||||||
|
def fromJson(jason : ujson.Value) : AllOfRequestData = try {
|
||||||
|
val data = read[AllOfRequestData](jason)
|
||||||
|
data
|
||||||
|
} catch {
|
||||||
|
case NonFatal(e) => sys.error(s"Error creating AllOfRequestData from json '$jason': $e")
|
||||||
|
}
|
||||||
|
|
||||||
|
def fromJsonString(jason : String) : AllOfRequestData = {
|
||||||
|
val parsed = try {
|
||||||
|
read[ujson.Value](jason)
|
||||||
|
} catch {
|
||||||
|
case NonFatal(e) => sys.error(s"Error parsing json '$jason': $e")
|
||||||
|
}
|
||||||
|
fromJson(parsed)
|
||||||
|
}
|
||||||
|
|
||||||
|
def manyFromJsonString(jason : String) : Seq[AllOfRequestData] = try {
|
||||||
|
read[List[AllOfRequestData]](jason)
|
||||||
|
} catch {
|
||||||
|
case NonFatal(e) => sys.error(s"Error parsing json '$jason' as list: $e")
|
||||||
|
}
|
||||||
|
|
||||||
|
def manyFromJsonStringValidated(jason : String, failFast : Boolean = false) : Try[Seq[AllOfRequest]] = {
|
||||||
|
Try(manyFromJsonString(jason)).flatMap { list =>
|
||||||
|
list.zipWithIndex.foldLeft(Try(Vector[AllOfRequest]())) {
|
||||||
|
case (Success(list), (next, i)) =>
|
||||||
|
next.validated(failFast) match {
|
||||||
|
case Success(ok) => Success(list :+ ok)
|
||||||
|
case Failure(err) => Failure(new Exception(s"Validation error on element $i: ${err.getMessage}", err))
|
||||||
|
}
|
||||||
|
case (fail, _) => fail
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def mapFromJsonString(jason : String) : Map[String, AllOfRequestData] = try {
|
||||||
|
read[Map[String, AllOfRequestData]](jason)
|
||||||
|
} catch {
|
||||||
|
case NonFatal(e) => sys.error(s"Error parsing json '$jason' as map: $e")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def mapFromJsonStringValidated(jason : String, failFast : Boolean = false) : Try[Map[String, AllOfRequest]] = {
|
||||||
|
Try(mapFromJsonString(jason)).flatMap { map =>
|
||||||
|
map.foldLeft(Try(Map[String, AllOfRequest]())) {
|
||||||
|
case (Success(map), (key, next)) =>
|
||||||
|
next.validated(failFast) match {
|
||||||
|
case Success(ok) => Success(map.updated(key, ok))
|
||||||
|
case Failure(err) => Failure(new Exception(s"Validation error on element $key: ${err.getMessage}", err))
|
||||||
|
}
|
||||||
|
case (fail, _) => fail
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,55 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* OpenAPI spec version: 1.0.0
|
||||||
|
*
|
||||||
|
* Contact: team@openapitools.org
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||||
|
*
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
*/
|
||||||
|
|
||||||
|
// this model was generated using model.mustache
|
||||||
|
package sample.cask.model
|
||||||
|
|
||||||
|
import scala.util.control.NonFatal
|
||||||
|
|
||||||
|
// see https://com-lihaoyi.github.io/upickle/
|
||||||
|
import upickle.default.{ReadWriter => RW, macroRW}
|
||||||
|
import upickle.default.*
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
case class AllOfRequestDetails(
|
||||||
|
address: Option[String] = None ,
|
||||||
|
contactNumber: Option[String] = None
|
||||||
|
|
||||||
|
|
||||||
|
) {
|
||||||
|
|
||||||
|
def asJsonString: String = asData.asJsonString
|
||||||
|
def asJson: ujson.Value = asData.asJson
|
||||||
|
|
||||||
|
def asData : AllOfRequestDetailsData = {
|
||||||
|
AllOfRequestDetailsData(
|
||||||
|
address = address.getOrElse("") /* 1 */,
|
||||||
|
contactNumber = contactNumber.getOrElse("") /* 1 */
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object AllOfRequestDetails {
|
||||||
|
given RW[AllOfRequestDetails] = summon[RW[ujson.Value]].bimap[AllOfRequestDetails](_.asJson, json => read[AllOfRequestDetailsData](json).asModel)
|
||||||
|
|
||||||
|
enum Fields(val fieldName : String) extends Field(fieldName) {
|
||||||
|
case address extends Fields("address")
|
||||||
|
case contactNumber extends Fields("contactNumber")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,137 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* OpenAPI spec version: 1.0.0
|
||||||
|
*
|
||||||
|
* Contact: team@openapitools.org
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||||
|
*
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
*/
|
||||||
|
|
||||||
|
// this model was generated using modelData.mustache
|
||||||
|
package sample.cask.model
|
||||||
|
import scala.util.control.NonFatal
|
||||||
|
import scala.util.*
|
||||||
|
|
||||||
|
// see https://com-lihaoyi.github.io/upickle/
|
||||||
|
import upickle.default.{ReadWriter => RW, macroRW}
|
||||||
|
import upickle.default.*
|
||||||
|
|
||||||
|
|
||||||
|
/** AllOfRequestDetailsData a data transfer object, primarily for simple json serialisation.
|
||||||
|
* It has no validation - there may be nulls, values out of range, etc
|
||||||
|
*/
|
||||||
|
case class AllOfRequestDetailsData(
|
||||||
|
address: String = "" ,
|
||||||
|
contactNumber: String = ""
|
||||||
|
|
||||||
|
|
||||||
|
) derives RW {
|
||||||
|
|
||||||
|
def asJsonString: String = asJson.toString()
|
||||||
|
|
||||||
|
def asJson : ujson.Value = {
|
||||||
|
val jason = writeJs(this)
|
||||||
|
jason
|
||||||
|
}
|
||||||
|
|
||||||
|
def validationErrors(path : Seq[Field], failFast : Boolean) : Seq[ValidationError] = {
|
||||||
|
val _allValidationErrors = scala.collection.mutable.ListBuffer[ValidationError]()
|
||||||
|
// ================== address validation ==================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ================== contactNumber validation ==================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
_allValidationErrors.toSeq
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the validated model within a Try (if successful)
|
||||||
|
*/
|
||||||
|
def validated(failFast : Boolean = false) : scala.util.Try[AllOfRequestDetails] = {
|
||||||
|
validationErrors(Vector(), failFast) match {
|
||||||
|
case Seq() => Success(asModel)
|
||||||
|
case first +: theRest => Failure(ValidationErrors(first, theRest))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** use 'validated' to check validation */
|
||||||
|
def asModel : AllOfRequestDetails = {
|
||||||
|
AllOfRequestDetails(
|
||||||
|
address = Option(address) /* 1 */,
|
||||||
|
contactNumber = Option(contactNumber) /* 1 */
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object AllOfRequestDetailsData {
|
||||||
|
|
||||||
|
def validated(d8a : AllOfRequestDetailsData, failFast : Boolean) : scala.util.Try[AllOfRequestDetails] = d8a.validated(failFast)
|
||||||
|
|
||||||
|
def fromJson(jason : ujson.Value) : AllOfRequestDetailsData = try {
|
||||||
|
val data = read[AllOfRequestDetailsData](jason)
|
||||||
|
data
|
||||||
|
} catch {
|
||||||
|
case NonFatal(e) => sys.error(s"Error creating AllOfRequestDetailsData from json '$jason': $e")
|
||||||
|
}
|
||||||
|
|
||||||
|
def fromJsonString(jason : String) : AllOfRequestDetailsData = {
|
||||||
|
val parsed = try {
|
||||||
|
read[ujson.Value](jason)
|
||||||
|
} catch {
|
||||||
|
case NonFatal(e) => sys.error(s"Error parsing json '$jason': $e")
|
||||||
|
}
|
||||||
|
fromJson(parsed)
|
||||||
|
}
|
||||||
|
|
||||||
|
def manyFromJsonString(jason : String) : Seq[AllOfRequestDetailsData] = try {
|
||||||
|
read[List[AllOfRequestDetailsData]](jason)
|
||||||
|
} catch {
|
||||||
|
case NonFatal(e) => sys.error(s"Error parsing json '$jason' as list: $e")
|
||||||
|
}
|
||||||
|
|
||||||
|
def manyFromJsonStringValidated(jason : String, failFast : Boolean = false) : Try[Seq[AllOfRequestDetails]] = {
|
||||||
|
Try(manyFromJsonString(jason)).flatMap { list =>
|
||||||
|
list.zipWithIndex.foldLeft(Try(Vector[AllOfRequestDetails]())) {
|
||||||
|
case (Success(list), (next, i)) =>
|
||||||
|
next.validated(failFast) match {
|
||||||
|
case Success(ok) => Success(list :+ ok)
|
||||||
|
case Failure(err) => Failure(new Exception(s"Validation error on element $i: ${err.getMessage}", err))
|
||||||
|
}
|
||||||
|
case (fail, _) => fail
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def mapFromJsonString(jason : String) : Map[String, AllOfRequestDetailsData] = try {
|
||||||
|
read[Map[String, AllOfRequestDetailsData]](jason)
|
||||||
|
} catch {
|
||||||
|
case NonFatal(e) => sys.error(s"Error parsing json '$jason' as map: $e")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def mapFromJsonStringValidated(jason : String, failFast : Boolean = false) : Try[Map[String, AllOfRequestDetails]] = {
|
||||||
|
Try(mapFromJsonString(jason)).flatMap { map =>
|
||||||
|
map.foldLeft(Try(Map[String, AllOfRequestDetails]())) {
|
||||||
|
case (Success(map), (key, next)) =>
|
||||||
|
next.validated(failFast) match {
|
||||||
|
case Success(ok) => Success(map.updated(key, ok))
|
||||||
|
case Failure(err) => Failure(new Exception(s"Validation error on element $key: ${err.getMessage}", err))
|
||||||
|
}
|
||||||
|
case (fail, _) => fail
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -55,3 +55,4 @@ enum Fields(val fieldName : String) extends Field(fieldName) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ case class ApiResponseData(
|
|||||||
}
|
}
|
||||||
|
|
||||||
def validationErrors(path : Seq[Field], failFast : Boolean) : Seq[ValidationError] = {
|
def validationErrors(path : Seq[Field], failFast : Boolean) : Seq[ValidationError] = {
|
||||||
val errors = scala.collection.mutable.ListBuffer[ValidationError]()
|
val _allValidationErrors = scala.collection.mutable.ListBuffer[ValidationError]()
|
||||||
// ================== code validation ==================
|
// ================== code validation ==================
|
||||||
|
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ case class ApiResponseData(
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
errors.toSeq
|
_allValidationErrors.toSeq
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -85,6 +85,8 @@ case class ApiResponseData(
|
|||||||
|
|
||||||
object ApiResponseData {
|
object ApiResponseData {
|
||||||
|
|
||||||
|
def validated(d8a : ApiResponseData, failFast : Boolean) : scala.util.Try[ApiResponse] = d8a.validated(failFast)
|
||||||
|
|
||||||
def fromJson(jason : ujson.Value) : ApiResponseData = try {
|
def fromJson(jason : ujson.Value) : ApiResponseData = try {
|
||||||
val data = read[ApiResponseData](jason)
|
val data = read[ApiResponseData](jason)
|
||||||
data
|
data
|
||||||
|
@ -52,3 +52,4 @@ enum Fields(val fieldName : String) extends Field(fieldName) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ case class CategoryData(
|
|||||||
}
|
}
|
||||||
|
|
||||||
def validationErrors(path : Seq[Field], failFast : Boolean) : Seq[ValidationError] = {
|
def validationErrors(path : Seq[Field], failFast : Boolean) : Seq[ValidationError] = {
|
||||||
val errors = scala.collection.mutable.ListBuffer[ValidationError]()
|
val _allValidationErrors = scala.collection.mutable.ListBuffer[ValidationError]()
|
||||||
// ================== id validation ==================
|
// ================== id validation ==================
|
||||||
|
|
||||||
|
|
||||||
@ -48,17 +48,17 @@ case class CategoryData(
|
|||||||
|
|
||||||
// ================== name validation ==================
|
// ================== name validation ==================
|
||||||
// validate against pattern '^[a-zA-Z0-9]+[a-zA-Z0-9\\.\\-_]*[a-zA-Z0-9]+$'
|
// validate against pattern '^[a-zA-Z0-9]+[a-zA-Z0-9\\.\\-_]*[a-zA-Z0-9]+$'
|
||||||
if (errors.isEmpty || !failFast) {
|
if (_allValidationErrors.isEmpty || !failFast) {
|
||||||
val regex = """^[a-zA-Z0-9]+[a-zA-Z0-9\\.\\-_]*[a-zA-Z0-9]+$"""
|
val regex = """^[a-zA-Z0-9]+[a-zA-Z0-9\\.\\-_]*[a-zA-Z0-9]+$"""
|
||||||
if name == null || !regex.r.matches(name) then
|
if name == null || !regex.r.matches(name) then
|
||||||
errors += ValidationError(path :+ Category.Fields.name, s"value '$name' doesn't match pattern $regex")
|
_allValidationErrors += ValidationError(path :+ Category.Fields.name, s"value '$name' doesn't match pattern $regex")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
errors.toSeq
|
_allValidationErrors.toSeq
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -83,6 +83,8 @@ case class CategoryData(
|
|||||||
|
|
||||||
object CategoryData {
|
object CategoryData {
|
||||||
|
|
||||||
|
def validated(d8a : CategoryData, failFast : Boolean) : scala.util.Try[Category] = d8a.validated(failFast)
|
||||||
|
|
||||||
def fromJson(jason : ujson.Value) : CategoryData = try {
|
def fromJson(jason : ujson.Value) : CategoryData = try {
|
||||||
val data = read[CategoryData](jason)
|
val data = read[CategoryData](jason)
|
||||||
data
|
data
|
||||||
|
@ -0,0 +1,127 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* OpenAPI spec version: 1.0.0
|
||||||
|
*
|
||||||
|
* Contact: team@openapitools.org
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||||
|
*
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
*/
|
||||||
|
|
||||||
|
// this model was generated using model.mustache
|
||||||
|
package sample.cask.model
|
||||||
|
import java.time.LocalDate
|
||||||
|
import java.time.OffsetDateTime
|
||||||
|
import java.util.UUID
|
||||||
|
import scala.math.BigDecimal
|
||||||
|
import ujson.Value
|
||||||
|
|
||||||
|
import scala.util.control.NonFatal
|
||||||
|
|
||||||
|
// see https://com-lihaoyi.github.io/upickle/
|
||||||
|
import upickle.default.{ReadWriter => RW, macroRW}
|
||||||
|
import upickle.default.*
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
case class ComplexRequest(
|
||||||
|
`type`: ComplexRequest.TypeEnum,
|
||||||
|
/* A required string field */
|
||||||
|
requiredField: String,
|
||||||
|
/* String with length constraints */
|
||||||
|
stringField: Option[String] = None ,
|
||||||
|
/* Integer with a range from 1 to 100 */
|
||||||
|
integerField: Option[Int] = None ,
|
||||||
|
/* Number with exclusive minimum and maximum constraints */
|
||||||
|
numberField: Option[BigDecimal] = None ,
|
||||||
|
/* A boolean field */
|
||||||
|
booleanField: Option[Boolean] = None ,
|
||||||
|
/* A valid email address */
|
||||||
|
emailField: Option[String] = None ,
|
||||||
|
/* A valid UUID */
|
||||||
|
uuidField: Option[UUID] = None ,
|
||||||
|
/* A date field (YYYY-MM-DD) */
|
||||||
|
dateField: Option[LocalDate] = None ,
|
||||||
|
/* A date-time field (RFC 3339 format) */
|
||||||
|
dateTimeField: Option[OffsetDateTime] = None ,
|
||||||
|
/* An array of strings with min and max items constraints */
|
||||||
|
arrayField: Seq[String] = Nil ,
|
||||||
|
/* A string field with enum validation */
|
||||||
|
enumField: Option[ComplexRequest.EnumFieldEnum] = None ,
|
||||||
|
nestedObject: Option[ComplexRequestNestedObject] = None ,
|
||||||
|
arrayOfObjectsField: Seq[ComplexRequestArrayOfObjectsFieldInner] = Nil ,
|
||||||
|
/* A string field with regex pattern validation */
|
||||||
|
patternField: Option[String] = None ,
|
||||||
|
/* A string field that allows null values */
|
||||||
|
nullableField: Option[String] = None
|
||||||
|
|
||||||
|
, additionalProperties : ujson.Value = ujson.Null
|
||||||
|
) {
|
||||||
|
|
||||||
|
def asJsonString: String = asData.asJsonString
|
||||||
|
def asJson: ujson.Value = asData.asJson
|
||||||
|
|
||||||
|
def asData : ComplexRequestData = {
|
||||||
|
ComplexRequestData(
|
||||||
|
`type` = `type` /* 2 */,
|
||||||
|
requiredField = requiredField /* 2 */,
|
||||||
|
stringField = stringField.getOrElse("") /* 1 */,
|
||||||
|
integerField = integerField.getOrElse(0) /* 1 */,
|
||||||
|
numberField = numberField.getOrElse(0) /* 1 */,
|
||||||
|
booleanField = booleanField.getOrElse(false) /* 1 */,
|
||||||
|
emailField = emailField.getOrElse("") /* 1 */,
|
||||||
|
uuidField = uuidField.getOrElse(java.util.UUID.randomUUID()) /* 1 */,
|
||||||
|
dateField = dateField.getOrElse(null) /* 1 */,
|
||||||
|
dateTimeField = dateTimeField.getOrElse(null) /* 1 */,
|
||||||
|
arrayField = arrayField /* 2 */,
|
||||||
|
enumField = enumField.getOrElse(null) /* 1 */,
|
||||||
|
nestedObject = nestedObject.map(_.asData).getOrElse(null) /* 4 */,
|
||||||
|
arrayOfObjectsField = arrayOfObjectsField.map(_.asData) /* 6 */,
|
||||||
|
patternField = patternField.getOrElse("") /* 1 */,
|
||||||
|
nullableField = nullableField.getOrElse("") /* 1 */
|
||||||
|
, additionalProperties
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object ComplexRequest {
|
||||||
|
given RW[ComplexRequest] = summon[RW[ujson.Value]].bimap[ComplexRequest](_.asJson, json => read[ComplexRequestData](json).asModel)
|
||||||
|
|
||||||
|
enum Fields(val fieldName : String) extends Field(fieldName) {
|
||||||
|
case `type` extends Fields("`type`")
|
||||||
|
case requiredField extends Fields("requiredField")
|
||||||
|
case stringField extends Fields("stringField")
|
||||||
|
case integerField extends Fields("integerField")
|
||||||
|
case numberField extends Fields("numberField")
|
||||||
|
case booleanField extends Fields("booleanField")
|
||||||
|
case emailField extends Fields("emailField")
|
||||||
|
case uuidField extends Fields("uuidField")
|
||||||
|
case dateField extends Fields("dateField")
|
||||||
|
case dateTimeField extends Fields("dateTimeField")
|
||||||
|
case arrayField extends Fields("arrayField")
|
||||||
|
case enumField extends Fields("enumField")
|
||||||
|
case nestedObject extends Fields("nestedObject")
|
||||||
|
case arrayOfObjectsField extends Fields("arrayOfObjectsField")
|
||||||
|
case patternField extends Fields("patternField")
|
||||||
|
case nullableField extends Fields("nullableField")
|
||||||
|
}
|
||||||
|
|
||||||
|
// baseName=type
|
||||||
|
// nameInCamelCase = `type`
|
||||||
|
enum TypeEnum derives ReadWriter {
|
||||||
|
case someEnum
|
||||||
|
}
|
||||||
|
// baseName=enumField
|
||||||
|
// nameInCamelCase = enumField
|
||||||
|
enum EnumFieldEnum derives ReadWriter {
|
||||||
|
case value1
|
||||||
|
case value2
|
||||||
|
case value3
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,55 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* OpenAPI spec version: 1.0.0
|
||||||
|
*
|
||||||
|
* Contact: team@openapitools.org
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||||
|
*
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
*/
|
||||||
|
|
||||||
|
// this model was generated using model.mustache
|
||||||
|
package sample.cask.model
|
||||||
|
|
||||||
|
import scala.util.control.NonFatal
|
||||||
|
|
||||||
|
// see https://com-lihaoyi.github.io/upickle/
|
||||||
|
import upickle.default.{ReadWriter => RW, macroRW}
|
||||||
|
import upickle.default.*
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
case class ComplexRequestArrayOfObjectsFieldInner(
|
||||||
|
objectField1: Option[String] = None ,
|
||||||
|
objectField2: Option[Int] = None
|
||||||
|
|
||||||
|
|
||||||
|
) {
|
||||||
|
|
||||||
|
def asJsonString: String = asData.asJsonString
|
||||||
|
def asJson: ujson.Value = asData.asJson
|
||||||
|
|
||||||
|
def asData : ComplexRequestArrayOfObjectsFieldInnerData = {
|
||||||
|
ComplexRequestArrayOfObjectsFieldInnerData(
|
||||||
|
objectField1 = objectField1.getOrElse("") /* 1 */,
|
||||||
|
objectField2 = objectField2.getOrElse(0) /* 1 */
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object ComplexRequestArrayOfObjectsFieldInner {
|
||||||
|
given RW[ComplexRequestArrayOfObjectsFieldInner] = summon[RW[ujson.Value]].bimap[ComplexRequestArrayOfObjectsFieldInner](_.asJson, json => read[ComplexRequestArrayOfObjectsFieldInnerData](json).asModel)
|
||||||
|
|
||||||
|
enum Fields(val fieldName : String) extends Field(fieldName) {
|
||||||
|
case objectField1 extends Fields("objectField1")
|
||||||
|
case objectField2 extends Fields("objectField2")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,137 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* OpenAPI spec version: 1.0.0
|
||||||
|
*
|
||||||
|
* Contact: team@openapitools.org
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||||
|
*
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
*/
|
||||||
|
|
||||||
|
// this model was generated using modelData.mustache
|
||||||
|
package sample.cask.model
|
||||||
|
import scala.util.control.NonFatal
|
||||||
|
import scala.util.*
|
||||||
|
|
||||||
|
// see https://com-lihaoyi.github.io/upickle/
|
||||||
|
import upickle.default.{ReadWriter => RW, macroRW}
|
||||||
|
import upickle.default.*
|
||||||
|
|
||||||
|
|
||||||
|
/** ComplexRequestArrayOfObjectsFieldInnerData a data transfer object, primarily for simple json serialisation.
|
||||||
|
* It has no validation - there may be nulls, values out of range, etc
|
||||||
|
*/
|
||||||
|
case class ComplexRequestArrayOfObjectsFieldInnerData(
|
||||||
|
objectField1: String = "" ,
|
||||||
|
objectField2: Int = 0
|
||||||
|
|
||||||
|
|
||||||
|
) derives RW {
|
||||||
|
|
||||||
|
def asJsonString: String = asJson.toString()
|
||||||
|
|
||||||
|
def asJson : ujson.Value = {
|
||||||
|
val jason = writeJs(this)
|
||||||
|
jason
|
||||||
|
}
|
||||||
|
|
||||||
|
def validationErrors(path : Seq[Field], failFast : Boolean) : Seq[ValidationError] = {
|
||||||
|
val _allValidationErrors = scala.collection.mutable.ListBuffer[ValidationError]()
|
||||||
|
// ================== objectField1 validation ==================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ================== objectField2 validation ==================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
_allValidationErrors.toSeq
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the validated model within a Try (if successful)
|
||||||
|
*/
|
||||||
|
def validated(failFast : Boolean = false) : scala.util.Try[ComplexRequestArrayOfObjectsFieldInner] = {
|
||||||
|
validationErrors(Vector(), failFast) match {
|
||||||
|
case Seq() => Success(asModel)
|
||||||
|
case first +: theRest => Failure(ValidationErrors(first, theRest))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** use 'validated' to check validation */
|
||||||
|
def asModel : ComplexRequestArrayOfObjectsFieldInner = {
|
||||||
|
ComplexRequestArrayOfObjectsFieldInner(
|
||||||
|
objectField1 = Option(objectField1) /* 1 */,
|
||||||
|
objectField2 = Option(objectField2) /* 1 */
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object ComplexRequestArrayOfObjectsFieldInnerData {
|
||||||
|
|
||||||
|
def validated(d8a : ComplexRequestArrayOfObjectsFieldInnerData, failFast : Boolean) : scala.util.Try[ComplexRequestArrayOfObjectsFieldInner] = d8a.validated(failFast)
|
||||||
|
|
||||||
|
def fromJson(jason : ujson.Value) : ComplexRequestArrayOfObjectsFieldInnerData = try {
|
||||||
|
val data = read[ComplexRequestArrayOfObjectsFieldInnerData](jason)
|
||||||
|
data
|
||||||
|
} catch {
|
||||||
|
case NonFatal(e) => sys.error(s"Error creating ComplexRequestArrayOfObjectsFieldInnerData from json '$jason': $e")
|
||||||
|
}
|
||||||
|
|
||||||
|
def fromJsonString(jason : String) : ComplexRequestArrayOfObjectsFieldInnerData = {
|
||||||
|
val parsed = try {
|
||||||
|
read[ujson.Value](jason)
|
||||||
|
} catch {
|
||||||
|
case NonFatal(e) => sys.error(s"Error parsing json '$jason': $e")
|
||||||
|
}
|
||||||
|
fromJson(parsed)
|
||||||
|
}
|
||||||
|
|
||||||
|
def manyFromJsonString(jason : String) : Seq[ComplexRequestArrayOfObjectsFieldInnerData] = try {
|
||||||
|
read[List[ComplexRequestArrayOfObjectsFieldInnerData]](jason)
|
||||||
|
} catch {
|
||||||
|
case NonFatal(e) => sys.error(s"Error parsing json '$jason' as list: $e")
|
||||||
|
}
|
||||||
|
|
||||||
|
def manyFromJsonStringValidated(jason : String, failFast : Boolean = false) : Try[Seq[ComplexRequestArrayOfObjectsFieldInner]] = {
|
||||||
|
Try(manyFromJsonString(jason)).flatMap { list =>
|
||||||
|
list.zipWithIndex.foldLeft(Try(Vector[ComplexRequestArrayOfObjectsFieldInner]())) {
|
||||||
|
case (Success(list), (next, i)) =>
|
||||||
|
next.validated(failFast) match {
|
||||||
|
case Success(ok) => Success(list :+ ok)
|
||||||
|
case Failure(err) => Failure(new Exception(s"Validation error on element $i: ${err.getMessage}", err))
|
||||||
|
}
|
||||||
|
case (fail, _) => fail
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def mapFromJsonString(jason : String) : Map[String, ComplexRequestArrayOfObjectsFieldInnerData] = try {
|
||||||
|
read[Map[String, ComplexRequestArrayOfObjectsFieldInnerData]](jason)
|
||||||
|
} catch {
|
||||||
|
case NonFatal(e) => sys.error(s"Error parsing json '$jason' as map: $e")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def mapFromJsonStringValidated(jason : String, failFast : Boolean = false) : Try[Map[String, ComplexRequestArrayOfObjectsFieldInner]] = {
|
||||||
|
Try(mapFromJsonString(jason)).flatMap { map =>
|
||||||
|
map.foldLeft(Try(Map[String, ComplexRequestArrayOfObjectsFieldInner]())) {
|
||||||
|
case (Success(map), (key, next)) =>
|
||||||
|
next.validated(failFast) match {
|
||||||
|
case Success(ok) => Success(map.updated(key, ok))
|
||||||
|
case Failure(err) => Failure(new Exception(s"Validation error on element $key: ${err.getMessage}", err))
|
||||||
|
}
|
||||||
|
case (fail, _) => fail
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,338 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* OpenAPI spec version: 1.0.0
|
||||||
|
*
|
||||||
|
* Contact: team@openapitools.org
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||||
|
*
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
*/
|
||||||
|
|
||||||
|
// this model was generated using modelData.mustache
|
||||||
|
package sample.cask.model
|
||||||
|
import java.time.LocalDate
|
||||||
|
import java.time.OffsetDateTime
|
||||||
|
import java.util.UUID
|
||||||
|
import scala.math.BigDecimal
|
||||||
|
import ujson.Value
|
||||||
|
import scala.util.control.NonFatal
|
||||||
|
import scala.util.*
|
||||||
|
|
||||||
|
// see https://com-lihaoyi.github.io/upickle/
|
||||||
|
import upickle.default.{ReadWriter => RW, macroRW}
|
||||||
|
import upickle.default.*
|
||||||
|
|
||||||
|
|
||||||
|
/** ComplexRequestData a data transfer object, primarily for simple json serialisation.
|
||||||
|
* It has no validation - there may be nulls, values out of range, etc
|
||||||
|
*/
|
||||||
|
case class ComplexRequestData(
|
||||||
|
`type`: ComplexRequest.TypeEnum,
|
||||||
|
/* A required string field */
|
||||||
|
requiredField: String,
|
||||||
|
/* String with length constraints */
|
||||||
|
stringField: String = "" ,
|
||||||
|
/* Integer with a range from 1 to 100 */
|
||||||
|
integerField: Int = 0 ,
|
||||||
|
/* Number with exclusive minimum and maximum constraints */
|
||||||
|
numberField: BigDecimal = 0 ,
|
||||||
|
/* A boolean field */
|
||||||
|
booleanField: Boolean = false ,
|
||||||
|
/* A valid email address */
|
||||||
|
emailField: String = "" ,
|
||||||
|
/* A valid UUID */
|
||||||
|
uuidField: UUID = java.util.UUID.randomUUID() ,
|
||||||
|
/* A date field (YYYY-MM-DD) */
|
||||||
|
dateField: LocalDate = null ,
|
||||||
|
/* A date-time field (RFC 3339 format) */
|
||||||
|
dateTimeField: OffsetDateTime = null ,
|
||||||
|
/* An array of strings with min and max items constraints */
|
||||||
|
arrayField: Seq[String] = Nil ,
|
||||||
|
/* A string field with enum validation */
|
||||||
|
enumField: ComplexRequest.EnumFieldEnum = null ,
|
||||||
|
nestedObject: ComplexRequestNestedObjectData = null ,
|
||||||
|
arrayOfObjectsField: Seq[ComplexRequestArrayOfObjectsFieldInnerData] = Nil ,
|
||||||
|
/* A string field with regex pattern validation */
|
||||||
|
patternField: String = "" ,
|
||||||
|
/* A string field that allows null values */
|
||||||
|
nullableField: String = ""
|
||||||
|
, additionalProperties : ujson.Value = ujson.Null
|
||||||
|
|
||||||
|
) derives RW {
|
||||||
|
|
||||||
|
def asJsonString: String = asJson.toString()
|
||||||
|
|
||||||
|
def asJson : ujson.Value = {
|
||||||
|
val jason = writeJs(this)
|
||||||
|
jason.obj.remove("additionalProperties")
|
||||||
|
jason.mergeWith(additionalProperties)
|
||||||
|
}
|
||||||
|
|
||||||
|
def validationErrors(path : Seq[Field], failFast : Boolean) : Seq[ValidationError] = {
|
||||||
|
val _allValidationErrors = scala.collection.mutable.ListBuffer[ValidationError]()
|
||||||
|
// ================== `type` validation ==================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ================== requiredField validation ==================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ================== stringField validation ==================
|
||||||
|
// validate min length 5
|
||||||
|
if (_allValidationErrors.isEmpty || !failFast) {
|
||||||
|
val len = if stringField == null then 0 else stringField.length
|
||||||
|
if (len < 5) {
|
||||||
|
_allValidationErrors += ValidationError(path :+ ComplexRequest.Fields.stringField, s"length $len is shorter than the min length 5")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// validate max length 100
|
||||||
|
if (_allValidationErrors.isEmpty || !failFast) {
|
||||||
|
val len = if stringField == null then 0 else stringField.length
|
||||||
|
if (len < 100) {
|
||||||
|
_allValidationErrors += ValidationError(path :+ ComplexRequest.Fields.stringField, s"length $len is longer than the max length 100")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ================== integerField validation ==================
|
||||||
|
// validate against minimum 1
|
||||||
|
if (_allValidationErrors.isEmpty || !failFast) {
|
||||||
|
if !(integerField >= 1) then
|
||||||
|
_allValidationErrors += ValidationError(path :+ ComplexRequest.Fields.integerField, s"value '$integerField' is not greater than the minimum value 1")
|
||||||
|
}
|
||||||
|
// validate against maximum 100
|
||||||
|
if (_allValidationErrors.isEmpty || !failFast) {
|
||||||
|
if !(integerField <= 100) then
|
||||||
|
_allValidationErrors += ValidationError(path :+ ComplexRequest.Fields.integerField, s"value '$integerField' is not greater than the maximum value 100")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ================== numberField validation ==================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ================== booleanField validation ==================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ================== emailField validation ==================
|
||||||
|
// validate emailField is a valid email address
|
||||||
|
if (_allValidationErrors.isEmpty || !failFast) {
|
||||||
|
val emailRegex = """^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"""
|
||||||
|
// validate emailField is email
|
||||||
|
if (emailField == null || !emailRegex.r.matches(emailField)) {
|
||||||
|
_allValidationErrors += ValidationError(path :+ ComplexRequest.Fields.emailField, s"$emailField is not a valid email address according to the pattern $emailRegex")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ================== uuidField validation ==================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ================== dateField validation ==================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ================== dateTimeField validation ==================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ================== arrayField validation ==================
|
||||||
|
|
||||||
|
// validate min items 1
|
||||||
|
if (_allValidationErrors.isEmpty || !failFast) {
|
||||||
|
val len = if arrayField == null then 0 else arrayField.size
|
||||||
|
if (len < 1) {
|
||||||
|
_allValidationErrors += ValidationError(path :+ ComplexRequest.Fields.arrayField, s"arrayField has $len, which is less than the min items 1")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// validate min items 10
|
||||||
|
if (_allValidationErrors.isEmpty || !failFast) {
|
||||||
|
val len = if arrayField == null then 0 else arrayField.size
|
||||||
|
if (len > 10) {
|
||||||
|
_allValidationErrors += ValidationError(path :+ ComplexRequest.Fields.arrayField, s"arrayField has $len, which is greater than the max items 10")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ================== enumField validation ==================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ================== nestedObject validation ==================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// validating nestedObject
|
||||||
|
if (_allValidationErrors.isEmpty || !failFast) {
|
||||||
|
if nestedObject != null then _allValidationErrors ++= nestedObject.validationErrors(path :+ ComplexRequest.Fields.nestedObject, failFast)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ================== arrayOfObjectsField validation ==================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (_allValidationErrors.isEmpty || !failFast) {
|
||||||
|
if (arrayOfObjectsField != null) {
|
||||||
|
arrayOfObjectsField.zipWithIndex.foreach {
|
||||||
|
case (value, i) if _allValidationErrors.isEmpty || !failFast =>
|
||||||
|
_allValidationErrors ++= value.validationErrors(
|
||||||
|
path :+ ComplexRequest.Fields.arrayOfObjectsField :+ Field(i.toString),
|
||||||
|
failFast)
|
||||||
|
case (value, i) =>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ================== patternField validation ==================
|
||||||
|
// validate against pattern '^[a-zA-Z0-9]{3,10}$'
|
||||||
|
if (_allValidationErrors.isEmpty || !failFast) {
|
||||||
|
val regex = """^[a-zA-Z0-9]{3,10}$"""
|
||||||
|
if patternField == null || !regex.r.matches(patternField) then
|
||||||
|
_allValidationErrors += ValidationError(path :+ ComplexRequest.Fields.patternField, s"value '$patternField' doesn't match pattern $regex")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ================== nullableField validation ==================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
_allValidationErrors.toSeq
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the validated model within a Try (if successful)
|
||||||
|
*/
|
||||||
|
def validated(failFast : Boolean = false) : scala.util.Try[ComplexRequest] = {
|
||||||
|
validationErrors(Vector(), failFast) match {
|
||||||
|
case Seq() => Success(asModel)
|
||||||
|
case first +: theRest => Failure(ValidationErrors(first, theRest))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** use 'validated' to check validation */
|
||||||
|
def asModel : ComplexRequest = {
|
||||||
|
ComplexRequest(
|
||||||
|
`type` = `type` /* 2 */,
|
||||||
|
requiredField = requiredField /* 2 */,
|
||||||
|
stringField = Option(stringField) /* 1 */,
|
||||||
|
integerField = Option(integerField) /* 1 */,
|
||||||
|
numberField = Option(numberField) /* 1 */,
|
||||||
|
booleanField = Option(booleanField) /* 1 */,
|
||||||
|
emailField = Option(emailField) /* 1 */,
|
||||||
|
uuidField = Option(uuidField) /* 1 */,
|
||||||
|
dateField = Option(dateField) /* 1 */,
|
||||||
|
dateTimeField = Option(dateTimeField) /* 1 */,
|
||||||
|
arrayField = arrayField /* 2 */,
|
||||||
|
enumField = Option(enumField) /* 1 */,
|
||||||
|
nestedObject = Option(nestedObject).map(_.asModel) /* 4 */,
|
||||||
|
arrayOfObjectsField = arrayOfObjectsField.map(_.asModel) /* 5 */,
|
||||||
|
patternField = Option(patternField) /* 1 */,
|
||||||
|
nullableField = Option(nullableField) /* 1 */
|
||||||
|
, additionalProperties
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object ComplexRequestData {
|
||||||
|
|
||||||
|
def validated(d8a : ComplexRequestData, failFast : Boolean) : scala.util.Try[ComplexRequest] = d8a.validated(failFast)
|
||||||
|
|
||||||
|
def fromJson(jason : ujson.Value) : ComplexRequestData = try {
|
||||||
|
val data = read[ComplexRequestData](jason)
|
||||||
|
val obj = jason.obj
|
||||||
|
ComplexRequest.Fields.values.foreach(v => obj.value.subtractOne(v.fieldName))
|
||||||
|
data.copy(additionalProperties = obj)
|
||||||
|
} catch {
|
||||||
|
case NonFatal(e) => sys.error(s"Error creating ComplexRequestData from json '$jason': $e")
|
||||||
|
}
|
||||||
|
|
||||||
|
def fromJsonString(jason : String) : ComplexRequestData = {
|
||||||
|
val parsed = try {
|
||||||
|
read[ujson.Value](jason)
|
||||||
|
} catch {
|
||||||
|
case NonFatal(e) => sys.error(s"Error parsing json '$jason': $e")
|
||||||
|
}
|
||||||
|
fromJson(parsed)
|
||||||
|
}
|
||||||
|
|
||||||
|
def manyFromJsonString(jason : String) : Seq[ComplexRequestData] = try {
|
||||||
|
read[List[ComplexRequestData]](jason)
|
||||||
|
} catch {
|
||||||
|
case NonFatal(e) => sys.error(s"Error parsing json '$jason' as list: $e")
|
||||||
|
}
|
||||||
|
|
||||||
|
def manyFromJsonStringValidated(jason : String, failFast : Boolean = false) : Try[Seq[ComplexRequest]] = {
|
||||||
|
Try(manyFromJsonString(jason)).flatMap { list =>
|
||||||
|
list.zipWithIndex.foldLeft(Try(Vector[ComplexRequest]())) {
|
||||||
|
case (Success(list), (next, i)) =>
|
||||||
|
next.validated(failFast) match {
|
||||||
|
case Success(ok) => Success(list :+ ok)
|
||||||
|
case Failure(err) => Failure(new Exception(s"Validation error on element $i: ${err.getMessage}", err))
|
||||||
|
}
|
||||||
|
case (fail, _) => fail
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def mapFromJsonString(jason : String) : Map[String, ComplexRequestData] = try {
|
||||||
|
read[Map[String, ComplexRequestData]](jason)
|
||||||
|
} catch {
|
||||||
|
case NonFatal(e) => sys.error(s"Error parsing json '$jason' as map: $e")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def mapFromJsonStringValidated(jason : String, failFast : Boolean = false) : Try[Map[String, ComplexRequest]] = {
|
||||||
|
Try(mapFromJsonString(jason)).flatMap { map =>
|
||||||
|
map.foldLeft(Try(Map[String, ComplexRequest]())) {
|
||||||
|
case (Success(map), (key, next)) =>
|
||||||
|
next.validated(failFast) match {
|
||||||
|
case Success(ok) => Success(map.updated(key, ok))
|
||||||
|
case Failure(err) => Failure(new Exception(s"Validation error on element $key: ${err.getMessage}", err))
|
||||||
|
}
|
||||||
|
case (fail, _) => fail
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,57 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* OpenAPI spec version: 1.0.0
|
||||||
|
*
|
||||||
|
* Contact: team@openapitools.org
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||||
|
*
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
*/
|
||||||
|
|
||||||
|
// this model was generated using model.mustache
|
||||||
|
package sample.cask.model
|
||||||
|
|
||||||
|
import scala.util.control.NonFatal
|
||||||
|
|
||||||
|
// see https://com-lihaoyi.github.io/upickle/
|
||||||
|
import upickle.default.{ReadWriter => RW, macroRW}
|
||||||
|
import upickle.default.*
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
case class ComplexRequestNestedObject(
|
||||||
|
/* A field within a nested object */
|
||||||
|
nestedField1: Option[String] = None ,
|
||||||
|
/* Another field in a nested object */
|
||||||
|
nestedField2: Option[Int] = None
|
||||||
|
|
||||||
|
|
||||||
|
) {
|
||||||
|
|
||||||
|
def asJsonString: String = asData.asJsonString
|
||||||
|
def asJson: ujson.Value = asData.asJson
|
||||||
|
|
||||||
|
def asData : ComplexRequestNestedObjectData = {
|
||||||
|
ComplexRequestNestedObjectData(
|
||||||
|
nestedField1 = nestedField1.getOrElse("") /* 1 */,
|
||||||
|
nestedField2 = nestedField2.getOrElse(0) /* 1 */
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object ComplexRequestNestedObject {
|
||||||
|
given RW[ComplexRequestNestedObject] = summon[RW[ujson.Value]].bimap[ComplexRequestNestedObject](_.asJson, json => read[ComplexRequestNestedObjectData](json).asModel)
|
||||||
|
|
||||||
|
enum Fields(val fieldName : String) extends Field(fieldName) {
|
||||||
|
case nestedField1 extends Fields("nestedField1")
|
||||||
|
case nestedField2 extends Fields("nestedField2")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,139 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* OpenAPI spec version: 1.0.0
|
||||||
|
*
|
||||||
|
* Contact: team@openapitools.org
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||||
|
*
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
*/
|
||||||
|
|
||||||
|
// this model was generated using modelData.mustache
|
||||||
|
package sample.cask.model
|
||||||
|
import scala.util.control.NonFatal
|
||||||
|
import scala.util.*
|
||||||
|
|
||||||
|
// see https://com-lihaoyi.github.io/upickle/
|
||||||
|
import upickle.default.{ReadWriter => RW, macroRW}
|
||||||
|
import upickle.default.*
|
||||||
|
|
||||||
|
|
||||||
|
/** ComplexRequestNestedObjectData a data transfer object, primarily for simple json serialisation.
|
||||||
|
* It has no validation - there may be nulls, values out of range, etc
|
||||||
|
*/
|
||||||
|
case class ComplexRequestNestedObjectData(
|
||||||
|
/* A field within a nested object */
|
||||||
|
nestedField1: String = "" ,
|
||||||
|
/* Another field in a nested object */
|
||||||
|
nestedField2: Int = 0
|
||||||
|
|
||||||
|
|
||||||
|
) derives RW {
|
||||||
|
|
||||||
|
def asJsonString: String = asJson.toString()
|
||||||
|
|
||||||
|
def asJson : ujson.Value = {
|
||||||
|
val jason = writeJs(this)
|
||||||
|
jason
|
||||||
|
}
|
||||||
|
|
||||||
|
def validationErrors(path : Seq[Field], failFast : Boolean) : Seq[ValidationError] = {
|
||||||
|
val _allValidationErrors = scala.collection.mutable.ListBuffer[ValidationError]()
|
||||||
|
// ================== nestedField1 validation ==================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ================== nestedField2 validation ==================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
_allValidationErrors.toSeq
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the validated model within a Try (if successful)
|
||||||
|
*/
|
||||||
|
def validated(failFast : Boolean = false) : scala.util.Try[ComplexRequestNestedObject] = {
|
||||||
|
validationErrors(Vector(), failFast) match {
|
||||||
|
case Seq() => Success(asModel)
|
||||||
|
case first +: theRest => Failure(ValidationErrors(first, theRest))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** use 'validated' to check validation */
|
||||||
|
def asModel : ComplexRequestNestedObject = {
|
||||||
|
ComplexRequestNestedObject(
|
||||||
|
nestedField1 = Option(nestedField1) /* 1 */,
|
||||||
|
nestedField2 = Option(nestedField2) /* 1 */
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object ComplexRequestNestedObjectData {
|
||||||
|
|
||||||
|
def validated(d8a : ComplexRequestNestedObjectData, failFast : Boolean) : scala.util.Try[ComplexRequestNestedObject] = d8a.validated(failFast)
|
||||||
|
|
||||||
|
def fromJson(jason : ujson.Value) : ComplexRequestNestedObjectData = try {
|
||||||
|
val data = read[ComplexRequestNestedObjectData](jason)
|
||||||
|
data
|
||||||
|
} catch {
|
||||||
|
case NonFatal(e) => sys.error(s"Error creating ComplexRequestNestedObjectData from json '$jason': $e")
|
||||||
|
}
|
||||||
|
|
||||||
|
def fromJsonString(jason : String) : ComplexRequestNestedObjectData = {
|
||||||
|
val parsed = try {
|
||||||
|
read[ujson.Value](jason)
|
||||||
|
} catch {
|
||||||
|
case NonFatal(e) => sys.error(s"Error parsing json '$jason': $e")
|
||||||
|
}
|
||||||
|
fromJson(parsed)
|
||||||
|
}
|
||||||
|
|
||||||
|
def manyFromJsonString(jason : String) : Seq[ComplexRequestNestedObjectData] = try {
|
||||||
|
read[List[ComplexRequestNestedObjectData]](jason)
|
||||||
|
} catch {
|
||||||
|
case NonFatal(e) => sys.error(s"Error parsing json '$jason' as list: $e")
|
||||||
|
}
|
||||||
|
|
||||||
|
def manyFromJsonStringValidated(jason : String, failFast : Boolean = false) : Try[Seq[ComplexRequestNestedObject]] = {
|
||||||
|
Try(manyFromJsonString(jason)).flatMap { list =>
|
||||||
|
list.zipWithIndex.foldLeft(Try(Vector[ComplexRequestNestedObject]())) {
|
||||||
|
case (Success(list), (next, i)) =>
|
||||||
|
next.validated(failFast) match {
|
||||||
|
case Success(ok) => Success(list :+ ok)
|
||||||
|
case Failure(err) => Failure(new Exception(s"Validation error on element $i: ${err.getMessage}", err))
|
||||||
|
}
|
||||||
|
case (fail, _) => fail
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def mapFromJsonString(jason : String) : Map[String, ComplexRequestNestedObjectData] = try {
|
||||||
|
read[Map[String, ComplexRequestNestedObjectData]](jason)
|
||||||
|
} catch {
|
||||||
|
case NonFatal(e) => sys.error(s"Error parsing json '$jason' as map: $e")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def mapFromJsonStringValidated(jason : String, failFast : Boolean = false) : Try[Map[String, ComplexRequestNestedObject]] = {
|
||||||
|
Try(mapFromJsonString(jason)).flatMap { map =>
|
||||||
|
map.foldLeft(Try(Map[String, ComplexRequestNestedObject]())) {
|
||||||
|
case (Success(map), (key, next)) =>
|
||||||
|
next.validated(failFast) match {
|
||||||
|
case Success(ok) => Success(map.updated(key, ok))
|
||||||
|
case Failure(err) => Failure(new Exception(s"Validation error on element $key: ${err.getMessage}", err))
|
||||||
|
}
|
||||||
|
case (fail, _) => fail
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* OpenAPI spec version: 1.0.0
|
||||||
|
*
|
||||||
|
* Contact: team@openapitools.org
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||||
|
*
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
*/
|
||||||
|
|
||||||
|
// this model was generated using model.mustache
|
||||||
|
package sample.cask.model
|
||||||
|
import java.time.OffsetDateTime
|
||||||
|
|
||||||
|
import scala.util.control.NonFatal
|
||||||
|
|
||||||
|
// see https://com-lihaoyi.github.io/upickle/
|
||||||
|
import upickle.default.{ReadWriter => RW, macroRW}
|
||||||
|
import upickle.default.*
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
type OneOfRequestAndResponse200Response = SomeResponse1 | SomeResponse2
|
||||||
|
object OneOfRequestAndResponse200Response {
|
||||||
|
|
||||||
|
given RW[OneOfRequestAndResponse200Response] = RW.merge(summon[RW[SomeResponse1]], summon[RW[SomeResponse2]])
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,48 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* OpenAPI spec version: 1.0.0
|
||||||
|
*
|
||||||
|
* Contact: team@openapitools.org
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||||
|
*
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
*/
|
||||||
|
|
||||||
|
// this model was generated using modelData.mustache
|
||||||
|
package sample.cask.model
|
||||||
|
import java.time.OffsetDateTime
|
||||||
|
import scala.util.control.NonFatal
|
||||||
|
import scala.util.*
|
||||||
|
|
||||||
|
// see https://com-lihaoyi.github.io/upickle/
|
||||||
|
import upickle.default.{ReadWriter => RW, macroRW}
|
||||||
|
import upickle.default.*
|
||||||
|
|
||||||
|
|
||||||
|
type OneOfRequestAndResponse200ResponseData = SomeResponse1Data | SomeResponse2Data
|
||||||
|
|
||||||
|
object OneOfRequestAndResponse200ResponseData {
|
||||||
|
|
||||||
|
def validated(d8a : OneOfRequestAndResponse200ResponseData, failFast: Boolean) : Try[OneOfRequestAndResponse200Response] = {
|
||||||
|
d8a match {
|
||||||
|
case value : SomeResponse1Data => value.validated(failFast)
|
||||||
|
case value : SomeResponse2Data => value.validated(failFast)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def fromJsonString(jason : String) = fromJson {
|
||||||
|
try {
|
||||||
|
read[ujson.Value](jason)
|
||||||
|
} catch {
|
||||||
|
case NonFatal(e) => sys.error(s"Error parsing json '$jason': $e")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def fromJson(jason : ujson.Value) : OneOfRequestAndResponse200ResponseData = {
|
||||||
|
val attempt = Try(SomeResponse1Data.fromJson(jason)) .orElse( Try(SomeResponse2Data.fromJson(jason)) ) /* not first */
|
||||||
|
attempt.get
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* OpenAPI spec version: 1.0.0
|
||||||
|
*
|
||||||
|
* Contact: team@openapitools.org
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||||
|
*
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
*/
|
||||||
|
|
||||||
|
// this model was generated using model.mustache
|
||||||
|
package sample.cask.model
|
||||||
|
import java.time.LocalDate
|
||||||
|
import java.time.OffsetDateTime
|
||||||
|
import java.util.UUID
|
||||||
|
import scala.math.BigDecimal
|
||||||
|
|
||||||
|
import scala.util.control.NonFatal
|
||||||
|
|
||||||
|
// see https://com-lihaoyi.github.io/upickle/
|
||||||
|
import upickle.default.{ReadWriter => RW, macroRW}
|
||||||
|
import upickle.default.*
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
type OneOfRequestAndResponseRequest = AllOfRequest | ComplexRequest
|
||||||
|
object OneOfRequestAndResponseRequest {
|
||||||
|
|
||||||
|
given RW[OneOfRequestAndResponseRequest] = RW.merge(summon[RW[AllOfRequest]], summon[RW[ComplexRequest]])
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,51 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* OpenAPI spec version: 1.0.0
|
||||||
|
*
|
||||||
|
* Contact: team@openapitools.org
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||||
|
*
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
*/
|
||||||
|
|
||||||
|
// this model was generated using modelData.mustache
|
||||||
|
package sample.cask.model
|
||||||
|
import java.time.LocalDate
|
||||||
|
import java.time.OffsetDateTime
|
||||||
|
import java.util.UUID
|
||||||
|
import scala.math.BigDecimal
|
||||||
|
import scala.util.control.NonFatal
|
||||||
|
import scala.util.*
|
||||||
|
|
||||||
|
// see https://com-lihaoyi.github.io/upickle/
|
||||||
|
import upickle.default.{ReadWriter => RW, macroRW}
|
||||||
|
import upickle.default.*
|
||||||
|
|
||||||
|
|
||||||
|
type OneOfRequestAndResponseRequestData = AllOfRequestData | ComplexRequestData
|
||||||
|
|
||||||
|
object OneOfRequestAndResponseRequestData {
|
||||||
|
|
||||||
|
def validated(d8a : OneOfRequestAndResponseRequestData, failFast: Boolean) : Try[OneOfRequestAndResponseRequest] = {
|
||||||
|
d8a match {
|
||||||
|
case value : AllOfRequestData => value.validated(failFast)
|
||||||
|
case value : ComplexRequestData => value.validated(failFast)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def fromJsonString(jason : String) = fromJson {
|
||||||
|
try {
|
||||||
|
read[ujson.Value](jason)
|
||||||
|
} catch {
|
||||||
|
case NonFatal(e) => sys.error(s"Error parsing json '$jason': $e")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def fromJson(jason : ujson.Value) : OneOfRequestAndResponseRequestData = {
|
||||||
|
val attempt = Try(AllOfRequestData.fromJson(jason)) .orElse( Try(ComplexRequestData.fromJson(jason)) ) /* not first */
|
||||||
|
attempt.get
|
||||||
|
}
|
||||||
|
}
|
@ -73,3 +73,4 @@ enum Fields(val fieldName : String) extends Field(fieldName) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ case class OrderData(
|
|||||||
}
|
}
|
||||||
|
|
||||||
def validationErrors(path : Seq[Field], failFast : Boolean) : Seq[ValidationError] = {
|
def validationErrors(path : Seq[Field], failFast : Boolean) : Seq[ValidationError] = {
|
||||||
val errors = scala.collection.mutable.ListBuffer[ValidationError]()
|
val _allValidationErrors = scala.collection.mutable.ListBuffer[ValidationError]()
|
||||||
// ================== id validation ==================
|
// ================== id validation ==================
|
||||||
|
|
||||||
|
|
||||||
@ -82,7 +82,7 @@ case class OrderData(
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
errors.toSeq
|
_allValidationErrors.toSeq
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -111,6 +111,8 @@ case class OrderData(
|
|||||||
|
|
||||||
object OrderData {
|
object OrderData {
|
||||||
|
|
||||||
|
def validated(d8a : OrderData, failFast : Boolean) : scala.util.Try[Order] = d8a.validated(failFast)
|
||||||
|
|
||||||
def fromJson(jason : ujson.Value) : OrderData = try {
|
def fromJson(jason : ujson.Value) : OrderData = try {
|
||||||
val data = read[OrderData](jason)
|
val data = read[OrderData](jason)
|
||||||
data
|
data
|
||||||
|
@ -72,3 +72,4 @@ enum Fields(val fieldName : String) extends Field(fieldName) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ case class PetData(
|
|||||||
}
|
}
|
||||||
|
|
||||||
def validationErrors(path : Seq[Field], failFast : Boolean) : Seq[ValidationError] = {
|
def validationErrors(path : Seq[Field], failFast : Boolean) : Seq[ValidationError] = {
|
||||||
val errors = scala.collection.mutable.ListBuffer[ValidationError]()
|
val _allValidationErrors = scala.collection.mutable.ListBuffer[ValidationError]()
|
||||||
// ================== id validation ==================
|
// ================== id validation ==================
|
||||||
|
|
||||||
|
|
||||||
@ -57,8 +57,8 @@ case class PetData(
|
|||||||
|
|
||||||
|
|
||||||
// validating category
|
// validating category
|
||||||
if (errors.isEmpty || !failFast) {
|
if (_allValidationErrors.isEmpty || !failFast) {
|
||||||
if category != null then errors ++= category.validationErrors(path :+ Pet.Fields.category, failFast)
|
if category != null then _allValidationErrors ++= category.validationErrors(path :+ Pet.Fields.category, failFast)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ================== name validation ==================
|
// ================== name validation ==================
|
||||||
@ -78,11 +78,11 @@ case class PetData(
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (errors.isEmpty || !failFast) {
|
if (_allValidationErrors.isEmpty || !failFast) {
|
||||||
if (tags != null) {
|
if (tags != null) {
|
||||||
tags.zipWithIndex.foreach {
|
tags.zipWithIndex.foreach {
|
||||||
case (value, i) if errors.isEmpty || !failFast =>
|
case (value, i) if _allValidationErrors.isEmpty || !failFast =>
|
||||||
errors ++= value.validationErrors(
|
_allValidationErrors ++= value.validationErrors(
|
||||||
path :+ Pet.Fields.tags :+ Field(i.toString),
|
path :+ Pet.Fields.tags :+ Field(i.toString),
|
||||||
failFast)
|
failFast)
|
||||||
case (value, i) =>
|
case (value, i) =>
|
||||||
@ -97,7 +97,7 @@ case class PetData(
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
errors.toSeq
|
_allValidationErrors.toSeq
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -126,6 +126,8 @@ case class PetData(
|
|||||||
|
|
||||||
object PetData {
|
object PetData {
|
||||||
|
|
||||||
|
def validated(d8a : PetData, failFast : Boolean) : scala.util.Try[Pet] = d8a.validated(failFast)
|
||||||
|
|
||||||
def fromJson(jason : ujson.Value) : PetData = try {
|
def fromJson(jason : ujson.Value) : PetData = try {
|
||||||
val data = read[PetData](jason)
|
val data = read[PetData](jason)
|
||||||
data
|
data
|
||||||
|
@ -0,0 +1,55 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* OpenAPI spec version: 1.0.0
|
||||||
|
*
|
||||||
|
* Contact: team@openapitools.org
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||||
|
*
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
*/
|
||||||
|
|
||||||
|
// this model was generated using model.mustache
|
||||||
|
package sample.cask.model
|
||||||
|
|
||||||
|
import scala.util.control.NonFatal
|
||||||
|
|
||||||
|
// see https://com-lihaoyi.github.io/upickle/
|
||||||
|
import upickle.default.{ReadWriter => RW, macroRW}
|
||||||
|
import upickle.default.*
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
case class SomeResponse1(
|
||||||
|
status: String,
|
||||||
|
message: String
|
||||||
|
|
||||||
|
|
||||||
|
) {
|
||||||
|
|
||||||
|
def asJsonString: String = asData.asJsonString
|
||||||
|
def asJson: ujson.Value = asData.asJson
|
||||||
|
|
||||||
|
def asData : SomeResponse1Data = {
|
||||||
|
SomeResponse1Data(
|
||||||
|
status = status /* 2 */,
|
||||||
|
message = message /* 2 */
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object SomeResponse1 {
|
||||||
|
given RW[SomeResponse1] = summon[RW[ujson.Value]].bimap[SomeResponse1](_.asJson, json => read[SomeResponse1Data](json).asModel)
|
||||||
|
|
||||||
|
enum Fields(val fieldName : String) extends Field(fieldName) {
|
||||||
|
case status extends Fields("status")
|
||||||
|
case message extends Fields("message")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,137 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* OpenAPI spec version: 1.0.0
|
||||||
|
*
|
||||||
|
* Contact: team@openapitools.org
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||||
|
*
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
*/
|
||||||
|
|
||||||
|
// this model was generated using modelData.mustache
|
||||||
|
package sample.cask.model
|
||||||
|
import scala.util.control.NonFatal
|
||||||
|
import scala.util.*
|
||||||
|
|
||||||
|
// see https://com-lihaoyi.github.io/upickle/
|
||||||
|
import upickle.default.{ReadWriter => RW, macroRW}
|
||||||
|
import upickle.default.*
|
||||||
|
|
||||||
|
|
||||||
|
/** SomeResponse1Data a data transfer object, primarily for simple json serialisation.
|
||||||
|
* It has no validation - there may be nulls, values out of range, etc
|
||||||
|
*/
|
||||||
|
case class SomeResponse1Data(
|
||||||
|
status: String,
|
||||||
|
message: String
|
||||||
|
|
||||||
|
|
||||||
|
) derives RW {
|
||||||
|
|
||||||
|
def asJsonString: String = asJson.toString()
|
||||||
|
|
||||||
|
def asJson : ujson.Value = {
|
||||||
|
val jason = writeJs(this)
|
||||||
|
jason
|
||||||
|
}
|
||||||
|
|
||||||
|
def validationErrors(path : Seq[Field], failFast : Boolean) : Seq[ValidationError] = {
|
||||||
|
val _allValidationErrors = scala.collection.mutable.ListBuffer[ValidationError]()
|
||||||
|
// ================== status validation ==================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ================== message validation ==================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
_allValidationErrors.toSeq
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the validated model within a Try (if successful)
|
||||||
|
*/
|
||||||
|
def validated(failFast : Boolean = false) : scala.util.Try[SomeResponse1] = {
|
||||||
|
validationErrors(Vector(), failFast) match {
|
||||||
|
case Seq() => Success(asModel)
|
||||||
|
case first +: theRest => Failure(ValidationErrors(first, theRest))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** use 'validated' to check validation */
|
||||||
|
def asModel : SomeResponse1 = {
|
||||||
|
SomeResponse1(
|
||||||
|
status = status /* 2 */,
|
||||||
|
message = message /* 2 */
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object SomeResponse1Data {
|
||||||
|
|
||||||
|
def validated(d8a : SomeResponse1Data, failFast : Boolean) : scala.util.Try[SomeResponse1] = d8a.validated(failFast)
|
||||||
|
|
||||||
|
def fromJson(jason : ujson.Value) : SomeResponse1Data = try {
|
||||||
|
val data = read[SomeResponse1Data](jason)
|
||||||
|
data
|
||||||
|
} catch {
|
||||||
|
case NonFatal(e) => sys.error(s"Error creating SomeResponse1Data from json '$jason': $e")
|
||||||
|
}
|
||||||
|
|
||||||
|
def fromJsonString(jason : String) : SomeResponse1Data = {
|
||||||
|
val parsed = try {
|
||||||
|
read[ujson.Value](jason)
|
||||||
|
} catch {
|
||||||
|
case NonFatal(e) => sys.error(s"Error parsing json '$jason': $e")
|
||||||
|
}
|
||||||
|
fromJson(parsed)
|
||||||
|
}
|
||||||
|
|
||||||
|
def manyFromJsonString(jason : String) : Seq[SomeResponse1Data] = try {
|
||||||
|
read[List[SomeResponse1Data]](jason)
|
||||||
|
} catch {
|
||||||
|
case NonFatal(e) => sys.error(s"Error parsing json '$jason' as list: $e")
|
||||||
|
}
|
||||||
|
|
||||||
|
def manyFromJsonStringValidated(jason : String, failFast : Boolean = false) : Try[Seq[SomeResponse1]] = {
|
||||||
|
Try(manyFromJsonString(jason)).flatMap { list =>
|
||||||
|
list.zipWithIndex.foldLeft(Try(Vector[SomeResponse1]())) {
|
||||||
|
case (Success(list), (next, i)) =>
|
||||||
|
next.validated(failFast) match {
|
||||||
|
case Success(ok) => Success(list :+ ok)
|
||||||
|
case Failure(err) => Failure(new Exception(s"Validation error on element $i: ${err.getMessage}", err))
|
||||||
|
}
|
||||||
|
case (fail, _) => fail
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def mapFromJsonString(jason : String) : Map[String, SomeResponse1Data] = try {
|
||||||
|
read[Map[String, SomeResponse1Data]](jason)
|
||||||
|
} catch {
|
||||||
|
case NonFatal(e) => sys.error(s"Error parsing json '$jason' as map: $e")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def mapFromJsonStringValidated(jason : String, failFast : Boolean = false) : Try[Map[String, SomeResponse1]] = {
|
||||||
|
Try(mapFromJsonString(jason)).flatMap { map =>
|
||||||
|
map.foldLeft(Try(Map[String, SomeResponse1]())) {
|
||||||
|
case (Success(map), (key, next)) =>
|
||||||
|
next.validated(failFast) match {
|
||||||
|
case Success(ok) => Success(map.updated(key, ok))
|
||||||
|
case Failure(err) => Failure(new Exception(s"Validation error on element $key: ${err.getMessage}", err))
|
||||||
|
}
|
||||||
|
case (fail, _) => fail
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,59 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* OpenAPI spec version: 1.0.0
|
||||||
|
*
|
||||||
|
* Contact: team@openapitools.org
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||||
|
*
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
*/
|
||||||
|
|
||||||
|
// this model was generated using model.mustache
|
||||||
|
package sample.cask.model
|
||||||
|
import java.time.OffsetDateTime
|
||||||
|
|
||||||
|
import scala.util.control.NonFatal
|
||||||
|
|
||||||
|
// see https://com-lihaoyi.github.io/upickle/
|
||||||
|
import upickle.default.{ReadWriter => RW, macroRW}
|
||||||
|
import upickle.default.*
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
case class SomeResponse2(
|
||||||
|
id: String,
|
||||||
|
createdAt: OffsetDateTime,
|
||||||
|
details: Option[SomeResponse2Details] = None
|
||||||
|
|
||||||
|
|
||||||
|
) {
|
||||||
|
|
||||||
|
def asJsonString: String = asData.asJsonString
|
||||||
|
def asJson: ujson.Value = asData.asJson
|
||||||
|
|
||||||
|
def asData : SomeResponse2Data = {
|
||||||
|
SomeResponse2Data(
|
||||||
|
id = id /* 2 */,
|
||||||
|
createdAt = createdAt /* 2 */,
|
||||||
|
details = details.map(_.asData).getOrElse(null) /* 4 */
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object SomeResponse2 {
|
||||||
|
given RW[SomeResponse2] = summon[RW[ujson.Value]].bimap[SomeResponse2](_.asJson, json => read[SomeResponse2Data](json).asModel)
|
||||||
|
|
||||||
|
enum Fields(val fieldName : String) extends Field(fieldName) {
|
||||||
|
case id extends Fields("id")
|
||||||
|
case createdAt extends Fields("createdAt")
|
||||||
|
case details extends Fields("details")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,156 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* OpenAPI spec version: 1.0.0
|
||||||
|
*
|
||||||
|
* Contact: team@openapitools.org
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||||
|
*
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
*/
|
||||||
|
|
||||||
|
// this model was generated using modelData.mustache
|
||||||
|
package sample.cask.model
|
||||||
|
import java.time.OffsetDateTime
|
||||||
|
import scala.util.control.NonFatal
|
||||||
|
import scala.util.*
|
||||||
|
|
||||||
|
// see https://com-lihaoyi.github.io/upickle/
|
||||||
|
import upickle.default.{ReadWriter => RW, macroRW}
|
||||||
|
import upickle.default.*
|
||||||
|
|
||||||
|
|
||||||
|
/** SomeResponse2Data a data transfer object, primarily for simple json serialisation.
|
||||||
|
* It has no validation - there may be nulls, values out of range, etc
|
||||||
|
*/
|
||||||
|
case class SomeResponse2Data(
|
||||||
|
id: String,
|
||||||
|
createdAt: OffsetDateTime,
|
||||||
|
details: SomeResponse2DetailsData = null
|
||||||
|
|
||||||
|
|
||||||
|
) derives RW {
|
||||||
|
|
||||||
|
def asJsonString: String = asJson.toString()
|
||||||
|
|
||||||
|
def asJson : ujson.Value = {
|
||||||
|
val jason = writeJs(this)
|
||||||
|
jason
|
||||||
|
}
|
||||||
|
|
||||||
|
def validationErrors(path : Seq[Field], failFast : Boolean) : Seq[ValidationError] = {
|
||||||
|
val _allValidationErrors = scala.collection.mutable.ListBuffer[ValidationError]()
|
||||||
|
// ================== id validation ==================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ================== createdAt validation ==================
|
||||||
|
|
||||||
|
if (_allValidationErrors.isEmpty || !failFast) {
|
||||||
|
if (createdAt == null) {
|
||||||
|
_allValidationErrors += ValidationError(path :+ SomeResponse2.Fields.createdAt, "createdAt is a required field and cannot be null")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ================== details validation ==================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// validating details
|
||||||
|
if (_allValidationErrors.isEmpty || !failFast) {
|
||||||
|
if details != null then _allValidationErrors ++= details.validationErrors(path :+ SomeResponse2.Fields.details, failFast)
|
||||||
|
}
|
||||||
|
|
||||||
|
_allValidationErrors.toSeq
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the validated model within a Try (if successful)
|
||||||
|
*/
|
||||||
|
def validated(failFast : Boolean = false) : scala.util.Try[SomeResponse2] = {
|
||||||
|
validationErrors(Vector(), failFast) match {
|
||||||
|
case Seq() => Success(asModel)
|
||||||
|
case first +: theRest => Failure(ValidationErrors(first, theRest))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** use 'validated' to check validation */
|
||||||
|
def asModel : SomeResponse2 = {
|
||||||
|
SomeResponse2(
|
||||||
|
id = id /* 2 */,
|
||||||
|
createdAt = createdAt /* 2 */,
|
||||||
|
details = Option(details).map(_.asModel) /* 4 */
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object SomeResponse2Data {
|
||||||
|
|
||||||
|
def validated(d8a : SomeResponse2Data, failFast : Boolean) : scala.util.Try[SomeResponse2] = d8a.validated(failFast)
|
||||||
|
|
||||||
|
def fromJson(jason : ujson.Value) : SomeResponse2Data = try {
|
||||||
|
val data = read[SomeResponse2Data](jason)
|
||||||
|
data
|
||||||
|
} catch {
|
||||||
|
case NonFatal(e) => sys.error(s"Error creating SomeResponse2Data from json '$jason': $e")
|
||||||
|
}
|
||||||
|
|
||||||
|
def fromJsonString(jason : String) : SomeResponse2Data = {
|
||||||
|
val parsed = try {
|
||||||
|
read[ujson.Value](jason)
|
||||||
|
} catch {
|
||||||
|
case NonFatal(e) => sys.error(s"Error parsing json '$jason': $e")
|
||||||
|
}
|
||||||
|
fromJson(parsed)
|
||||||
|
}
|
||||||
|
|
||||||
|
def manyFromJsonString(jason : String) : Seq[SomeResponse2Data] = try {
|
||||||
|
read[List[SomeResponse2Data]](jason)
|
||||||
|
} catch {
|
||||||
|
case NonFatal(e) => sys.error(s"Error parsing json '$jason' as list: $e")
|
||||||
|
}
|
||||||
|
|
||||||
|
def manyFromJsonStringValidated(jason : String, failFast : Boolean = false) : Try[Seq[SomeResponse2]] = {
|
||||||
|
Try(manyFromJsonString(jason)).flatMap { list =>
|
||||||
|
list.zipWithIndex.foldLeft(Try(Vector[SomeResponse2]())) {
|
||||||
|
case (Success(list), (next, i)) =>
|
||||||
|
next.validated(failFast) match {
|
||||||
|
case Success(ok) => Success(list :+ ok)
|
||||||
|
case Failure(err) => Failure(new Exception(s"Validation error on element $i: ${err.getMessage}", err))
|
||||||
|
}
|
||||||
|
case (fail, _) => fail
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def mapFromJsonString(jason : String) : Map[String, SomeResponse2Data] = try {
|
||||||
|
read[Map[String, SomeResponse2Data]](jason)
|
||||||
|
} catch {
|
||||||
|
case NonFatal(e) => sys.error(s"Error parsing json '$jason' as map: $e")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def mapFromJsonStringValidated(jason : String, failFast : Boolean = false) : Try[Map[String, SomeResponse2]] = {
|
||||||
|
Try(mapFromJsonString(jason)).flatMap { map =>
|
||||||
|
map.foldLeft(Try(Map[String, SomeResponse2]())) {
|
||||||
|
case (Success(map), (key, next)) =>
|
||||||
|
next.validated(failFast) match {
|
||||||
|
case Success(ok) => Success(map.updated(key, ok))
|
||||||
|
case Failure(err) => Failure(new Exception(s"Validation error on element $key: ${err.getMessage}", err))
|
||||||
|
}
|
||||||
|
case (fail, _) => fail
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,55 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* OpenAPI spec version: 1.0.0
|
||||||
|
*
|
||||||
|
* Contact: team@openapitools.org
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||||
|
*
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
*/
|
||||||
|
|
||||||
|
// this model was generated using model.mustache
|
||||||
|
package sample.cask.model
|
||||||
|
|
||||||
|
import scala.util.control.NonFatal
|
||||||
|
|
||||||
|
// see https://com-lihaoyi.github.io/upickle/
|
||||||
|
import upickle.default.{ReadWriter => RW, macroRW}
|
||||||
|
import upickle.default.*
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
case class SomeResponse2Details(
|
||||||
|
description: Option[String] = None ,
|
||||||
|
status: Option[String] = None
|
||||||
|
|
||||||
|
|
||||||
|
) {
|
||||||
|
|
||||||
|
def asJsonString: String = asData.asJsonString
|
||||||
|
def asJson: ujson.Value = asData.asJson
|
||||||
|
|
||||||
|
def asData : SomeResponse2DetailsData = {
|
||||||
|
SomeResponse2DetailsData(
|
||||||
|
description = description.getOrElse("") /* 1 */,
|
||||||
|
status = status.getOrElse("") /* 1 */
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object SomeResponse2Details {
|
||||||
|
given RW[SomeResponse2Details] = summon[RW[ujson.Value]].bimap[SomeResponse2Details](_.asJson, json => read[SomeResponse2DetailsData](json).asModel)
|
||||||
|
|
||||||
|
enum Fields(val fieldName : String) extends Field(fieldName) {
|
||||||
|
case description extends Fields("description")
|
||||||
|
case status extends Fields("status")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,137 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* OpenAPI spec version: 1.0.0
|
||||||
|
*
|
||||||
|
* Contact: team@openapitools.org
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||||
|
*
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
*/
|
||||||
|
|
||||||
|
// this model was generated using modelData.mustache
|
||||||
|
package sample.cask.model
|
||||||
|
import scala.util.control.NonFatal
|
||||||
|
import scala.util.*
|
||||||
|
|
||||||
|
// see https://com-lihaoyi.github.io/upickle/
|
||||||
|
import upickle.default.{ReadWriter => RW, macroRW}
|
||||||
|
import upickle.default.*
|
||||||
|
|
||||||
|
|
||||||
|
/** SomeResponse2DetailsData a data transfer object, primarily for simple json serialisation.
|
||||||
|
* It has no validation - there may be nulls, values out of range, etc
|
||||||
|
*/
|
||||||
|
case class SomeResponse2DetailsData(
|
||||||
|
description: String = "" ,
|
||||||
|
status: String = ""
|
||||||
|
|
||||||
|
|
||||||
|
) derives RW {
|
||||||
|
|
||||||
|
def asJsonString: String = asJson.toString()
|
||||||
|
|
||||||
|
def asJson : ujson.Value = {
|
||||||
|
val jason = writeJs(this)
|
||||||
|
jason
|
||||||
|
}
|
||||||
|
|
||||||
|
def validationErrors(path : Seq[Field], failFast : Boolean) : Seq[ValidationError] = {
|
||||||
|
val _allValidationErrors = scala.collection.mutable.ListBuffer[ValidationError]()
|
||||||
|
// ================== description validation ==================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ================== status validation ==================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
_allValidationErrors.toSeq
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the validated model within a Try (if successful)
|
||||||
|
*/
|
||||||
|
def validated(failFast : Boolean = false) : scala.util.Try[SomeResponse2Details] = {
|
||||||
|
validationErrors(Vector(), failFast) match {
|
||||||
|
case Seq() => Success(asModel)
|
||||||
|
case first +: theRest => Failure(ValidationErrors(first, theRest))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** use 'validated' to check validation */
|
||||||
|
def asModel : SomeResponse2Details = {
|
||||||
|
SomeResponse2Details(
|
||||||
|
description = Option(description) /* 1 */,
|
||||||
|
status = Option(status) /* 1 */
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object SomeResponse2DetailsData {
|
||||||
|
|
||||||
|
def validated(d8a : SomeResponse2DetailsData, failFast : Boolean) : scala.util.Try[SomeResponse2Details] = d8a.validated(failFast)
|
||||||
|
|
||||||
|
def fromJson(jason : ujson.Value) : SomeResponse2DetailsData = try {
|
||||||
|
val data = read[SomeResponse2DetailsData](jason)
|
||||||
|
data
|
||||||
|
} catch {
|
||||||
|
case NonFatal(e) => sys.error(s"Error creating SomeResponse2DetailsData from json '$jason': $e")
|
||||||
|
}
|
||||||
|
|
||||||
|
def fromJsonString(jason : String) : SomeResponse2DetailsData = {
|
||||||
|
val parsed = try {
|
||||||
|
read[ujson.Value](jason)
|
||||||
|
} catch {
|
||||||
|
case NonFatal(e) => sys.error(s"Error parsing json '$jason': $e")
|
||||||
|
}
|
||||||
|
fromJson(parsed)
|
||||||
|
}
|
||||||
|
|
||||||
|
def manyFromJsonString(jason : String) : Seq[SomeResponse2DetailsData] = try {
|
||||||
|
read[List[SomeResponse2DetailsData]](jason)
|
||||||
|
} catch {
|
||||||
|
case NonFatal(e) => sys.error(s"Error parsing json '$jason' as list: $e")
|
||||||
|
}
|
||||||
|
|
||||||
|
def manyFromJsonStringValidated(jason : String, failFast : Boolean = false) : Try[Seq[SomeResponse2Details]] = {
|
||||||
|
Try(manyFromJsonString(jason)).flatMap { list =>
|
||||||
|
list.zipWithIndex.foldLeft(Try(Vector[SomeResponse2Details]())) {
|
||||||
|
case (Success(list), (next, i)) =>
|
||||||
|
next.validated(failFast) match {
|
||||||
|
case Success(ok) => Success(list :+ ok)
|
||||||
|
case Failure(err) => Failure(new Exception(s"Validation error on element $i: ${err.getMessage}", err))
|
||||||
|
}
|
||||||
|
case (fail, _) => fail
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def mapFromJsonString(jason : String) : Map[String, SomeResponse2DetailsData] = try {
|
||||||
|
read[Map[String, SomeResponse2DetailsData]](jason)
|
||||||
|
} catch {
|
||||||
|
case NonFatal(e) => sys.error(s"Error parsing json '$jason' as map: $e")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def mapFromJsonStringValidated(jason : String, failFast : Boolean = false) : Try[Map[String, SomeResponse2Details]] = {
|
||||||
|
Try(mapFromJsonString(jason)).flatMap { map =>
|
||||||
|
map.foldLeft(Try(Map[String, SomeResponse2Details]())) {
|
||||||
|
case (Success(map), (key, next)) =>
|
||||||
|
next.validated(failFast) match {
|
||||||
|
case Success(ok) => Success(map.updated(key, ok))
|
||||||
|
case Failure(err) => Failure(new Exception(s"Validation error on element $key: ${err.getMessage}", err))
|
||||||
|
}
|
||||||
|
case (fail, _) => fail
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -52,3 +52,4 @@ enum Fields(val fieldName : String) extends Field(fieldName) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ case class TagData(
|
|||||||
}
|
}
|
||||||
|
|
||||||
def validationErrors(path : Seq[Field], failFast : Boolean) : Seq[ValidationError] = {
|
def validationErrors(path : Seq[Field], failFast : Boolean) : Seq[ValidationError] = {
|
||||||
val errors = scala.collection.mutable.ListBuffer[ValidationError]()
|
val _allValidationErrors = scala.collection.mutable.ListBuffer[ValidationError]()
|
||||||
// ================== id validation ==================
|
// ================== id validation ==================
|
||||||
|
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ case class TagData(
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
errors.toSeq
|
_allValidationErrors.toSeq
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -77,6 +77,8 @@ case class TagData(
|
|||||||
|
|
||||||
object TagData {
|
object TagData {
|
||||||
|
|
||||||
|
def validated(d8a : TagData, failFast : Boolean) : scala.util.Try[Tag] = d8a.validated(failFast)
|
||||||
|
|
||||||
def fromJson(jason : ujson.Value) : TagData = try {
|
def fromJson(jason : ujson.Value) : TagData = try {
|
||||||
val data = read[TagData](jason)
|
val data = read[TagData](jason)
|
||||||
data
|
data
|
||||||
|
@ -71,3 +71,4 @@ enum Fields(val fieldName : String) extends Field(fieldName) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ case class UserData(
|
|||||||
}
|
}
|
||||||
|
|
||||||
def validationErrors(path : Seq[Field], failFast : Boolean) : Seq[ValidationError] = {
|
def validationErrors(path : Seq[Field], failFast : Boolean) : Seq[ValidationError] = {
|
||||||
val errors = scala.collection.mutable.ListBuffer[ValidationError]()
|
val _allValidationErrors = scala.collection.mutable.ListBuffer[ValidationError]()
|
||||||
// ================== id validation ==================
|
// ================== id validation ==================
|
||||||
|
|
||||||
|
|
||||||
@ -95,7 +95,7 @@ case class UserData(
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
errors.toSeq
|
_allValidationErrors.toSeq
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -126,6 +126,8 @@ case class UserData(
|
|||||||
|
|
||||||
object UserData {
|
object UserData {
|
||||||
|
|
||||||
|
def validated(d8a : UserData, failFast : Boolean) : scala.util.Try[User] = d8a.validated(failFast)
|
||||||
|
|
||||||
def fromJson(jason : ujson.Value) : UserData = try {
|
def fromJson(jason : ujson.Value) : UserData = try {
|
||||||
val data = read[UserData](jason)
|
val data = read[UserData](jason)
|
||||||
data
|
data
|
||||||
|
Loading…
x
Reference in New Issue
Block a user