diff --git a/packages/type-safe-api/scripts/type-safe-api/generators/generate-next.ts b/packages/type-safe-api/scripts/type-safe-api/generators/generate-next.ts index 959214ffd..54b410c3c 100755 --- a/packages/type-safe-api/scripts/type-safe-api/generators/generate-next.ts +++ b/packages/type-safe-api/scripts/type-safe-api/generators/generate-next.ts @@ -17,6 +17,7 @@ import _orderBy from "lodash/orderBy"; import _uniq from "lodash/uniq"; import _uniqBy from "lodash/uniqBy"; import _isEqual from "lodash/isEqual"; +import _cloneDeepWith from "lodash/cloneDeepWith" import { OpenAPIV3 } from "openapi-types"; import * as parseOpenapi from "parse-openapi"; import { getOperationResponses } from "parse-openapi/dist/parser/getOperationResponses"; @@ -302,6 +303,7 @@ const splitAndWriteFiles = (renderedFileContents: string[], outputPath: string) // Model types which indicate it is composed (ie inherits/mixin's another schema) const COMPOSED_SCHEMA_TYPES = new Set(["one-of", "any-of", "all-of"]); +const COLLECTION_TYPES = new Set(["array", "dictionary"]); const PRIMITIVE_TYPES = new Set(["string", "integer", "number", "boolean", "null", "any", "binary", "void"]); /** @@ -496,7 +498,7 @@ const mutateModelWithAdditionalTypes = (model: parseOpenapi.Model) => { (model as any).javaType = toJavaType(model); (model as any).pythonName = toPythonName('property', model.name); (model as any).pythonType = toPythonType(model); - (model as any).isPrimitive = PRIMITIVE_TYPES.has(model.type); + (model as any).isPrimitive = PRIMITIVE_TYPES.has(model.type) && !COMPOSED_SCHEMA_TYPES.has(model.export) && !COLLECTION_TYPES.has(model.export); }; interface MockDataContext { @@ -615,6 +617,8 @@ const _ensureModelLinks = (spec: OpenAPIV3.Document, modelsByName: {[name: strin if (modelsByName[name] && !model.link) { model.link = modelsByName[name]; } + } else if (model.link && typeof schema.additionalProperties !== 'boolean') { + _ensureModelLinks(spec, modelsByName, model.link, schema.additionalProperties, visited); } } else if (model.export === "array" && 'items' in schema && schema.items) { if (isRef(schema.items)) { @@ -622,6 +626,8 @@ const _ensureModelLinks = (spec: OpenAPIV3.Document, modelsByName: {[name: strin if (modelsByName[name] && !model.link) { model.link = modelsByName[name]; } + } else if (model.link) { + _ensureModelLinks(spec, modelsByName, model.link, schema.items, visited); } } @@ -713,13 +719,12 @@ const buildData = async (inSpec: OpenAPIV3.Document, metadata: any) => { // In order for the new generator not to be breaking, we apply the same logic here, however this can be removed // in future since we have control to avoid the duplicate handlers while allowing an operation to be part of // multiple "services". - let spec = JSON.parse(JSON.stringify(inSpec, (key, value) => { + let spec = _cloneDeepWith(inSpec, (value, key) => { // Keep only the first tag where we find a tag if (key === "tags" && value && value.length > 0 && typeof value[0] === "string") { return [value[0]]; } - return value; - })) as OpenAPIV3.Document; + }) as OpenAPIV3.Document; // Ensure spec has schemas set if (!spec?.components?.schemas) { @@ -775,7 +780,7 @@ const buildData = async (inSpec: OpenAPIV3.Document, metadata: any) => { // "Inline" any refs to non objects/enums const inlinedRefs: Set = new Set(); - spec = JSON.parse(JSON.stringify(spec, (k, v) => { + spec = _cloneDeepWith(spec, (v) => { if (v && typeof v === "object" && v.$ref) { const resolved = resolveRef(spec, v.$ref); if (resolved && resolved.type && resolved.type !== "object" && !(resolved.type === "string" && resolved.enum)) { @@ -783,8 +788,7 @@ const buildData = async (inSpec: OpenAPIV3.Document, metadata: any) => { return resolved; } } - return v; - })); + }); // Delete the non object schemas that were inlined [...inlinedRefs].forEach(ref => { @@ -808,7 +812,7 @@ const buildData = async (inSpec: OpenAPIV3.Document, metadata: any) => { faker.setDefaultRefDate(new Date("2021-06-10")); const mockDataContext: MockDataContext = { faker, - dereferencedSpec: await SwaggerParser.dereference(structuredClone(spec), { dereference: { circular: 'ignore' }}) as OpenAPIV3.Document, + dereferencedSpec: await SwaggerParser.dereference(structuredClone(spec), { dereference: { circular: 'ignore' } }) as OpenAPIV3.Document, }; // Augment operations with additional data diff --git a/packages/type-safe-api/scripts/type-safe-api/generators/typescript/templates/client/models/models.ejs b/packages/type-safe-api/scripts/type-safe-api/generators/typescript/templates/client/models/models.ejs index a28a68295..669a66ddb 100644 --- a/packages/type-safe-api/scripts/type-safe-api/generators/typescript/templates/client/models/models.ejs +++ b/packages/type-safe-api/scripts/type-safe-api/generators/typescript/templates/client/models/models.ejs @@ -33,6 +33,16 @@ import { } from './<%= importName %>'; <%_ }); _%> <%_ const isComposite = model.export === "one-of" || model.export === "any-of" || model.export === "all-of"; _%> +<%_ +// Nested arrays of primitives (besides dates) don't need to have .map(...) called to convert them as the base case will be a noop +// eg. an array of arrays of strings doesn't need to be rendered as `value.map(item0 => item0.map(item1 => item1))` +const canShortCircuitConversion = (property) => { + if (["array", "dictionary"].includes(property.export)) { + return canShortCircuitConversion(property.link); + } + return property.isPrimitive && !["date", "date-time"].includes(property.format); +}; +_%> <%_ if (model.export === "enum") { _%> /** @@ -126,19 +136,45 @@ export function <%= model.name %>FromJSONTyped(json: any, ignoreDiscriminator: b <%_ } else { _%> return { +<%_ +// Renders the appropriate nested function for .map() or mapValues() for arrays and dictionaries for the given type +const renderNestedFromJsonValue = (type, depth = 0) => { + const itemIdentifier = `item${depth}`; + if (type.isPrimitive) { + return `(${itemIdentifier}) => ${["date", "date-time"].includes(type.format) ? `new Date(${itemIdentifier})` : itemIdentifier}`; + } else if (type.export === "array") { + return `(${itemIdentifier}) => ${itemIdentifier}.map(${renderNestedFromJsonValue(type.link, depth + 1)})`; + } else if (type.export === "dictionary") { + return `(${itemIdentifier}) => mapValues(${itemIdentifier}, ${renderNestedFromJsonValue(type.link, depth + 1)})`; + } + return `${type.name || type.type}FromJSON`; +}; +// Renders the code to transform a property of the model from its json representation into the model types +const renderFromJsonValue = (property) => { + const value = `json['${property.name}']`; + let rendered = ''; + if (canShortCircuitConversion(property)) { + rendered = value; + } else if (property.isPrimitive) { + rendered = ["date", "date-time"].includes(property.format) ? `(new Date(${value}))` : value; + } else if (property.export === "array") { + rendered = `((${value} as Array).map(${renderNestedFromJsonValue(property.link)}))`; + rendered = property.uniqueItems ? `new Set(${rendered})` : rendered; + } else if (property.export === "dictionary") { + rendered = `(mapValues(${value}, ${renderNestedFromJsonValue(property.link)}))`; + } else { + rendered = `${property.type}FromJSON(${value})`; + } + rendered = property.isNullable ? `${value} === null ? null : ${rendered}` : rendered; + rendered = !property.isRequired ? `!exists(json, '${property.name}') ? undefined : ${rendered}` : rendered; + return rendered; +}; +_%> <%_ if (model.export === "dictionary") { _%> ...json, <%_ } _%> <%_ model.properties.forEach((property) => { _%> - <%_ if (property.isPrimitive) { _%> - '<%= property.typescriptName %>': <% if (!property.isRequired) { %>!exists(json, '<%- property.name %>') ? undefined : <% } %><% if (["date", "date-time"].includes(property.format) && property.isNullable) { %>json['<%- property.name %>'] === null ? null : <% } %><% if (["date", "date-time"].includes(property.format)) { %>(new Date(json['<%= property.name %>']))<% } else { %>json['<%= property.name %>']<% } %>, - <%_ } else if (property.export === 'array') { _%> - '<%= property.typescriptName %>': <% if (!property.isRequired) { %>!exists(json, '<%- property.name %>') ? undefined : <% } %><% if (property.isNullable) { %>json['<%- property.name %>'] === null ? null : <% } %><%= property.uniqueItems ? 'new Set(' : '' %>((json['<%= property.name %>'] as Array).map(<%= property.type %>FromJSON))<%= property.uniqueItems ? ')' : '' %>, - <%_ } else if (property.export === 'dictionary') { _%> - '<%= property.typescriptName %>': <% if (!property.isRequired) { %>!exists(json, '<%- property.name %>') ? undefined : <% } %><% if (property.isNullable) { %>json['<%- property.name %>'] === null ? null : <% } %>(mapValues(json['<%= property.name %>'], <%= property.type %>FromJSON)), - <%_ } else { _%> - '<%= property.typescriptName %>': <% if (!property.isRequired) { %>!exists(json, '<%- property.name %>') ? undefined : <% } %><% if (property.isNullable) { %>json['<%- property.name %>'] === null ? null : <% } %><%= property.type %>FromJSON(json['<%= property.name %>']), - <%_ } _%> + '<%= property.typescriptName %>': <%- renderFromJsonValue(property) %>, <%_ }); _%> }; <%_ } _%> @@ -173,24 +209,56 @@ export function <%= model.name %>ToJSON(value?: <%= model.name %> | null): any { <%_ } else { _%> return { +<%_ +// Render code to convert a date to its string representation +const renderToJsonDateValue = (identifier, format) => { + return `${identifier}.toISOString()${format === 'date' ? '.substr(0,10)' : ''}`; +}; +// Renders the appropriate nested function for .map() or mapValues() for arrays and dictionaries for the given type +const renderNestedToJsonValue = (type, depth = 0) => { + const itemIdentifier = `item${depth}`; + if (type.isPrimitive) { + return `(${itemIdentifier}) => ${["date", "date-time"].includes(type.format) ? renderToJsonDateValue(itemIdentifier, type.format) : itemIdentifier}`; + } else if (type.export === "array") { + return `(${itemIdentifier}) => ${itemIdentifier}.map(${renderNestedToJsonValue(type.link, depth + 1)})`; + } else if (type.export === "dictionary") { + return `(${itemIdentifier}) => mapValues(${itemIdentifier}, ${renderNestedToJsonValue(type.link, depth + 1)})`; + } + return `${type.name || type.type}ToJSON`; +}; +// Renders the code to transform a property of the model to its json representation from the model types +const renderToJsonValue = (property) => { + const value = `value.${property.typescriptName}`; + let rendered = ''; + + if (canShortCircuitConversion(property)) { + rendered = value; + } else if (property.isPrimitive) { + rendered = ["date", "date-time"].includes(property.format) ? `(${renderToJsonDateValue(value, property.format)})` : value; + } else if (property.export === "array") { + const prefix = property.uniqueItems ? `Array.from(${value} as Array)` : `(${value} as Array)`; + rendered = `(${prefix}.map(${renderNestedToJsonValue(property.link)}))`; + } else if (property.export === "dictionary") { + rendered = `(mapValues(${value}, ${renderNestedToJsonValue(property.link)}))`; + } else if (property.type !== "any") { + rendered = `${property.type}ToJSON(${value})`; + } else { + rendered = value; + } + + if ((property.isPrimitive && ["date", "date-time"].includes(property.format)) || (!property.isPrimitive && ["array", "dictionary"].includes(property.export))) { + rendered = property.isNullable ? `${value} === null ? null : ${rendered}` : rendered; + rendered = !property.isRequired ? `${value} === undefined ? undefined : ${rendered}` : rendered; + } + return rendered; +}; +_%> <%_ if (model.export === "dictionary") { _%> ...value, <%_ } _%> <%_ model.properties.forEach((property) => { _%> <%_ if (!property.isReadOnly) { _%> - <%_ if (property.isPrimitive && ["date", "date-time"].includes(property.format)) { _%> - '<%= property.name %>': <% if (!property.isRequired) { %>value.<%- property.typescriptName %> === undefined ? undefined : <% } %>(<% if (property.isNullable) { %>value.<%- property.typescriptName %> === null ? null : <% } %>value.<%- property.typescriptName %>.toISOString()<% if (property.format === 'date') { %>.substr(0,10)<% } %>), - <%_ } else if (property.isPrimitive) { _%> - '<%= property.name %>': value.<%- property.typescriptName %>, - <%_ } else if (property.export === 'array') { _%> - '<%= property.name %>': <% if (!property.isRequired) { %>value.<%- property.typescriptName %> === undefined ? undefined : <% } %>(<% if (property.isNullable) { %>value.<%- property.typescriptName %> === null ? null : <% } %><% if (property.uniqueItems) { %>Array.from(value.<%- property.typescriptName %> as Set)<% } else { %>(value.<%- property.typescriptName %> as Array)<% } %>.map(<%- property.type %>ToJSON)), - <%_ } else if (property.export === 'dictionary') { _%> - '<%= property.name %>': <% if (!property.isRequired) { %>value.<%- property.typescriptName %> === undefined ? undefined : <% } %>(<% if (property.isNullable) { %>value.<%- property.typescriptName %> === null ? null : <% } %>mapValues(value.<%- property.typescriptName %>, <%- property.type %>ToJSON)), - <%_ } else if (property.type !== 'any') { _%> - '<%= property.name %>': <%- property.type %>ToJSON(value.<%- property.typescriptName %>), - <%_ } else { _%> - '<%= property.name %>': value.<%- property.typescriptName %>, - <%_ } _%> + '<%= property.name %>': <%- renderToJsonValue(property) %>, <%_ } _%> <%_ }); _%> }; diff --git a/packages/type-safe-api/test/resources/specs/edge-cases.yaml b/packages/type-safe-api/test/resources/specs/edge-cases.yaml index cf100a7a6..550a8d6e0 100644 --- a/packages/type-safe-api/test/resources/specs/edge-cases.yaml +++ b/packages/type-safe-api/test/resources/specs/edge-cases.yaml @@ -138,6 +138,16 @@ paths: application/json: schema: $ref: "#/components/schemas/ArrayOfOneOfs" + /nested-collections: + post: + operationId: nestedCollections + responses: + 200: + description: ok + content: + application/json: + schema: + $ref: "#/components/schemas/NestedCollections" /additional-properties: post: operationId: dictionary @@ -175,6 +185,96 @@ components: type: array items: $ref: "#/components/schemas/NamedOneOfUnion" + NestedCollections: + type: object + properties: + nestedArrayOfStrings: + type: array + items: + type: array + items: + type: string + nestedArrayOfDates: + type: array + items: + type: array + items: + type: string + format: date + nestedArrayOfObjects: + type: array + items: + type: array + items: + $ref: "#/components/schemas/SomeObject" + fourDimensionalNestedArrayOfObjects: + type: array + items: + type: array + items: + type: array + items: + type: array + items: + $ref: "#/components/schemas/SomeObject" + nestedDictionaryOfStrings: + type: object + additionalProperties: + type: object + additionalProperties: + type: string + nestedDictionaryOfObjects: + type: object + additionalProperties: + type: object + additionalProperties: + $ref: "#/components/schemas/SomeObject" + fourDimensionalNestedDictionaryOfObjects: + type: object + additionalProperties: + type: object + additionalProperties: + type: object + additionalProperties: + type: object + additionalProperties: + $ref: "#/components/schemas/SomeObject" + nestedMixOfDictionariesAndArrays: + type: array + items: + type: object + additionalProperties: + type: array + items: + type: array + items: + type: object + additionalProperties: + type: array + items: + $ref: "#/components/schemas/SomeObject" + cycleArray: + $ref: "#/components/schemas/CycleArray" + cycleDictionary: + $ref: "#/components/schemas/CycleDictionary" + CycleArray: + type: array + items: + $ref: "#/components/schemas/CycleArrayNode" + CycleArrayNode: + type: object + properties: + nodes: + $ref: "#/components/schemas/CycleArray" + CycleDictionary: + type: object + additionalProperties: + $ref: "#/components/schemas/CycleDictionaryNode" + CycleDictionaryNode: + type: object + properties: + nodes: + $ref: "#/components/schemas/CycleDictionary" AdditionalPropertiesResponse: type: object properties: diff --git a/packages/type-safe-api/test/scripts/generators/__snapshots__/java.test.ts.snap b/packages/type-safe-api/test/scripts/generators/__snapshots__/java.test.ts.snap index 342f0a7eb..fa7ceeca9 100644 --- a/packages/type-safe-api/test/scripts/generators/__snapshots__/java.test.ts.snap +++ b/packages/type-safe-api/test/scripts/generators/__snapshots__/java.test.ts.snap @@ -22835,9 +22835,6 @@ public class DataTypes200Response { if (jsonObj.get("myDateArray") != null && !jsonObj.get("myDateArray").isJsonArray()) { throw new IllegalArgumentException(String.format("Expected the field \`myDateArray\` to be an array in the JSON string but got \`%s\`", jsonObj.get("myDateArray").toString())); } - if ((jsonObj.get("myDateArray") != null && !jsonObj.get("myDateArray").isJsonNull()) && !jsonObj.get("myDateArray").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field \`myDateArray\` to be a primitive type in the JSON string but got \`%s\`", jsonObj.get("myDateArray").toString())); - } if ((jsonObj.get("myEmail") != null && !jsonObj.get("myEmail").isJsonNull()) && !jsonObj.get("myEmail").isJsonPrimitive()) { throw new IllegalArgumentException(String.format("Expected the field \`myEmail\` to be a primitive type in the JSON string but got \`%s\`", jsonObj.get("myEmail").toString())); } @@ -30345,6 +30342,9 @@ src/main/java/test/test/runtime/model/AbstractOpenApiSchema.java src/main/java/test/test/runtime/model/AdditionalPropertiesResponse.java src/main/java/test/test/runtime/model/AnotherNamedOneOf.java src/main/java/test/test/runtime/model/ArrayOfOneOfs.java +src/main/java/test/test/runtime/model/CycleArrayNode.java +src/main/java/test/test/runtime/model/CycleDictionary.java +src/main/java/test/test/runtime/model/CycleDictionaryNode.java src/main/java/test/test/runtime/model/Dictionary.java src/main/java/test/test/runtime/model/InlineEnum200Response.java src/main/java/test/test/runtime/model/InlineEnum200ResponseCategoryEnum.java @@ -30352,6 +30352,7 @@ src/main/java/test/test/runtime/model/InlineRequestBodyRequestContent.java src/main/java/test/test/runtime/model/MyEnum.java src/main/java/test/test/runtime/model/NamedOneOf.java src/main/java/test/test/runtime/model/NamedOneOfUnion.java +src/main/java/test/test/runtime/model/NestedCollections.java src/main/java/test/test/runtime/model/SomeObject.java src/main/java/test/test/runtime/api/handlers/Handlers.java src/main/java/test/test/runtime/api/handlers/Response.java @@ -30369,6 +30370,7 @@ src/main/java/test/test/runtime/api/handlers/dictionary/DictionaryResponse.java src/main/java/test/test/runtime/api/handlers/inline_enum/InlineEnumResponse.java src/main/java/test/test/runtime/api/handlers/inline_request_body/InlineRequestBodyResponse.java src/main/java/test/test/runtime/api/handlers/named_one_of/NamedOneOfResponse.java +src/main/java/test/test/runtime/api/handlers/nested_collections/NestedCollectionsResponse.java src/main/java/test/test/runtime/api/handlers/reserved_keywords/ReservedKeywordsResponse.java src/main/java/test/test/runtime/api/handlers/array_of_one_ofs/ArrayOfOneOfs200Response.java src/main/java/test/test/runtime/api/handlers/array_request_parameters/ArrayRequestParameters200Response.java @@ -30376,6 +30378,7 @@ src/main/java/test/test/runtime/api/handlers/dictionary/Dictionary200Response.ja src/main/java/test/test/runtime/api/handlers/inline_enum/InlineEnum200Response.java src/main/java/test/test/runtime/api/handlers/inline_request_body/InlineRequestBody204Response.java src/main/java/test/test/runtime/api/handlers/named_one_of/NamedOneOf200Response.java +src/main/java/test/test/runtime/api/handlers/nested_collections/NestedCollections200Response.java src/main/java/test/test/runtime/api/handlers/reserved_keywords/ReservedKeywords200Response.java src/main/java/test/test/runtime/api/handlers/array_of_one_ofs/ArrayOfOneOfsRequestParameters.java src/main/java/test/test/runtime/api/handlers/array_request_parameters/ArrayRequestParametersRequestParameters.java @@ -30383,6 +30386,7 @@ src/main/java/test/test/runtime/api/handlers/dictionary/DictionaryRequestParamet src/main/java/test/test/runtime/api/handlers/inline_enum/InlineEnumRequestParameters.java src/main/java/test/test/runtime/api/handlers/inline_request_body/InlineRequestBodyRequestParameters.java src/main/java/test/test/runtime/api/handlers/named_one_of/NamedOneOfRequestParameters.java +src/main/java/test/test/runtime/api/handlers/nested_collections/NestedCollectionsRequestParameters.java src/main/java/test/test/runtime/api/handlers/reserved_keywords/ReservedKeywordsRequestParameters.java src/main/java/test/test/runtime/api/handlers/array_of_one_ofs/ArrayOfOneOfsInput.java src/main/java/test/test/runtime/api/handlers/array_request_parameters/ArrayRequestParametersInput.java @@ -30390,6 +30394,7 @@ src/main/java/test/test/runtime/api/handlers/dictionary/DictionaryInput.java src/main/java/test/test/runtime/api/handlers/inline_enum/InlineEnumInput.java src/main/java/test/test/runtime/api/handlers/inline_request_body/InlineRequestBodyInput.java src/main/java/test/test/runtime/api/handlers/named_one_of/NamedOneOfInput.java +src/main/java/test/test/runtime/api/handlers/nested_collections/NestedCollectionsInput.java src/main/java/test/test/runtime/api/handlers/reserved_keywords/ReservedKeywordsInput.java src/main/java/test/test/runtime/api/handlers/array_of_one_ofs/ArrayOfOneOfsRequestInput.java src/main/java/test/test/runtime/api/handlers/array_request_parameters/ArrayRequestParametersRequestInput.java @@ -30397,6 +30402,7 @@ src/main/java/test/test/runtime/api/handlers/dictionary/DictionaryRequestInput.j src/main/java/test/test/runtime/api/handlers/inline_enum/InlineEnumRequestInput.java src/main/java/test/test/runtime/api/handlers/inline_request_body/InlineRequestBodyRequestInput.java src/main/java/test/test/runtime/api/handlers/named_one_of/NamedOneOfRequestInput.java +src/main/java/test/test/runtime/api/handlers/nested_collections/NestedCollectionsRequestInput.java src/main/java/test/test/runtime/api/handlers/reserved_keywords/ReservedKeywordsRequestInput.java src/main/java/test/test/runtime/api/handlers/array_of_one_ofs/ArrayOfOneOfs.java src/main/java/test/test/runtime/api/handlers/array_request_parameters/ArrayRequestParameters.java @@ -30404,6 +30410,7 @@ src/main/java/test/test/runtime/api/handlers/dictionary/Dictionary.java src/main/java/test/test/runtime/api/handlers/inline_enum/InlineEnum.java src/main/java/test/test/runtime/api/handlers/inline_request_body/InlineRequestBody.java src/main/java/test/test/runtime/api/handlers/named_one_of/NamedOneOf.java +src/main/java/test/test/runtime/api/handlers/nested_collections/NestedCollections.java src/main/java/test/test/runtime/api/handlers/reserved_keywords/ReservedKeywords.java src/main/java/test/test/runtime/api/handlers/HandlerRouter.java src/main/java/test/test/runtime/api/interceptors/TryCatchInterceptor.java @@ -32484,11 +32491,15 @@ public class JSON { gsonBuilder.registerTypeAdapterFactory(new test.test.runtime.model.AdditionalPropertiesResponse.CustomTypeAdapterFactory()); gsonBuilder.registerTypeAdapterFactory(new test.test.runtime.model.AnotherNamedOneOf.CustomTypeAdapterFactory()); gsonBuilder.registerTypeAdapterFactory(new test.test.runtime.model.ArrayOfOneOfs.CustomTypeAdapterFactory()); + gsonBuilder.registerTypeAdapterFactory(new test.test.runtime.model.CycleArrayNode.CustomTypeAdapterFactory()); + gsonBuilder.registerTypeAdapterFactory(new test.test.runtime.model.CycleDictionary.CustomTypeAdapterFactory()); + gsonBuilder.registerTypeAdapterFactory(new test.test.runtime.model.CycleDictionaryNode.CustomTypeAdapterFactory()); gsonBuilder.registerTypeAdapterFactory(new test.test.runtime.model.Dictionary.CustomTypeAdapterFactory()); gsonBuilder.registerTypeAdapterFactory(new test.test.runtime.model.InlineEnum200Response.CustomTypeAdapterFactory()); gsonBuilder.registerTypeAdapterFactory(new test.test.runtime.model.InlineRequestBodyRequestContent.CustomTypeAdapterFactory()); gsonBuilder.registerTypeAdapterFactory(new test.test.runtime.model.NamedOneOf.CustomTypeAdapterFactory()); gsonBuilder.registerTypeAdapterFactory(new test.test.runtime.model.NamedOneOfUnion.CustomTypeAdapterFactory()); + gsonBuilder.registerTypeAdapterFactory(new test.test.runtime.model.NestedCollections.CustomTypeAdapterFactory()); gsonBuilder.registerTypeAdapterFactory(new test.test.runtime.model.SomeObject.CustomTypeAdapterFactory()); gson = gsonBuilder.create(); } @@ -33196,6 +33207,7 @@ import test.test.runtime.model.InlineEnum200Response; import test.test.runtime.model.InlineRequestBodyRequestContent; import test.test.runtime.model.MyEnum; import test.test.runtime.model.NamedOneOfUnion; +import test.test.runtime.model.NestedCollections; import java.lang.reflect.Type; import java.util.ArrayList; @@ -34248,6 +34260,151 @@ public class DefaultApi { public APInamedOneOfRequest namedOneOf() { return new APInamedOneOfRequest(); } + private okhttp3.Call nestedCollectionsCall(final ApiCallback _callback) throws ApiException { + String basePath = null; + // Operation Servers + String[] localBasePaths = new String[] { }; + + // Determine Base Path to Use + if (localCustomBaseUrl != null){ + basePath = localCustomBaseUrl; + } else if ( localBasePaths.length > 0 ) { + basePath = localBasePaths[localHostIndex]; + } else { + basePath = null; + } + + Object localVarPostBody = null; + + // create path and map variables + String localVarPath = "/nested-collections"; + + List localVarQueryParams = new ArrayList(); + List localVarCollectionQueryParams = new ArrayList(); + Map localVarHeaderParams = new HashMap(); + Map localVarCookieParams = new HashMap(); + Map localVarFormParams = new HashMap(); + + final String[] localVarAccepts = { + "application/json" + }; + final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); + if (localVarAccept != null) { + localVarHeaderParams.put("Accept", localVarAccept); + } + + final String[] localVarContentTypes = { + }; + final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); + if (localVarContentType != null) { + localVarHeaderParams.put("Content-Type", localVarContentType); + } + + String[] localVarAuthNames = new String[] { }; + return localVarApiClient.buildCall(basePath, localVarPath, "POST", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); + } + + + @SuppressWarnings("rawtypes") + private okhttp3.Call nestedCollectionsValidateBeforeCall(final ApiCallback _callback) throws ApiException { + return nestedCollectionsCall(_callback); + + } + + private ApiResponse nestedCollectionsWithHttpInfo() throws ApiException { + okhttp3.Call localVarCall = nestedCollectionsValidateBeforeCall(null); + Type localVarReturnType = new TypeToken(){}.getType(); + return localVarApiClient.execute(localVarCall, localVarReturnType); + } + + + private okhttp3.Call nestedCollectionsAsync(final ApiCallback _callback) throws ApiException { + + okhttp3.Call localVarCall = nestedCollectionsValidateBeforeCall(_callback); + Type localVarReturnType = new TypeToken(){}.getType(); + localVarApiClient.executeAsync(localVarCall, localVarReturnType, _callback); + return localVarCall; + } + + public class APInestedCollectionsRequest { + + private APInestedCollectionsRequest() { + } + + /** + * Build call for nestedCollections + * @param _callback ApiCallback API callback + * @return Call to execute + * @throws ApiException If fail to serialize the request body object + * @http.response.details + + + +
Status Code Description Response Headers
200 ok -
+ */ + public okhttp3.Call buildCall(final ApiCallback _callback) throws ApiException { + return nestedCollectionsCall(_callback); + } + + /** + * Execute nestedCollections request + * @return NestedCollections + * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body + * @http.response.details + + + +
Status Code Description Response Headers
200 ok -
+ */ + public NestedCollections execute() throws ApiException { + ApiResponse localVarResp = nestedCollectionsWithHttpInfo(); + return localVarResp.getData(); + } + + /** + * Execute nestedCollections request with HTTP info returned + * @return ApiResponse<NestedCollections> + * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body + * @http.response.details + + + +
Status Code Description Response Headers
200 ok -
+ */ + public ApiResponse executeWithHttpInfo() throws ApiException { + return nestedCollectionsWithHttpInfo(); + } + + /** + * Execute nestedCollections request (asynchronously) + * @param _callback The callback to be executed when the API call finishes + * @return The request call + * @throws ApiException If fail to process the API call, e.g. serializing the request body object + * @http.response.details + + + +
Status Code Description Response Headers
200 ok -
+ */ + public okhttp3.Call executeAsync(final ApiCallback _callback) throws ApiException { + return nestedCollectionsAsync(_callback); + } + } + + /** + * + * + * @return APInestedCollectionsRequest + * @http.response.details + + + +
Status Code Description Response Headers
200 ok -
+ */ + + public APInestedCollectionsRequest nestedCollections() { + return new APInestedCollectionsRequest(); + } private okhttp3.Call reservedKeywordsCall(String with, String _if, String propertyClass, final ApiCallback _callback) throws ApiException { String basePath = null; // Operation Servers @@ -34487,6 +34644,7 @@ import test.test.runtime.api.handlers.dictionary.*; import test.test.runtime.api.handlers.inline_enum.*; import test.test.runtime.api.handlers.inline_request_body.*; import test.test.runtime.api.handlers.named_one_of.*; +import test.test.runtime.api.handlers.nested_collections.*; import test.test.runtime.api.handlers.reserved_keywords.*; import test.test.runtime.api.handlers.Handlers; @@ -34511,6 +34669,7 @@ public abstract class HandlerRouter implements RequestHandler> namedOneOfInterceptors = Handlers.getAnnotationInterceptors(this.getClass()); namedOneOfInterceptors.addAll(this.getInterceptors()); return this.constructedNamedOneOf.handleRequestWithAdditionalInterceptors(event, context, namedOneOfInterceptors); + case nestedCollectionsRoute: + List> nestedCollectionsInterceptors = Handlers.getAnnotationInterceptors(this.getClass()); + nestedCollectionsInterceptors.addAll(this.getInterceptors()); + return this.constructedNestedCollections.handleRequestWithAdditionalInterceptors(event, context, nestedCollectionsInterceptors); case reservedKeywordsRoute: List> reservedKeywordsInterceptors = Handlers.getAnnotationInterceptors(this.getClass()); reservedKeywordsInterceptors.addAll(this.getInterceptors()); @@ -37782,8 +37953,8 @@ import test.test.runtime.api.handlers.Response; */ public interface NamedOneOfResponse extends Response {} ", - "src/main/java/test/test/runtime/api/handlers/reserved_keywords/ReservedKeywords.java": " -package test.test.runtime.api.handlers.reserved_keywords; + "src/main/java/test/test/runtime/api/handlers/nested_collections/NestedCollections.java": " +package test.test.runtime.api.handlers.nested_collections; import test.test.runtime.model.*; import test.test.runtime.JSON; @@ -37807,50 +37978,50 @@ import org.crac.Resource; /** - * Lambda handler wrapper for the reservedKeywords operation + * Lambda handler wrapper for the nestedCollections operation */ -public abstract class ReservedKeywords implements RequestHandler, Resource { +public abstract class NestedCollections implements RequestHandler, Resource { { Core.getGlobalContext().register(this); } /** - * Handle the request for the reservedKeywords operation + * Handle the request for the nestedCollections operation */ - public abstract ReservedKeywordsResponse handle(final ReservedKeywordsRequestInput request); + public abstract NestedCollectionsResponse handle(final NestedCollectionsRequestInput request); /** * Interceptors that the handler class has been decorated with */ - private List> annotationInterceptors = Handlers.getAnnotationInterceptors(ReservedKeywords.class); + private List> annotationInterceptors = Handlers.getAnnotationInterceptors(NestedCollections.class); /** * For more complex interceptors that require instantiation with parameters, you may override this method to * return a list of instantiated interceptors. For simple interceptors with no need for constructor arguments, * prefer the @Interceptors annotation. */ - public List> getInterceptors() { + public List> getInterceptors() { return Collections.emptyList(); } - private List> getHandlerInterceptors() { - List> interceptors = new ArrayList<>(); + private List> getHandlerInterceptors() { + List> interceptors = new ArrayList<>(); interceptors.addAll(annotationInterceptors); interceptors.addAll(this.getInterceptors()); return interceptors; } - private HandlerChain buildChain(List> interceptors) { - return Handlers.buildHandlerChain(interceptors, new HandlerChain() { + private HandlerChain buildChain(List> interceptors) { + return Handlers.buildHandlerChain(interceptors, new HandlerChain() { @Override - public Response next(ChainedRequestInput input) { - return handle(new ReservedKeywordsRequestInput(input.getEvent(), input.getContext(), input.getInterceptorContext(), input.getInput())); + public Response next(ChainedRequestInput input) { + return handle(new NestedCollectionsRequestInput(input.getEvent(), input.getContext(), input.getInterceptorContext(), input.getInput())); } }); } - private ChainedRequestInput buildChainedRequestInput(final APIGatewayProxyRequestEvent event, final Context context, final ReservedKeywordsInput input, final Map interceptorContext) { - return new ChainedRequestInput() { + private ChainedRequestInput buildChainedRequestInput(final APIGatewayProxyRequestEvent event, final Context context, final NestedCollectionsInput input, final Map interceptorContext) { + return new ChainedRequestInput() { @Override public HandlerChain getChain() { // The chain's next method ignores the chain given as input, and is pre-built to follow the remaining @@ -37869,7 +38040,7 @@ public abstract class ReservedKeywords implements RequestHandler()) .withQueryStringParameters(new HashMap<>()) @@ -37930,20 +38101,20 @@ public abstract class ReservedKeywords implements RequestHandler> additionalInterceptors) { + public APIGatewayProxyResponseEvent handleRequestWithAdditionalInterceptors(final APIGatewayProxyRequestEvent event, final Context context, final List> additionalInterceptors) { final Map interceptorContext = new HashMap<>(); - interceptorContext.put("operationId", "reservedKeywords"); + interceptorContext.put("operationId", "nestedCollections"); - List> interceptors = new ArrayList<>(); + List> interceptors = new ArrayList<>(); interceptors.addAll(additionalInterceptors); interceptors.addAll(this.getHandlerInterceptors()); final HandlerChain chain = this.buildChain(interceptors); - ReservedKeywordsInput input; + NestedCollectionsInput input; try { - input = new ReservedKeywordsInput(event); + input = new NestedCollectionsInput(event); } catch (RuntimeException e) { Map headers = new HashMap<>(); headers.putAll(Handlers.extractResponseHeadersFromInterceptors(interceptors)); @@ -37968,8 +38139,8 @@ public abstract class ReservedKeywords implements RequestHandler headers; private final Map> multiValueHeaders; - private ReservedKeywords200Response(final Map headers, final Map> multiValueHeaders) { - - this.body = ""; + private NestedCollections200Response(final NestedCollections body, final Map headers, final Map> multiValueHeaders) { + this.typedBody = body; + this.body = body.toJson(); this.headers = headers; this.multiValueHeaders = multiValueHeaders; } @@ -38011,6 +38182,9 @@ public class ReservedKeywords200Response extends RuntimeException implements Res return this.body; } + public NestedCollections getTypedBody() { + return this.typedBody; + } @Override public Map getHeaders() { @@ -38023,29 +38197,29 @@ public class ReservedKeywords200Response extends RuntimeException implements Res } /** - * Create a ReservedKeywords200Response without a body + * Create a NestedCollections200Response with a body */ - public static ReservedKeywords200Response of() { - return new ReservedKeywords200Response(new HashMap<>(), new HashMap<>()); + public static NestedCollections200Response of(final NestedCollections body) { + return new NestedCollections200Response(body, new HashMap<>(), new HashMap<>()); } /** - * Create a ReservedKeywords200Response without a body and headers + * Create a NestedCollections200Response with a body and headers */ - public static ReservedKeywords200Response of(final Map headers) { - return new ReservedKeywords200Response(headers, new HashMap<>()); + public static NestedCollections200Response of(final NestedCollections body, final Map headers) { + return new NestedCollections200Response(body, headers, new HashMap<>()); } /** - * Create a ReservedKeywords200Response without a body, headers and multi-value headers + * Create a NestedCollections200Response with a body, headers and multi-value headers */ - public static ReservedKeywords200Response of(final Map headers, final Map> multiValueHeaders) { - return new ReservedKeywords200Response(headers, multiValueHeaders); + public static NestedCollections200Response of(final NestedCollections body, final Map headers, final Map> multiValueHeaders) { + return new NestedCollections200Response(body, headers, multiValueHeaders); } } ", - "src/main/java/test/test/runtime/api/handlers/reserved_keywords/ReservedKeywordsInput.java": " -package test.test.runtime.api.handlers.reserved_keywords; + "src/main/java/test/test/runtime/api/handlers/nested_collections/NestedCollectionsInput.java": " +package test.test.runtime.api.handlers.nested_collections; import test.test.runtime.model.*; import test.test.runtime.JSON; @@ -38058,11 +38232,11 @@ import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent; import java.io.IOException; /** - * Input for the reservedKeywords operation + * Input for the nestedCollections operation */ @lombok.Builder @lombok.AllArgsConstructor -public class ReservedKeywordsInput { +public class NestedCollectionsInput { static { // JSON has a static instance of Gson which is instantiated lazily the first time it is initialised. // Create an instance here if required to ensure that the static Gson instance is always available. @@ -38071,20 +38245,20 @@ public class ReservedKeywordsInput { } } - private final ReservedKeywordsRequestParameters requestParameters; + private final NestedCollectionsRequestParameters requestParameters; - public ReservedKeywordsInput(final APIGatewayProxyRequestEvent event) { - this.requestParameters = new ReservedKeywordsRequestParameters(event); + public NestedCollectionsInput(final APIGatewayProxyRequestEvent event) { + this.requestParameters = new NestedCollectionsRequestParameters(event); } - public ReservedKeywordsRequestParameters getRequestParameters() { + public NestedCollectionsRequestParameters getRequestParameters() { return this.requestParameters; } } ", - "src/main/java/test/test/runtime/api/handlers/reserved_keywords/ReservedKeywordsRequestInput.java": " -package test.test.runtime.api.handlers.reserved_keywords; + "src/main/java/test/test/runtime/api/handlers/nested_collections/NestedCollectionsRequestInput.java": " +package test.test.runtime.api.handlers.nested_collections; import test.test.runtime.model.*; import test.test.runtime.api.handlers.RequestInput; @@ -38097,20 +38271,20 @@ import java.io.IOException; import com.amazonaws.services.lambda.runtime.Context; /** - * Full request input for the reservedKeywords operation, including the raw API Gateway event + * Full request input for the nestedCollections operation, including the raw API Gateway event */ @lombok.Builder @lombok.AllArgsConstructor -public class ReservedKeywordsRequestInput implements RequestInput { +public class NestedCollectionsRequestInput implements RequestInput { private final APIGatewayProxyRequestEvent event; private final Context context; private final Map interceptorContext; - private final ReservedKeywordsInput input; + private final NestedCollectionsInput input; /** * Returns the typed request input, with path, query and body parameters */ - public ReservedKeywordsInput getInput() { + public NestedCollectionsInput getInput() { return this.input; } @@ -38136,8 +38310,8 @@ public class ReservedKeywordsRequestInput implements RequestInput with; - private final Optional _if; - private final Optional propertyClass; +public class NestedCollectionsRequestParameters { - public ReservedKeywordsRequestParameters(final APIGatewayProxyRequestEvent event) { + public NestedCollectionsRequestParameters(final APIGatewayProxyRequestEvent event) { Map rawStringParameters = new HashMap<>(); Handlers.putAllFromNullableMap(event.getPathParameters(), rawStringParameters); Handlers.putAllFromNullableMap(event.getQueryStringParameters(), rawStringParameters); @@ -38175,439 +38346,848 @@ public class ReservedKeywordsRequestParameters { Handlers.putAllFromNullableMap(event.getMultiValueHeaders(), rawStringArrayParameters); Map> decodedStringArrayParameters = Handlers.decodeRequestArrayParameters(rawStringArrayParameters); - this.with = Optional.ofNullable(Handlers.coerceStringParameter("with", false, decodedStringParameters)); - this._if = Optional.ofNullable(Handlers.coerceStringParameter("if", false, decodedStringParameters)); - this.propertyClass = Optional.ofNullable(Handlers.coerceStringParameter("class", false, decodedStringParameters)); } - public Optional getWith() { - return this.with; - } - public Optional getIf() { - return this._if; - } - public Optional getPropertyClass() { - return this.propertyClass; - } } ", - "src/main/java/test/test/runtime/api/handlers/reserved_keywords/ReservedKeywordsResponse.java": " -package test.test.runtime.api.handlers.reserved_keywords; + "src/main/java/test/test/runtime/api/handlers/nested_collections/NestedCollectionsResponse.java": " +package test.test.runtime.api.handlers.nested_collections; import test.test.runtime.api.handlers.Response; /** - * Response for the reservedKeywords operation + * Response for the nestedCollections operation */ -public interface ReservedKeywordsResponse extends Response {} +public interface NestedCollectionsResponse extends Response {} ", - "src/main/java/test/test/runtime/api/interceptors/DefaultInterceptors.java": "package test.test.runtime.api.interceptors; + "src/main/java/test/test/runtime/api/handlers/reserved_keywords/ReservedKeywords.java": " +package test.test.runtime.api.handlers.reserved_keywords; -import test.test.runtime.api.interceptors.powertools.LoggingInterceptor; -import test.test.runtime.api.interceptors.powertools.MetricsInterceptor; -import test.test.runtime.api.interceptors.powertools.TracingInterceptor; +import test.test.runtime.model.*; +import test.test.runtime.JSON; import test.test.runtime.api.handlers.Interceptor; +import test.test.runtime.api.handlers.Handlers; +import test.test.runtime.api.handlers.*; -import java.util.Arrays; import java.util.List; - -public class DefaultInterceptors { - public static List> all() { - return Arrays.asList( - new ResponseHeadersInterceptor<>(), - new LoggingInterceptor<>(), - new TryCatchInterceptor<>(), - new TracingInterceptor<>(), - new MetricsInterceptor<>() - ); - } -}", - "src/main/java/test/test/runtime/api/interceptors/ResponseHeadersInterceptor.java": "package test.test.runtime.api.interceptors; - -import test.test.runtime.api.handlers.ChainedRequestInput; -import test.test.runtime.api.handlers.Response; -import test.test.runtime.api.handlers.Interceptor; -import test.test.runtime.api.handlers.InterceptorWithWarmup; +import java.util.ArrayList; +import java.util.Optional; import java.util.Map; import java.util.HashMap; +import java.util.Collections; +import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent; +import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent; +import java.io.IOException; +import com.amazonaws.services.lambda.runtime.Context; +import com.amazonaws.services.lambda.runtime.RequestHandler; +import org.crac.Core; +import org.crac.Resource; + /** - * An interceptor for adding cross-origin resource sharing (CORS) headers to the response. - * Allows all origins and headers. + * Lambda handler wrapper for the reservedKeywords operation */ -public class ResponseHeadersInterceptor extends InterceptorWithWarmup { - private final Map additionalHeaders; - - public ResponseHeadersInterceptor() { - this.additionalHeaders = new HashMap<>(); - this.additionalHeaders.put("Access-Control-Allow-Origin", "*"); - this.additionalHeaders.put("Access-Control-Allow-Headers", "*"); +public abstract class ReservedKeywords implements RequestHandler, Resource { + { + Core.getGlobalContext().register(this); } - public ResponseHeadersInterceptor(final Map headers) { - this.additionalHeaders = headers; + /** + * Handle the request for the reservedKeywords operation + */ + public abstract ReservedKeywordsResponse handle(final ReservedKeywordsRequestInput request); + + /** + * Interceptors that the handler class has been decorated with + */ + private List> annotationInterceptors = Handlers.getAnnotationInterceptors(ReservedKeywords.class); + + /** + * For more complex interceptors that require instantiation with parameters, you may override this method to + * return a list of instantiated interceptors. For simple interceptors with no need for constructor arguments, + * prefer the @Interceptors annotation. + */ + public List> getInterceptors() { + return Collections.emptyList(); } - @Override - public Response handle(ChainedRequestInput input) { - Response res = input.getChain().next(input); - res.getHeaders().putAll(this.additionalHeaders); - return res; + private List> getHandlerInterceptors() { + List> interceptors = new ArrayList<>(); + interceptors.addAll(annotationInterceptors); + interceptors.addAll(this.getInterceptors()); + return interceptors; } - public Map getAdditionalHeaders() { - return this.additionalHeaders; + private HandlerChain buildChain(List> interceptors) { + return Handlers.buildHandlerChain(interceptors, new HandlerChain() { + @Override + public Response next(ChainedRequestInput input) { + return handle(new ReservedKeywordsRequestInput(input.getEvent(), input.getContext(), input.getInterceptorContext(), input.getInput())); + } + }); } -} -", - "src/main/java/test/test/runtime/api/interceptors/TryCatchInterceptor.java": "package test.test.runtime.api.interceptors; -import test.test.runtime.api.handlers.ApiResponse; -import test.test.runtime.api.handlers.ChainedRequestInput; -import test.test.runtime.api.handlers.Response; -import test.test.runtime.api.handlers.Interceptor; -import test.test.runtime.api.handlers.InterceptorWithWarmup; -import org.apache.logging.log4j.Logger; + private ChainedRequestInput buildChainedRequestInput(final APIGatewayProxyRequestEvent event, final Context context, final ReservedKeywordsInput input, final Map interceptorContext) { + return new ChainedRequestInput() { + @Override + public HandlerChain getChain() { + // The chain's next method ignores the chain given as input, and is pre-built to follow the remaining + // chain. + return null; + } -/** - * Interceptor for handling uncaught exceptions and responding with a default error response - */ -public class TryCatchInterceptor extends InterceptorWithWarmup { - private final int statusCode; - private final String errorResponseBody; + @Override + public APIGatewayProxyRequestEvent getEvent() { + return event; + } - public TryCatchInterceptor() { - this(500, "{\\"message\\": \\"Internal Error\\"}"); - } + @Override + public Context getContext() { + return context; + } - public TryCatchInterceptor(final int statusCode, final String errorResponseBody) { - this.statusCode = statusCode; - this.errorResponseBody = errorResponseBody; + @Override + public ReservedKeywordsInput getInput() { + return input; + } + + @Override + public Map getInterceptorContext() { + return interceptorContext; + } + }; } @Override - public Response handle(final ChainedRequestInput input) { - try { - return input.getChain().next(input); - } catch (Throwable e) { - if (e instanceof Response) { - return (Response) e; - } + public void beforeCheckpoint(org.crac.Context context) { + // Prime building the handler chain which can take a few 100ms to JIT. + this.buildChain(this.getHandlerInterceptors()); + this.buildChainedRequestInput(null, null, null, null); - Object logger = input.getInterceptorContext().get("logger"); - if (logger instanceof Logger) { - ((Logger) logger).error("Interceptor caught exception", e); - } else { - System.err.println("Interceptor caught exception"); - e.printStackTrace(); - } + // Initialise instance of Gson and prime serialisation and deserialisation + new JSON(); + JSON.getGson().fromJson(JSON.getGson().toJson(new ApiResponse("", 0, new HashMap<>(), new HashMap<>())), ApiResponse.class); - return ApiResponse.builder() - .statusCode(this.statusCode) - .body(this.errorResponseBody) - .build(); - } - } -} -", - "src/main/java/test/test/runtime/api/interceptors/powertools/LoggingInterceptor.java": "package test.test.runtime.api.interceptors.powertools; + try { + // Prime input validation - this will likely fail for the fake event but ensures the code path is optimised + // ready for a real invocation + new ReservedKeywordsInput(new APIGatewayProxyRequestEvent() + .withBody("{}") + .withPathParameters(new HashMap<>()) + .withQueryStringParameters(new HashMap<>()) + .withMultiValueQueryStringParameters(new HashMap<>()) + .withHeaders(new HashMap<>()) + .withMultiValueHeaders(new HashMap<>()) + ); + } catch (Exception e) { -import test.test.runtime.api.handlers.ChainedRequestInput; -import test.test.runtime.api.handlers.RequestInput; -import test.test.runtime.api.handlers.Response; -import test.test.runtime.api.handlers.Interceptor; -import test.test.runtime.api.handlers.InterceptorWithWarmup; -import com.amazonaws.services.lambda.runtime.Context; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.ThreadContext; -import software.amazon.lambda.powertools.core.internal.LambdaHandlerProcessor; -import software.amazon.lambda.powertools.logging.LoggingUtils; + } -/** - * An interceptor which adds an aws lambda powertools logger to the interceptor context, - * and adds the lambda context. - * See https://docs.powertools.aws.dev/lambda/java/latest/core/logging/ - */ -public class LoggingInterceptor extends InterceptorWithWarmup { - private Logger logger = LogManager.getLogger(LoggingInterceptor.class); + this.warmUp(); + } @Override - public void warmUp() { - super.warmUp(); - logger.info("LoggingInterceptor: init"); + public void afterRestore(org.crac.Context context) { + } /** - * Return the instance of the logger from the interceptor context + * Override this method to perform any warmup activities which will be executed prior to the snap-start snapshot. */ - public static Logger getLogger(final RequestInput request) { - Object logger = request.getInterceptorContext().get("logger"); - if (logger == null) { - throw new RuntimeException("No logger found. Did you configure the LoggingInterceptor?"); - } - return (Logger) logger; - } + public void warmUp() { - private void addContext(final Context context) { - LoggingUtils.appendKey("functionName", context.getFunctionName()); - LoggingUtils.appendKey("functionVersion", context.getFunctionVersion()); - LoggingUtils.appendKey("functionArn", context.getInvokedFunctionArn()); - LoggingUtils.appendKey("functionMemorySize", String.valueOf(context.getMemoryLimitInMB())); - // Same casing as powertools aspect implementation - LoggingUtils.appendKey("function_request_id", String.valueOf(context.getAwsRequestId())); } @Override - public Response handle(final ChainedRequestInput input) { - // Add lambda context fields - this.addContext(input.getContext()); + public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEvent event, final Context context) { + return this.handleRequestWithAdditionalInterceptors(event, context, new ArrayList<>()); + } - // Add service, cold start and tracing - LoggingUtils.appendKey("service", LambdaHandlerProcessor.serviceName()); - LoggingUtils.appendKey("coldStart", LambdaHandlerProcessor.isColdStart() ? "true" : "false"); - LambdaHandlerProcessor.getXrayTraceId().ifPresent((xRayTraceId) -> { - LoggingUtils.appendKey("xray_trace_id", xRayTraceId); - }); + private Map getErrorResponseHeaders(final int statusCode) { + Map headers = new HashMap<>(); + return headers; + } - // Add the operation id - String operationId = (String) input.getInterceptorContext().get("operationId"); - LoggingUtils.appendKey("operationId", operationId); + public APIGatewayProxyResponseEvent handleRequestWithAdditionalInterceptors(final APIGatewayProxyRequestEvent event, final Context context, final List> additionalInterceptors) { + final Map interceptorContext = new HashMap<>(); + interceptorContext.put("operationId", "reservedKeywords"); - // Add the logger to the interceptor context - input.getInterceptorContext().put("logger", logger); + List> interceptors = new ArrayList<>(); + interceptors.addAll(additionalInterceptors); + interceptors.addAll(this.getHandlerInterceptors()); - Response response = input.getChain().next(input); + final HandlerChain chain = this.buildChain(interceptors); - // Mark cold start done - LambdaHandlerProcessor.coldStartDone(); + ReservedKeywordsInput input; - // Clear the logger keys - ThreadContext.clearMap(); + try { + input = new ReservedKeywordsInput(event); + } catch (RuntimeException e) { + Map headers = new HashMap<>(); + headers.putAll(Handlers.extractResponseHeadersFromInterceptors(interceptors)); + headers.putAll(this.getErrorResponseHeaders(400)); + return new APIGatewayProxyResponseEvent() + .withStatusCode(400) + .withHeaders(headers) + .withBody("{\\"message\\": \\"" + e.getMessage() + "\\"}"); + } - return response; + final Response response = chain.next(this.buildChainedRequestInput(event, context, input, interceptorContext)); + + Map responseHeaders = new HashMap<>(); + responseHeaders.putAll(this.getErrorResponseHeaders(response.getStatusCode())); + responseHeaders.putAll(response.getHeaders()); + + return new APIGatewayProxyResponseEvent() + .withStatusCode(response.getStatusCode()) + .withHeaders(responseHeaders) + .withMultiValueHeaders(response.getMultiValueHeaders()) + .withBody(response.getBody()); } } ", - "src/main/java/test/test/runtime/api/interceptors/powertools/MetricsInterceptor.java": "package test.test.runtime.api.interceptors.powertools; + "src/main/java/test/test/runtime/api/handlers/reserved_keywords/ReservedKeywords200Response.java": " +package test.test.runtime.api.handlers.reserved_keywords; -import test.test.runtime.api.handlers.ChainedRequestInput; -import test.test.runtime.api.handlers.RequestInput; -import test.test.runtime.api.handlers.Response; -import test.test.runtime.api.handlers.Interceptor; -import test.test.runtime.api.handlers.InterceptorWithWarmup; -import software.amazon.cloudwatchlogs.emf.logger.MetricsLogger; -import software.amazon.cloudwatchlogs.emf.model.DimensionSet; -import software.amazon.lambda.powertools.core.internal.LambdaHandlerProcessor; -import software.amazon.lambda.powertools.metrics.MetricsUtils; +import test.test.runtime.model.*; +import test.test.runtime.JSON; +import java.util.Map; +import java.util.HashMap; +import java.util.List; /** - * Interceptor which adds an instance of aws lambda powertools metrics to the interceptor context (under the key "metrics"), - * and ensures metrics are flushed prior to finishing the lambda execution - * See: https://docs.powertools.aws.dev/lambda/typescript/latest/core/metrics + * Response with status code 200 for the reservedKeywords operation */ -public class MetricsInterceptor extends InterceptorWithWarmup { - private MetricsLogger metrics = MetricsUtils.metricsLogger(); - - /** - * Return the instance of the metrics logger from the interceptor context - */ - public static MetricsLogger getMetrics(final RequestInput request) { - Object metrics = request.getInterceptorContext().get("metrics"); - if (metrics == null) { - throw new RuntimeException("No metrics logger found. Did you configure the MetricsInterceptor?"); +public class ReservedKeywords200Response extends RuntimeException implements ReservedKeywordsResponse { + static { + // JSON has a static instance of Gson which is instantiated lazily the first time it is initialised. + // Create an instance here if required to ensure that the static Gson instance is always available. + if (JSON.getGson() == null) { + new JSON(); } - return (MetricsLogger) metrics; } - @Override - public Response handle(final ChainedRequestInput input) { - metrics.putDimensions(DimensionSet.of("operationId", (String) input.getInterceptorContext().get("operationId"))); - - input.getInterceptorContext().put("metrics", metrics); - - metrics.putProperty("function_request_id", input.getContext().getAwsRequestId()); - LambdaHandlerProcessor.getXrayTraceId().ifPresent((traceId) -> { - metrics.putProperty("xray_trace_id", traceId); - }); - - try { - Response response = input.getChain().next(input); - - // Mark cold start done - LambdaHandlerProcessor.coldStartDone(); + private final String body; + + private final Map headers; + private final Map> multiValueHeaders; - return response; - } finally { - metrics.flush(); - } + private ReservedKeywords200Response(final Map headers, final Map> multiValueHeaders) { + + this.body = ""; + this.headers = headers; + this.multiValueHeaders = multiValueHeaders; } -} -", - "src/main/java/test/test/runtime/api/interceptors/powertools/TracingInterceptor.java": "package test.test.runtime.api.interceptors.powertools; - -import test.test.runtime.api.handlers.ChainedRequestInput; -import test.test.runtime.api.handlers.Response; -import test.test.runtime.api.handlers.Interceptor; -import test.test.runtime.api.handlers.InterceptorWithWarmup; -import com.amazonaws.xray.AWSXRay; -import com.amazonaws.xray.AWSXRayRecorderBuilder; -import com.amazonaws.xray.entities.Subsegment; -import com.fasterxml.jackson.core.JsonProcessingException; -import org.apache.logging.log4j.Logger; -import software.amazon.lambda.powertools.core.internal.LambdaHandlerProcessor; -import software.amazon.lambda.powertools.tracing.TracingUtils; - -/** - * Interceptor which adds an aws lambda powertools tracer to the interceptor context, - * creating the appropriate segment for the handler execution and annotating with recommended - * details. - * See: https://docs.powertools.aws.dev/lambda/java/latest/core/tracing/ - */ -public class TracingInterceptor extends InterceptorWithWarmup { - static { - AWSXRayRecorderBuilder builder = AWSXRayRecorderBuilder.standard(); - AWSXRay.setGlobalRecorder(builder.build()); + @Override + public int getStatusCode() { + return 200; } - private final boolean captureResponse; - - public TracingInterceptor(final boolean captureResponse) { - this.captureResponse = captureResponse; + @Override + public String getBody() { + return this.body; } - public TracingInterceptor() { - this(false); - } @Override - public void warmUp() { - try { - // Set a dummy trace header to ensure the regular subsegment code path is followed and warmed. - // The segment is not actually recorded by xray. - System.setProperty("com.amazonaws.xray.traceHeader", "Root=1-xxx;Parent=yyy;Sampled=1"); - super.warmUp(); - } finally { - System.clearProperty("com.amazonaws.xray.traceHeader"); - } - } - - private void logError(final String message, final ChainedRequestInput input, final Throwable e) { - Object logger = input.getInterceptorContext().get("logger"); - if (logger instanceof Logger) { - ((Logger) logger).error(message, e); - } else { - System.err.println(message); - e.printStackTrace(); - } + public Map getHeaders() { + return this.headers; } @Override - public Response handle(final ChainedRequestInput input) { - String operationId = (String) input.getInterceptorContext().get("operationId"); - Subsegment segment = AWSXRay.beginSubsegment("## " + operationId); - - segment.setNamespace(operationId); - segment.putAnnotation("ColdStart", LambdaHandlerProcessor.isColdStart()); - segment.putAnnotation("Service", LambdaHandlerProcessor.serviceName()); - - try { - Response response = input.getChain().next(input); + public Map> getMultiValueHeaders() { + return this.multiValueHeaders; + } - try { - if (this.captureResponse) { - segment.putMetadata(operationId + " response", TracingUtils.objectMapper() != null ? TracingUtils.objectMapper().writeValueAsString(response) : response); - } - } catch (JsonProcessingException e) { - this.logError("Failed to add response to trace", input, e); - } + /** + * Create a ReservedKeywords200Response without a body + */ + public static ReservedKeywords200Response of() { + return new ReservedKeywords200Response(new HashMap<>(), new HashMap<>()); + } - // Mark cold start done - LambdaHandlerProcessor.coldStartDone(); + /** + * Create a ReservedKeywords200Response without a body and headers + */ + public static ReservedKeywords200Response of(final Map headers) { + return new ReservedKeywords200Response(headers, new HashMap<>()); + } - return response; - } catch (Throwable e) { - try { - segment.putMetadata(operationId + " error", TracingUtils.objectMapper() != null ? TracingUtils.objectMapper().writeValueAsString(e) : e); - } catch (JsonProcessingException ex) { - this.logError("Failed to add error to trace", input, e); - } - throw e; - } finally { - if (!LambdaHandlerProcessor.isSamLocal()) { - AWSXRay.endSubsegment(); - } - } + /** + * Create a ReservedKeywords200Response without a body, headers and multi-value headers + */ + public static ReservedKeywords200Response of(final Map headers, final Map> multiValueHeaders) { + return new ReservedKeywords200Response(headers, multiValueHeaders); } } ", - "src/main/java/test/test/runtime/api/operation_config/OperationConfig.java": "package test.test.runtime.api.operation_config; + "src/main/java/test/test/runtime/api/handlers/reserved_keywords/ReservedKeywordsInput.java": " +package test.test.runtime.api.handlers.reserved_keywords; import test.test.runtime.model.*; - -import java.util.HashMap; +import test.test.runtime.JSON; +import java.util.List; +import java.util.ArrayList; +import java.util.Optional; import java.util.Map; +import java.util.HashMap; +import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent; +import java.io.IOException; -// Generic type for object "keyed" by operation names -@lombok.Builder @lombok.Getter -public class OperationConfig { - private T arrayOfOneOfs; - private T arrayRequestParameters; - private T dictionary; - private T inlineEnum; - private T inlineRequestBody; - private T namedOneOf; - private T reservedKeywords; +/** + * Input for the reservedKeywords operation + */ +@lombok.Builder +@lombok.AllArgsConstructor +public class ReservedKeywordsInput { + static { + // JSON has a static instance of Gson which is instantiated lazily the first time it is initialised. + // Create an instance here if required to ensure that the static Gson instance is always available. + if (JSON.getGson() == null) { + new JSON(); + } + } - public Map asMap() { - Map map = new HashMap<>(); - map.put("arrayOfOneOfs", this.arrayOfOneOfs); - map.put("arrayRequestParameters", this.arrayRequestParameters); - map.put("dictionary", this.dictionary); - map.put("inlineEnum", this.inlineEnum); - map.put("inlineRequestBody", this.inlineRequestBody); - map.put("namedOneOf", this.namedOneOf); - map.put("reservedKeywords", this.reservedKeywords); - return map; + private final ReservedKeywordsRequestParameters requestParameters; + + public ReservedKeywordsInput(final APIGatewayProxyRequestEvent event) { + this.requestParameters = new ReservedKeywordsRequestParameters(event); + } + + public ReservedKeywordsRequestParameters getRequestParameters() { + return this.requestParameters; } + } ", - "src/main/java/test/test/runtime/api/operation_config/OperationLookup.java": "package test.test.runtime.api.operation_config; + "src/main/java/test/test/runtime/api/handlers/reserved_keywords/ReservedKeywordsRequestInput.java": " +package test.test.runtime.api.handlers.reserved_keywords; import test.test.runtime.model.*; - -import java.util.HashMap; -import java.util.Map; +import test.test.runtime.api.handlers.RequestInput; import java.util.List; -import java.util.Arrays; +import java.util.Optional; +import java.util.Map; +import java.util.HashMap; +import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent; +import java.io.IOException; +import com.amazonaws.services.lambda.runtime.Context; +/** + * Full request input for the reservedKeywords operation, including the raw API Gateway event + */ +@lombok.Builder +@lombok.AllArgsConstructor +public class ReservedKeywordsRequestInput implements RequestInput { + private final APIGatewayProxyRequestEvent event; + private final Context context; + private final Map interceptorContext; + private final ReservedKeywordsInput input; -// Look up path and http method for a given operation name -public class OperationLookup { - @lombok.Builder @lombok.Getter - public static class OperationLookupEntry { - private String method; - private String path; - private List contentTypes; + /** + * Returns the typed request input, with path, query and body parameters + */ + public ReservedKeywordsInput getInput() { + return this.input; } /** - * Returns the operation lookup information for the TypeSafeRestApi construct + * Returns the raw API Gateway event */ - public static Map getOperationLookup() { - final Map config = new HashMap<>(); + public APIGatewayProxyRequestEvent getEvent() { + return this.event; + } - config.put("arrayOfOneOfs", OperationLookupEntry.builder() - .path("/array-of-one-ofs") - .method("POST") - .contentTypes(Arrays.asList("application/json")) - .build()); - config.put("arrayRequestParameters", OperationLookupEntry.builder() - .path("/array-request-parameters") - .method("GET") - .contentTypes(Arrays.asList("application/json")) - .build()); + /** + * Returns the lambda context + */ + public Context getContext() { + return this.context; + } + + /** + * Returns the interceptor context, which may contain values set by request interceptors + */ + public Map getInterceptorContext() { + return this.interceptorContext; + } +} +", + "src/main/java/test/test/runtime/api/handlers/reserved_keywords/ReservedKeywordsRequestParameters.java": " +package test.test.runtime.api.handlers.reserved_keywords; + +import test.test.runtime.api.handlers.Handlers; +import java.util.Optional; +import java.util.Map; +import java.util.List; +import java.util.ArrayList; +import java.util.HashMap; +import java.time.OffsetDateTime; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.stream.Collectors; +import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent; + +import test.test.runtime.model.*; + +/** + * Query, path and header parameters for the ReservedKeywords operation + */ +@lombok.Builder +@lombok.AllArgsConstructor +public class ReservedKeywordsRequestParameters { + private final Optional with; + private final Optional _if; + private final Optional propertyClass; + + public ReservedKeywordsRequestParameters(final APIGatewayProxyRequestEvent event) { + Map rawStringParameters = new HashMap<>(); + Handlers.putAllFromNullableMap(event.getPathParameters(), rawStringParameters); + Handlers.putAllFromNullableMap(event.getQueryStringParameters(), rawStringParameters); + Handlers.putAllFromNullableMap(event.getHeaders(), rawStringParameters); + Map decodedStringParameters = Handlers.decodeRequestParameters(rawStringParameters); + + Map> rawStringArrayParameters = new HashMap<>(); + Handlers.putAllFromNullableMap(event.getMultiValueQueryStringParameters(), rawStringArrayParameters); + Handlers.putAllFromNullableMap(event.getMultiValueHeaders(), rawStringArrayParameters); + Map> decodedStringArrayParameters = Handlers.decodeRequestArrayParameters(rawStringArrayParameters); + + this.with = Optional.ofNullable(Handlers.coerceStringParameter("with", false, decodedStringParameters)); + this._if = Optional.ofNullable(Handlers.coerceStringParameter("if", false, decodedStringParameters)); + this.propertyClass = Optional.ofNullable(Handlers.coerceStringParameter("class", false, decodedStringParameters)); + } + + public Optional getWith() { + return this.with; + } + public Optional getIf() { + return this._if; + } + public Optional getPropertyClass() { + return this.propertyClass; + } +} +", + "src/main/java/test/test/runtime/api/handlers/reserved_keywords/ReservedKeywordsResponse.java": " +package test.test.runtime.api.handlers.reserved_keywords; + +import test.test.runtime.api.handlers.Response; + +/** + * Response for the reservedKeywords operation + */ +public interface ReservedKeywordsResponse extends Response {} +", + "src/main/java/test/test/runtime/api/interceptors/DefaultInterceptors.java": "package test.test.runtime.api.interceptors; + +import test.test.runtime.api.interceptors.powertools.LoggingInterceptor; +import test.test.runtime.api.interceptors.powertools.MetricsInterceptor; +import test.test.runtime.api.interceptors.powertools.TracingInterceptor; +import test.test.runtime.api.handlers.Interceptor; + +import java.util.Arrays; +import java.util.List; + +public class DefaultInterceptors { + public static List> all() { + return Arrays.asList( + new ResponseHeadersInterceptor<>(), + new LoggingInterceptor<>(), + new TryCatchInterceptor<>(), + new TracingInterceptor<>(), + new MetricsInterceptor<>() + ); + } +}", + "src/main/java/test/test/runtime/api/interceptors/ResponseHeadersInterceptor.java": "package test.test.runtime.api.interceptors; + +import test.test.runtime.api.handlers.ChainedRequestInput; +import test.test.runtime.api.handlers.Response; +import test.test.runtime.api.handlers.Interceptor; +import test.test.runtime.api.handlers.InterceptorWithWarmup; +import java.util.Map; +import java.util.HashMap; + +/** + * An interceptor for adding cross-origin resource sharing (CORS) headers to the response. + * Allows all origins and headers. + */ +public class ResponseHeadersInterceptor extends InterceptorWithWarmup { + private final Map additionalHeaders; + + public ResponseHeadersInterceptor() { + this.additionalHeaders = new HashMap<>(); + this.additionalHeaders.put("Access-Control-Allow-Origin", "*"); + this.additionalHeaders.put("Access-Control-Allow-Headers", "*"); + } + + public ResponseHeadersInterceptor(final Map headers) { + this.additionalHeaders = headers; + } + + @Override + public Response handle(ChainedRequestInput input) { + Response res = input.getChain().next(input); + res.getHeaders().putAll(this.additionalHeaders); + return res; + } + + public Map getAdditionalHeaders() { + return this.additionalHeaders; + } +} +", + "src/main/java/test/test/runtime/api/interceptors/TryCatchInterceptor.java": "package test.test.runtime.api.interceptors; + +import test.test.runtime.api.handlers.ApiResponse; +import test.test.runtime.api.handlers.ChainedRequestInput; +import test.test.runtime.api.handlers.Response; +import test.test.runtime.api.handlers.Interceptor; +import test.test.runtime.api.handlers.InterceptorWithWarmup; +import org.apache.logging.log4j.Logger; + +/** + * Interceptor for handling uncaught exceptions and responding with a default error response + */ +public class TryCatchInterceptor extends InterceptorWithWarmup { + private final int statusCode; + private final String errorResponseBody; + + public TryCatchInterceptor() { + this(500, "{\\"message\\": \\"Internal Error\\"}"); + } + + public TryCatchInterceptor(final int statusCode, final String errorResponseBody) { + this.statusCode = statusCode; + this.errorResponseBody = errorResponseBody; + } + + @Override + public Response handle(final ChainedRequestInput input) { + try { + return input.getChain().next(input); + } catch (Throwable e) { + if (e instanceof Response) { + return (Response) e; + } + + Object logger = input.getInterceptorContext().get("logger"); + if (logger instanceof Logger) { + ((Logger) logger).error("Interceptor caught exception", e); + } else { + System.err.println("Interceptor caught exception"); + e.printStackTrace(); + } + + return ApiResponse.builder() + .statusCode(this.statusCode) + .body(this.errorResponseBody) + .build(); + } + } +} +", + "src/main/java/test/test/runtime/api/interceptors/powertools/LoggingInterceptor.java": "package test.test.runtime.api.interceptors.powertools; + +import test.test.runtime.api.handlers.ChainedRequestInput; +import test.test.runtime.api.handlers.RequestInput; +import test.test.runtime.api.handlers.Response; +import test.test.runtime.api.handlers.Interceptor; +import test.test.runtime.api.handlers.InterceptorWithWarmup; +import com.amazonaws.services.lambda.runtime.Context; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.ThreadContext; +import software.amazon.lambda.powertools.core.internal.LambdaHandlerProcessor; +import software.amazon.lambda.powertools.logging.LoggingUtils; + +/** + * An interceptor which adds an aws lambda powertools logger to the interceptor context, + * and adds the lambda context. + * See https://docs.powertools.aws.dev/lambda/java/latest/core/logging/ + */ +public class LoggingInterceptor extends InterceptorWithWarmup { + private Logger logger = LogManager.getLogger(LoggingInterceptor.class); + + @Override + public void warmUp() { + super.warmUp(); + logger.info("LoggingInterceptor: init"); + } + + /** + * Return the instance of the logger from the interceptor context + */ + public static Logger getLogger(final RequestInput request) { + Object logger = request.getInterceptorContext().get("logger"); + if (logger == null) { + throw new RuntimeException("No logger found. Did you configure the LoggingInterceptor?"); + } + return (Logger) logger; + } + + private void addContext(final Context context) { + LoggingUtils.appendKey("functionName", context.getFunctionName()); + LoggingUtils.appendKey("functionVersion", context.getFunctionVersion()); + LoggingUtils.appendKey("functionArn", context.getInvokedFunctionArn()); + LoggingUtils.appendKey("functionMemorySize", String.valueOf(context.getMemoryLimitInMB())); + // Same casing as powertools aspect implementation + LoggingUtils.appendKey("function_request_id", String.valueOf(context.getAwsRequestId())); + } + + @Override + public Response handle(final ChainedRequestInput input) { + // Add lambda context fields + this.addContext(input.getContext()); + + // Add service, cold start and tracing + LoggingUtils.appendKey("service", LambdaHandlerProcessor.serviceName()); + LoggingUtils.appendKey("coldStart", LambdaHandlerProcessor.isColdStart() ? "true" : "false"); + LambdaHandlerProcessor.getXrayTraceId().ifPresent((xRayTraceId) -> { + LoggingUtils.appendKey("xray_trace_id", xRayTraceId); + }); + + // Add the operation id + String operationId = (String) input.getInterceptorContext().get("operationId"); + LoggingUtils.appendKey("operationId", operationId); + + // Add the logger to the interceptor context + input.getInterceptorContext().put("logger", logger); + + Response response = input.getChain().next(input); + + // Mark cold start done + LambdaHandlerProcessor.coldStartDone(); + + // Clear the logger keys + ThreadContext.clearMap(); + + return response; + } +} +", + "src/main/java/test/test/runtime/api/interceptors/powertools/MetricsInterceptor.java": "package test.test.runtime.api.interceptors.powertools; + +import test.test.runtime.api.handlers.ChainedRequestInput; +import test.test.runtime.api.handlers.RequestInput; +import test.test.runtime.api.handlers.Response; +import test.test.runtime.api.handlers.Interceptor; +import test.test.runtime.api.handlers.InterceptorWithWarmup; +import software.amazon.cloudwatchlogs.emf.logger.MetricsLogger; +import software.amazon.cloudwatchlogs.emf.model.DimensionSet; +import software.amazon.lambda.powertools.core.internal.LambdaHandlerProcessor; +import software.amazon.lambda.powertools.metrics.MetricsUtils; + +/** + * Interceptor which adds an instance of aws lambda powertools metrics to the interceptor context (under the key "metrics"), + * and ensures metrics are flushed prior to finishing the lambda execution + * See: https://docs.powertools.aws.dev/lambda/typescript/latest/core/metrics + */ +public class MetricsInterceptor extends InterceptorWithWarmup { + private MetricsLogger metrics = MetricsUtils.metricsLogger(); + + /** + * Return the instance of the metrics logger from the interceptor context + */ + public static MetricsLogger getMetrics(final RequestInput request) { + Object metrics = request.getInterceptorContext().get("metrics"); + if (metrics == null) { + throw new RuntimeException("No metrics logger found. Did you configure the MetricsInterceptor?"); + } + return (MetricsLogger) metrics; + } + + @Override + public Response handle(final ChainedRequestInput input) { + metrics.putDimensions(DimensionSet.of("operationId", (String) input.getInterceptorContext().get("operationId"))); + + input.getInterceptorContext().put("metrics", metrics); + + metrics.putProperty("function_request_id", input.getContext().getAwsRequestId()); + LambdaHandlerProcessor.getXrayTraceId().ifPresent((traceId) -> { + metrics.putProperty("xray_trace_id", traceId); + }); + + try { + Response response = input.getChain().next(input); + + // Mark cold start done + LambdaHandlerProcessor.coldStartDone(); + + return response; + } finally { + metrics.flush(); + } + } +} +", + "src/main/java/test/test/runtime/api/interceptors/powertools/TracingInterceptor.java": "package test.test.runtime.api.interceptors.powertools; + +import test.test.runtime.api.handlers.ChainedRequestInput; +import test.test.runtime.api.handlers.Response; +import test.test.runtime.api.handlers.Interceptor; +import test.test.runtime.api.handlers.InterceptorWithWarmup; +import com.amazonaws.xray.AWSXRay; +import com.amazonaws.xray.AWSXRayRecorderBuilder; +import com.amazonaws.xray.entities.Subsegment; +import com.fasterxml.jackson.core.JsonProcessingException; +import org.apache.logging.log4j.Logger; +import software.amazon.lambda.powertools.core.internal.LambdaHandlerProcessor; +import software.amazon.lambda.powertools.tracing.TracingUtils; + +/** + * Interceptor which adds an aws lambda powertools tracer to the interceptor context, + * creating the appropriate segment for the handler execution and annotating with recommended + * details. + * See: https://docs.powertools.aws.dev/lambda/java/latest/core/tracing/ + */ +public class TracingInterceptor extends InterceptorWithWarmup { + + static { + AWSXRayRecorderBuilder builder = AWSXRayRecorderBuilder.standard(); + AWSXRay.setGlobalRecorder(builder.build()); + } + + private final boolean captureResponse; + + public TracingInterceptor(final boolean captureResponse) { + this.captureResponse = captureResponse; + } + + public TracingInterceptor() { + this(false); + } + + @Override + public void warmUp() { + try { + // Set a dummy trace header to ensure the regular subsegment code path is followed and warmed. + // The segment is not actually recorded by xray. + System.setProperty("com.amazonaws.xray.traceHeader", "Root=1-xxx;Parent=yyy;Sampled=1"); + super.warmUp(); + } finally { + System.clearProperty("com.amazonaws.xray.traceHeader"); + } + } + + private void logError(final String message, final ChainedRequestInput input, final Throwable e) { + Object logger = input.getInterceptorContext().get("logger"); + if (logger instanceof Logger) { + ((Logger) logger).error(message, e); + } else { + System.err.println(message); + e.printStackTrace(); + } + } + + @Override + public Response handle(final ChainedRequestInput input) { + String operationId = (String) input.getInterceptorContext().get("operationId"); + Subsegment segment = AWSXRay.beginSubsegment("## " + operationId); + + segment.setNamespace(operationId); + segment.putAnnotation("ColdStart", LambdaHandlerProcessor.isColdStart()); + segment.putAnnotation("Service", LambdaHandlerProcessor.serviceName()); + + try { + Response response = input.getChain().next(input); + + try { + if (this.captureResponse) { + segment.putMetadata(operationId + " response", TracingUtils.objectMapper() != null ? TracingUtils.objectMapper().writeValueAsString(response) : response); + } + } catch (JsonProcessingException e) { + this.logError("Failed to add response to trace", input, e); + } + + // Mark cold start done + LambdaHandlerProcessor.coldStartDone(); + + return response; + } catch (Throwable e) { + try { + segment.putMetadata(operationId + " error", TracingUtils.objectMapper() != null ? TracingUtils.objectMapper().writeValueAsString(e) : e); + } catch (JsonProcessingException ex) { + this.logError("Failed to add error to trace", input, e); + } + throw e; + } finally { + if (!LambdaHandlerProcessor.isSamLocal()) { + AWSXRay.endSubsegment(); + } + } + } +} +", + "src/main/java/test/test/runtime/api/operation_config/OperationConfig.java": "package test.test.runtime.api.operation_config; + +import test.test.runtime.model.*; + +import java.util.HashMap; +import java.util.Map; + +// Generic type for object "keyed" by operation names +@lombok.Builder @lombok.Getter +public class OperationConfig { + private T arrayOfOneOfs; + private T arrayRequestParameters; + private T dictionary; + private T inlineEnum; + private T inlineRequestBody; + private T namedOneOf; + private T nestedCollections; + private T reservedKeywords; + + public Map asMap() { + Map map = new HashMap<>(); + map.put("arrayOfOneOfs", this.arrayOfOneOfs); + map.put("arrayRequestParameters", this.arrayRequestParameters); + map.put("dictionary", this.dictionary); + map.put("inlineEnum", this.inlineEnum); + map.put("inlineRequestBody", this.inlineRequestBody); + map.put("namedOneOf", this.namedOneOf); + map.put("nestedCollections", this.nestedCollections); + map.put("reservedKeywords", this.reservedKeywords); + return map; + } +} +", + "src/main/java/test/test/runtime/api/operation_config/OperationLookup.java": "package test.test.runtime.api.operation_config; + +import test.test.runtime.model.*; + +import java.util.HashMap; +import java.util.Map; +import java.util.List; +import java.util.Arrays; + + +// Look up path and http method for a given operation name +public class OperationLookup { + @lombok.Builder @lombok.Getter + public static class OperationLookupEntry { + private String method; + private String path; + private List contentTypes; + } + + /** + * Returns the operation lookup information for the TypeSafeRestApi construct + */ + public static Map getOperationLookup() { + final Map config = new HashMap<>(); + + config.put("arrayOfOneOfs", OperationLookupEntry.builder() + .path("/array-of-one-ofs") + .method("POST") + .contentTypes(Arrays.asList("application/json")) + .build()); + config.put("arrayRequestParameters", OperationLookupEntry.builder() + .path("/array-request-parameters") + .method("GET") + .contentTypes(Arrays.asList("application/json")) + .build()); config.put("dictionary", OperationLookupEntry.builder() .path("/additional-properties") .method("POST") @@ -38628,38 +39208,427 @@ public class OperationLookup { .method("POST") .contentTypes(Arrays.asList("application/json")) .build()); + config.put("nestedCollections", OperationLookupEntry.builder() + .path("/nested-collections") + .method("POST") + .contentTypes(Arrays.asList("application/json")) + .build()); config.put("reservedKeywords", OperationLookupEntry.builder() .path("/reserved-keywords") .method("GET") .contentTypes(Arrays.asList("application/json")) .build()); - return config; + return config; + } +} +", + "src/main/java/test/test/runtime/api/operation_config/Operations.java": "package test.test.runtime.api.operation_config; + +public class Operations { + /** + * Returns an OperationConfig Builder with all values populated with the given value. + * You can override specific values on the builder if you like. + * Make sure you call \`.build()\` at the end to construct the OperationConfig. + */ + public static OperationConfig.OperationConfigBuilder all(final T value) { + return OperationConfig.builder() + .arrayOfOneOfs(value) + .arrayRequestParameters(value) + .dictionary(value) + .inlineEnum(value) + .inlineRequestBody(value) + .namedOneOf(value) + .nestedCollections(value) + .reservedKeywords(value) + ; + } +} +", + "src/main/java/test/test/runtime/auth/ApiKeyAuth.java": "/* + * Edge Cases + * + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated. + * Do not edit the class manually. + */ + + +package test.test.runtime.auth; + +import test.test.runtime.ApiException; +import test.test.runtime.Pair; + +import java.net.URI; +import java.util.Map; +import java.util.List; + +public class ApiKeyAuth implements Authentication { + private final String location; + private final String paramName; + + private String apiKey; + private String apiKeyPrefix; + + public ApiKeyAuth(String location, String paramName) { + this.location = location; + this.paramName = paramName; + } + + public String getLocation() { + return location; + } + + public String getParamName() { + return paramName; + } + + public String getApiKey() { + return apiKey; + } + + public void setApiKey(String apiKey) { + this.apiKey = apiKey; + } + + public String getApiKeyPrefix() { + return apiKeyPrefix; + } + + public void setApiKeyPrefix(String apiKeyPrefix) { + this.apiKeyPrefix = apiKeyPrefix; + } + + @Override + public void applyToParams(List queryParams, Map headerParams, Map cookieParams, + String payload, String method, URI uri) throws ApiException { + if (apiKey == null) { + return; + } + String value; + if (apiKeyPrefix != null) { + value = apiKeyPrefix + " " + apiKey; + } else { + value = apiKey; + } + if ("query".equals(location)) { + queryParams.add(new Pair(paramName, value)); + } else if ("header".equals(location)) { + headerParams.put(paramName, value); + } else if ("cookie".equals(location)) { + cookieParams.put(paramName, value); + } + } +} +", + "src/main/java/test/test/runtime/auth/Authentication.java": "/* + * Edge Cases + * + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated. + * Do not edit the class manually. + */ + + +package test.test.runtime.auth; + +import test.test.runtime.Pair; +import test.test.runtime.ApiException; + +import java.net.URI; +import java.util.Map; +import java.util.List; + +public interface Authentication { + /** + * Apply authentication settings to header and query params. + * + * @param queryParams List of query parameters + * @param headerParams Map of header parameters + * @param cookieParams Map of cookie parameters + * @param payload HTTP request body + * @param method HTTP method + * @param uri URI + * @throws ApiException if failed to update the parameters + */ + void applyToParams(List queryParams, Map headerParams, Map cookieParams, String payload, String method, URI uri) throws ApiException; +} +", + "src/main/java/test/test/runtime/auth/HttpBasicAuth.java": "/* + * Edge Cases + * + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated. + * Do not edit the class manually. + */ + + +package test.test.runtime.auth; + +import test.test.runtime.Pair; +import test.test.runtime.ApiException; + +import okhttp3.Credentials; + +import java.net.URI; +import java.util.Map; +import java.util.List; + +import java.io.UnsupportedEncodingException; + +public class HttpBasicAuth implements Authentication { + private String username; + private String password; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + @Override + public void applyToParams(List queryParams, Map headerParams, Map cookieParams, + String payload, String method, URI uri) throws ApiException { + if (username == null && password == null) { + return; + } + headerParams.put("Authorization", Credentials.basic( + username == null ? "" : username, + password == null ? "" : password)); + } +} +", + "src/main/java/test/test/runtime/auth/HttpBearerAuth.java": "/* + * Edge Cases + * + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated. + * Do not edit the class manually. + */ + + +package test.test.runtime.auth; + +import test.test.runtime.ApiException; +import test.test.runtime.Pair; + +import java.net.URI; +import java.util.Map; +import java.util.List; + +public class HttpBearerAuth implements Authentication { + private final String scheme; + private String bearerToken; + + public HttpBearerAuth(String scheme) { + this.scheme = scheme; + } + + /** + * Gets the token, which together with the scheme, will be sent as the value of the Authorization header. + * + * @return The bearer token + */ + public String getBearerToken() { + return bearerToken; + } + + /** + * Sets the token, which together with the scheme, will be sent as the value of the Authorization header. + * + * @param bearerToken The bearer token to send in the Authorization header + */ + public void setBearerToken(String bearerToken) { + this.bearerToken = bearerToken; + } + + @Override + public void applyToParams(List queryParams, Map headerParams, Map cookieParams, + String payload, String method, URI uri) throws ApiException { + if (bearerToken == null) { + return; + } + + headerParams.put("Authorization", (scheme != null ? upperCaseBearer(scheme) + " " : "") + bearerToken); + } + + private static String upperCaseBearer(String scheme) { + return ("bearer".equalsIgnoreCase(scheme)) ? "Bearer" : scheme; + } +} +", + "src/main/java/test/test/runtime/model/AbstractOpenApiSchema.java": "/* + * Edge Cases + * + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated. + * Do not edit the class manually. + */ + + +package test.test.runtime.model; + +import test.test.runtime.ApiException; +import java.util.Objects; +import java.lang.reflect.Type; +import java.util.Map; +import javax.ws.rs.core.GenericType; + +//import com.fasterxml.jackson.annotation.JsonValue; + +/** + * Abstract class for oneOf,anyOf schemas defined in OpenAPI spec + */ +@lombok.AllArgsConstructor @lombok.experimental.SuperBuilder +public abstract class AbstractOpenApiSchema { + + // store the actual instance of the schema/object + private Object instance; + + // is nullable + private Boolean isNullable; + + // schema type (e.g. oneOf, anyOf) + private final String schemaType; + + public AbstractOpenApiSchema(String schemaType, Boolean isNullable) { + this.schemaType = schemaType; + this.isNullable = isNullable; + } + + /** + * Get the list of oneOf/anyOf composed schemas allowed to be stored in this object + * + * @return an instance of the actual schema/object + */ + public abstract Map getSchemas(); + + /** + * Get the actual instance + * + * @return an instance of the actual schema/object + */ + //@JsonValue + public Object getActualInstance() {return instance;} + + /** + * Set the actual instance + * + * @param instance the actual instance of the schema/object + */ + public void setActualInstance(Object instance) {this.instance = instance;} + + /** + * Get the instant recursively when the schemas defined in oneOf/anyof happen to be oneOf/anyOf schema as well + * + * @return an instance of the actual schema/object + */ + public Object getActualInstanceRecursively() { + return getActualInstanceRecursively(this); + } + + private Object getActualInstanceRecursively(AbstractOpenApiSchema object) { + if (object.getActualInstance() == null) { + return null; + } else if (object.getActualInstance() instanceof AbstractOpenApiSchema) { + return getActualInstanceRecursively((AbstractOpenApiSchema)object.getActualInstance()); + } else { + return object.getActualInstance(); + } + } + + /** + * Get the schema type (e.g. anyOf, oneOf) + * + * @return the schema type + */ + public String getSchemaType() { + return schemaType; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ").append(getClass()).append(" {\\n"); + sb.append(" instance: ").append(toIndentedString(instance)).append("\\n"); + sb.append(" isNullable: ").append(toIndentedString(isNullable)).append("\\n"); + sb.append(" schemaType: ").append(toIndentedString(schemaType)).append("\\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\\n", "\\n "); + } + + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AbstractOpenApiSchema a = (AbstractOpenApiSchema) o; + return Objects.equals(this.instance, a.instance) && + Objects.equals(this.isNullable, a.isNullable) && + Objects.equals(this.schemaType, a.schemaType); + } + + @Override + public int hashCode() { + return Objects.hash(instance, isNullable, schemaType); } -} -", - "src/main/java/test/test/runtime/api/operation_config/Operations.java": "package test.test.runtime.api.operation_config; -public class Operations { /** - * Returns an OperationConfig Builder with all values populated with the given value. - * You can override specific values on the builder if you like. - * Make sure you call \`.build()\` at the end to construct the OperationConfig. + * Is nullable + * + * @return true if it's nullable */ - public static OperationConfig.OperationConfigBuilder all(final T value) { - return OperationConfig.builder() - .arrayOfOneOfs(value) - .arrayRequestParameters(value) - .dictionary(value) - .inlineEnum(value) - .inlineRequestBody(value) - .namedOneOf(value) - .reservedKeywords(value) - ; + public Boolean isNullable() { + if (Boolean.TRUE.equals(isNullable)) { + return Boolean.TRUE; + } else { + return Boolean.FALSE; + } } + + + } ", - "src/main/java/test/test/runtime/auth/ApiKeyAuth.java": "/* + "src/main/java/test/test/runtime/model/AdditionalPropertiesResponse.java": "/* * Edge Cases * * @@ -38671,74 +39640,257 @@ public class Operations { */ -package test.test.runtime.auth; +package test.test.runtime.model; -import test.test.runtime.ApiException; -import test.test.runtime.Pair; +import java.util.Objects; +import java.util.Arrays; +import test.test.runtime.model.Dictionary; +import com.google.gson.TypeAdapter; +import com.google.gson.annotations.JsonAdapter; +import com.google.gson.annotations.SerializedName; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; +import java.io.IOException; + +import javax.ws.rs.core.GenericType; +import java.io.IOException; +import java.io.File; +import java.math.BigDecimal; import java.net.URI; +import java.time.LocalDate; +import java.time.OffsetDateTime; +import java.util.UUID; +import java.lang.reflect.Type; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.HashMap; import java.util.Map; +import java.util.Map.Entry; import java.util.List; +import java.util.Set; -public class ApiKeyAuth implements Authentication { - private final String location; - private final String paramName; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonArray; +import com.google.gson.JsonParseException; +import com.google.gson.TypeAdapter; +import com.google.gson.TypeAdapterFactory; +import com.google.gson.reflect.TypeToken; +import com.google.gson.JsonPrimitive; +import com.google.gson.annotations.JsonAdapter; +import com.google.gson.annotations.SerializedName; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; - private String apiKey; - private String apiKeyPrefix; +import test.test.runtime.JSON; - public ApiKeyAuth(String location, String paramName) { - this.location = location; - this.paramName = paramName; +/** + * AdditionalPropertiesResponse + */ +@lombok.AllArgsConstructor @lombok.experimental.SuperBuilder +public class AdditionalPropertiesResponse { + public static final String SERIALIZED_NAME_DICTIONARY_OF_OBJECTS = "dictionaryOfObjects"; + @SerializedName(SERIALIZED_NAME_DICTIONARY_OF_OBJECTS) + private Dictionary dictionaryOfObjects; + + public static final String SERIALIZED_NAME_DICTIONARY_OF_PRIMITIVES = "dictionaryOfPrimitives"; + @SerializedName(SERIALIZED_NAME_DICTIONARY_OF_PRIMITIVES) + private Map dictionaryOfPrimitives = null; + + public AdditionalPropertiesResponse() { } - public String getLocation() { - return location; + public AdditionalPropertiesResponse dictionaryOfObjects(Dictionary dictionaryOfObjects) { + + this.dictionaryOfObjects = dictionaryOfObjects; + return this; } - public String getParamName() { - return paramName; + /** + * Get dictionaryOfObjects + * @return dictionaryOfObjects + **/ + @javax.annotation.Nullable + public Dictionary getDictionaryOfObjects() { + return dictionaryOfObjects; } - public String getApiKey() { - return apiKey; + + public void setDictionaryOfObjects(Dictionary dictionaryOfObjects) { + this.dictionaryOfObjects = dictionaryOfObjects; } - public void setApiKey(String apiKey) { - this.apiKey = apiKey; + public AdditionalPropertiesResponse dictionaryOfPrimitives(Map dictionaryOfPrimitives) { + + this.dictionaryOfPrimitives = dictionaryOfPrimitives; + return this; + } + + public AdditionalPropertiesResponse putDictionaryOfPrimitivesItem(String key, String dictionaryOfPrimitivesItem) { + if (this.dictionaryOfPrimitives == null) { + this.dictionaryOfPrimitives = new HashMap<>(); + } + this.dictionaryOfPrimitives.put(key, dictionaryOfPrimitivesItem); + return this; + } + + /** + * Get dictionaryOfPrimitives + * @return dictionaryOfPrimitives + **/ + @javax.annotation.Nullable + public Map getDictionaryOfPrimitives() { + return dictionaryOfPrimitives; + } + + + public void setDictionaryOfPrimitives(Map dictionaryOfPrimitives) { + this.dictionaryOfPrimitives = dictionaryOfPrimitives; + } + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AdditionalPropertiesResponse additionalPropertiesResponse = (AdditionalPropertiesResponse) o; + return Objects.equals(this.dictionaryOfObjects, additionalPropertiesResponse.dictionaryOfObjects) && + Objects.equals(this.dictionaryOfPrimitives, additionalPropertiesResponse.dictionaryOfPrimitives); + + } + + @Override + public int hashCode() { + return Objects.hash(dictionaryOfObjects, dictionaryOfPrimitives); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class AdditionalPropertiesResponse {\\n"); + sb.append(" dictionaryOfObjects: ").append(toIndentedString(dictionaryOfObjects)).append("\\n"); + sb.append(" dictionaryOfPrimitives: ").append(toIndentedString(dictionaryOfPrimitives)).append("\\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\\n", "\\n "); + } + + + public static HashSet openapiFields; + public static HashSet openapiRequiredFields; + + static { + // a set of all properties/fields (JSON key names) + openapiFields = new HashSet(); + openapiFields.add("dictionaryOfObjects"); + openapiFields.add("dictionaryOfPrimitives"); + + // a set of required properties/fields (JSON key names) + openapiRequiredFields = new HashSet(); + } + + /** + * Validates the JSON Object and throws an exception if issues found + * + * @param jsonObj JSON Object + * @throws IOException if the JSON Object is invalid with respect to AdditionalPropertiesResponse + */ + public static void validateJsonObject(JsonObject jsonObj) throws IOException { + if (jsonObj == null) { + if (!AdditionalPropertiesResponse.openapiRequiredFields.isEmpty()) { // has required fields but JSON object is null + throw new IllegalArgumentException(String.format("The required field(s) %s in AdditionalPropertiesResponse is not found in the empty JSON string", AdditionalPropertiesResponse.openapiRequiredFields.toString())); + } + } + + Set> entries = jsonObj.entrySet(); + // check to see if the JSON string contains additional fields + for (Entry entry : entries) { + if (!AdditionalPropertiesResponse.openapiFields.contains(entry.getKey())) { + throw new IllegalArgumentException(String.format("The field \`%s\` in the JSON string is not defined in the \`AdditionalPropertiesResponse\` properties. JSON: %s", entry.getKey(), jsonObj.toString())); + } + } + // validate the optional field \`dictionaryOfObjects\` + if (jsonObj.get("dictionaryOfObjects") != null && !jsonObj.get("dictionaryOfObjects").isJsonNull()) { + Dictionary.validateJsonObject(jsonObj.getAsJsonObject("dictionaryOfObjects")); + } } - public String getApiKeyPrefix() { - return apiKeyPrefix; + public static class CustomTypeAdapterFactory implements TypeAdapterFactory { + @SuppressWarnings("unchecked") + @Override + public TypeAdapter create(Gson gson, TypeToken type) { + if (!AdditionalPropertiesResponse.class.isAssignableFrom(type.getRawType())) { + return null; // this class only serializes 'AdditionalPropertiesResponse' and its subtypes + } + final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); + final TypeAdapter thisAdapter + = gson.getDelegateAdapter(this, TypeToken.get(AdditionalPropertiesResponse.class)); + + return (TypeAdapter) new TypeAdapter() { + @Override + public void write(JsonWriter out, AdditionalPropertiesResponse value) throws IOException { + JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); + elementAdapter.write(out, obj); + } + + @Override + public AdditionalPropertiesResponse read(JsonReader in) throws IOException { + JsonObject jsonObj = elementAdapter.read(in).getAsJsonObject(); + validateJsonObject(jsonObj); + return thisAdapter.fromJsonTree(jsonObj); + } + + }.nullSafe(); + } } - public void setApiKeyPrefix(String apiKeyPrefix) { - this.apiKeyPrefix = apiKeyPrefix; + /** + * Create an instance of AdditionalPropertiesResponse given an JSON string + * + * @param jsonString JSON string + * @return An instance of AdditionalPropertiesResponse + * @throws IOException if the JSON string is invalid with respect to AdditionalPropertiesResponse + */ + public static AdditionalPropertiesResponse fromJson(String jsonString) throws IOException { + return JSON.getGson().fromJson(jsonString, AdditionalPropertiesResponse.class); } - @Override - public void applyToParams(List queryParams, Map headerParams, Map cookieParams, - String payload, String method, URI uri) throws ApiException { - if (apiKey == null) { - return; - } - String value; - if (apiKeyPrefix != null) { - value = apiKeyPrefix + " " + apiKey; - } else { - value = apiKey; - } - if ("query".equals(location)) { - queryParams.add(new Pair(paramName, value)); - } else if ("header".equals(location)) { - headerParams.put(paramName, value); - } else if ("cookie".equals(location)) { - cookieParams.put(paramName, value); - } + /** + * Convert an instance of AdditionalPropertiesResponse to an JSON string + * + * @return JSON string + */ + public String toJson() { + return JSON.getGson().toJson(this); } } ", - "src/main/java/test/test/runtime/auth/Authentication.java": "/* + "src/main/java/test/test/runtime/model/AnotherNamedOneOf.java": "/* * Edge Cases * * @@ -38750,150 +39902,220 @@ public class ApiKeyAuth implements Authentication { */ -package test.test.runtime.auth; +package test.test.runtime.model; -import test.test.runtime.Pair; -import test.test.runtime.ApiException; +import java.util.Objects; +import java.util.Arrays; +import com.google.gson.TypeAdapter; +import com.google.gson.annotations.JsonAdapter; +import com.google.gson.annotations.SerializedName; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; +import java.io.IOException; + +import javax.ws.rs.core.GenericType; +import java.io.IOException; +import java.io.File; +import java.math.BigDecimal; import java.net.URI; +import java.time.LocalDate; +import java.time.OffsetDateTime; +import java.util.UUID; +import java.lang.reflect.Type; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.HashMap; import java.util.Map; +import java.util.Map.Entry; import java.util.List; +import java.util.Set; -public interface Authentication { - /** - * Apply authentication settings to header and query params. - * - * @param queryParams List of query parameters - * @param headerParams Map of header parameters - * @param cookieParams Map of cookie parameters - * @param payload HTTP request body - * @param method HTTP method - * @param uri URI - * @throws ApiException if failed to update the parameters - */ - void applyToParams(List queryParams, Map headerParams, Map cookieParams, String payload, String method, URI uri) throws ApiException; -} -", - "src/main/java/test/test/runtime/auth/HttpBasicAuth.java": "/* - * Edge Cases - * - * - * The version of the OpenAPI document: 1.0.0 - * - * - * NOTE: This class is auto generated. - * Do not edit the class manually. +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonArray; +import com.google.gson.JsonParseException; +import com.google.gson.TypeAdapter; +import com.google.gson.TypeAdapterFactory; +import com.google.gson.reflect.TypeToken; +import com.google.gson.JsonPrimitive; +import com.google.gson.annotations.JsonAdapter; +import com.google.gson.annotations.SerializedName; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; + +import test.test.runtime.JSON; + +/** + * AnotherNamedOneOf */ +@lombok.AllArgsConstructor @lombok.experimental.SuperBuilder +public class AnotherNamedOneOf { + public static final String SERIALIZED_NAME_BAR = "bar"; + @SerializedName(SERIALIZED_NAME_BAR) + private String bar; + public AnotherNamedOneOf() { + } -package test.test.runtime.auth; + public AnotherNamedOneOf bar(String bar) { -import test.test.runtime.Pair; -import test.test.runtime.ApiException; + this.bar = bar; + return this; + } -import okhttp3.Credentials; + /** + * Get bar + * @return bar + **/ + @javax.annotation.Nullable + public String getBar() { + return bar; + } -import java.net.URI; -import java.util.Map; -import java.util.List; -import java.io.UnsupportedEncodingException; + public void setBar(String bar) { + this.bar = bar; + } -public class HttpBasicAuth implements Authentication { - private String username; - private String password; - public String getUsername() { - return username; + @Override + public boolean equals(Object o) { + if (this == o) { + return true; } - - public void setUsername(String username) { - this.username = username; + if (o == null || getClass() != o.getClass()) { + return false; } + AnotherNamedOneOf anotherNamedOneOf = (AnotherNamedOneOf) o; + return Objects.equals(this.bar, anotherNamedOneOf.bar); + + } - public String getPassword() { - return password; - } + @Override + public int hashCode() { + return Objects.hash(bar); + } - public void setPassword(String password) { - this.password = password; - } + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class AnotherNamedOneOf {\\n"); + sb.append(" bar: ").append(toIndentedString(bar)).append("\\n"); + sb.append("}"); + return sb.toString(); + } - @Override - public void applyToParams(List queryParams, Map headerParams, Map cookieParams, - String payload, String method, URI uri) throws ApiException { - if (username == null && password == null) { - return; - } - headerParams.put("Authorization", Credentials.basic( - username == null ? "" : username, - password == null ? "" : password)); + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; } -} -", - "src/main/java/test/test/runtime/auth/HttpBearerAuth.java": "/* - * Edge Cases - * - * - * The version of the OpenAPI document: 1.0.0 - * - * - * NOTE: This class is auto generated. - * Do not edit the class manually. - */ + return o.toString().replace("\\n", "\\n "); + } -package test.test.runtime.auth; + public static HashSet openapiFields; + public static HashSet openapiRequiredFields; -import test.test.runtime.ApiException; -import test.test.runtime.Pair; + static { + // a set of all properties/fields (JSON key names) + openapiFields = new HashSet(); + openapiFields.add("bar"); -import java.net.URI; -import java.util.Map; -import java.util.List; + // a set of required properties/fields (JSON key names) + openapiRequiredFields = new HashSet(); + } -public class HttpBearerAuth implements Authentication { - private final String scheme; - private String bearerToken; + /** + * Validates the JSON Object and throws an exception if issues found + * + * @param jsonObj JSON Object + * @throws IOException if the JSON Object is invalid with respect to AnotherNamedOneOf + */ + public static void validateJsonObject(JsonObject jsonObj) throws IOException { + if (jsonObj == null) { + if (!AnotherNamedOneOf.openapiRequiredFields.isEmpty()) { // has required fields but JSON object is null + throw new IllegalArgumentException(String.format("The required field(s) %s in AnotherNamedOneOf is not found in the empty JSON string", AnotherNamedOneOf.openapiRequiredFields.toString())); + } + } - public HttpBearerAuth(String scheme) { - this.scheme = scheme; + Set> entries = jsonObj.entrySet(); + // check to see if the JSON string contains additional fields + for (Entry entry : entries) { + if (!AnotherNamedOneOf.openapiFields.contains(entry.getKey())) { + throw new IllegalArgumentException(String.format("The field \`%s\` in the JSON string is not defined in the \`AnotherNamedOneOf\` properties. JSON: %s", entry.getKey(), jsonObj.toString())); + } + } + if ((jsonObj.get("bar") != null && !jsonObj.get("bar").isJsonNull()) && !jsonObj.get("bar").isJsonPrimitive()) { + throw new IllegalArgumentException(String.format("Expected the field \`bar\` to be a primitive type in the JSON string but got \`%s\`", jsonObj.get("bar").toString())); + } } - /** - * Gets the token, which together with the scheme, will be sent as the value of the Authorization header. - * - * @return The bearer token - */ - public String getBearerToken() { - return bearerToken; - } + public static class CustomTypeAdapterFactory implements TypeAdapterFactory { + @SuppressWarnings("unchecked") + @Override + public TypeAdapter create(Gson gson, TypeToken type) { + if (!AnotherNamedOneOf.class.isAssignableFrom(type.getRawType())) { + return null; // this class only serializes 'AnotherNamedOneOf' and its subtypes + } + final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); + final TypeAdapter thisAdapter + = gson.getDelegateAdapter(this, TypeToken.get(AnotherNamedOneOf.class)); - /** - * Sets the token, which together with the scheme, will be sent as the value of the Authorization header. - * - * @param bearerToken The bearer token to send in the Authorization header - */ - public void setBearerToken(String bearerToken) { - this.bearerToken = bearerToken; - } + return (TypeAdapter) new TypeAdapter() { + @Override + public void write(JsonWriter out, AnotherNamedOneOf value) throws IOException { + JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); + elementAdapter.write(out, obj); + } - @Override - public void applyToParams(List queryParams, Map headerParams, Map cookieParams, - String payload, String method, URI uri) throws ApiException { - if (bearerToken == null) { - return; + @Override + public AnotherNamedOneOf read(JsonReader in) throws IOException { + JsonObject jsonObj = elementAdapter.read(in).getAsJsonObject(); + validateJsonObject(jsonObj); + return thisAdapter.fromJsonTree(jsonObj); + } + + }.nullSafe(); } + } - headerParams.put("Authorization", (scheme != null ? upperCaseBearer(scheme) + " " : "") + bearerToken); + /** + * Create an instance of AnotherNamedOneOf given an JSON string + * + * @param jsonString JSON string + * @return An instance of AnotherNamedOneOf + * @throws IOException if the JSON string is invalid with respect to AnotherNamedOneOf + */ + public static AnotherNamedOneOf fromJson(String jsonString) throws IOException { + return JSON.getGson().fromJson(jsonString, AnotherNamedOneOf.class); } - private static String upperCaseBearer(String scheme) { - return ("bearer".equalsIgnoreCase(scheme)) ? "Bearer" : scheme; + /** + * Convert an instance of AnotherNamedOneOf to an JSON string + * + * @return JSON string + */ + public String toJson() { + return JSON.getGson().toJson(this); } } ", - "src/main/java/test/test/runtime/model/AbstractOpenApiSchema.java": "/* + "src/main/java/test/test/runtime/model/ArrayOfOneOfs.java": "/* * Edge Cases * * @@ -38907,142 +40129,238 @@ public class HttpBearerAuth implements Authentication { package test.test.runtime.model; -import test.test.runtime.ApiException; import java.util.Objects; +import java.util.Arrays; +import test.test.runtime.model.NamedOneOfUnion; +import com.google.gson.TypeAdapter; +import com.google.gson.annotations.JsonAdapter; +import com.google.gson.annotations.SerializedName; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; +import java.io.IOException; + +import javax.ws.rs.core.GenericType; + +import java.io.IOException; +import java.io.File; +import java.math.BigDecimal; +import java.net.URI; +import java.time.LocalDate; +import java.time.OffsetDateTime; +import java.util.UUID; import java.lang.reflect.Type; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.HashMap; import java.util.Map; -import javax.ws.rs.core.GenericType; +import java.util.Map.Entry; +import java.util.List; +import java.util.Set; -//import com.fasterxml.jackson.annotation.JsonValue; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonArray; +import com.google.gson.JsonParseException; +import com.google.gson.TypeAdapter; +import com.google.gson.TypeAdapterFactory; +import com.google.gson.reflect.TypeToken; +import com.google.gson.JsonPrimitive; +import com.google.gson.annotations.JsonAdapter; +import com.google.gson.annotations.SerializedName; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; + +import test.test.runtime.JSON; /** - * Abstract class for oneOf,anyOf schemas defined in OpenAPI spec + * ArrayOfOneOfs */ @lombok.AllArgsConstructor @lombok.experimental.SuperBuilder -public abstract class AbstractOpenApiSchema { +public class ArrayOfOneOfs { + public static final String SERIALIZED_NAME_ONE_OFS = "oneOfs"; + @SerializedName(SERIALIZED_NAME_ONE_OFS) + private List oneOfs = null; - // store the actual instance of the schema/object - private Object instance; + public ArrayOfOneOfs() { + } - // is nullable - private Boolean isNullable; + public ArrayOfOneOfs oneOfs(List oneOfs) { - // schema type (e.g. oneOf, anyOf) - private final String schemaType; + this.oneOfs = oneOfs; + return this; + } - public AbstractOpenApiSchema(String schemaType, Boolean isNullable) { - this.schemaType = schemaType; - this.isNullable = isNullable; + public ArrayOfOneOfs addOneOfsItem(NamedOneOfUnion oneOfsItem) { + if (this.oneOfs == null) { + this.oneOfs = new ArrayList<>(); } + this.oneOfs.add(oneOfsItem); + return this; + } - /** - * Get the list of oneOf/anyOf composed schemas allowed to be stored in this object - * - * @return an instance of the actual schema/object - */ - public abstract Map getSchemas(); + /** + * Get oneOfs + * @return oneOfs + **/ + @javax.annotation.Nullable + public List getOneOfs() { + return oneOfs; + } - /** - * Get the actual instance - * - * @return an instance of the actual schema/object - */ - //@JsonValue - public Object getActualInstance() {return instance;} - /** - * Set the actual instance - * - * @param instance the actual instance of the schema/object - */ - public void setActualInstance(Object instance) {this.instance = instance;} + public void setOneOfs(List oneOfs) { + this.oneOfs = oneOfs; + } - /** - * Get the instant recursively when the schemas defined in oneOf/anyof happen to be oneOf/anyOf schema as well - * - * @return an instance of the actual schema/object - */ - public Object getActualInstanceRecursively() { - return getActualInstanceRecursively(this); - } - private Object getActualInstanceRecursively(AbstractOpenApiSchema object) { - if (object.getActualInstance() == null) { - return null; - } else if (object.getActualInstance() instanceof AbstractOpenApiSchema) { - return getActualInstanceRecursively((AbstractOpenApiSchema)object.getActualInstance()); - } else { - return object.getActualInstance(); - } + @Override + public boolean equals(Object o) { + if (this == o) { + return true; } - - /** - * Get the schema type (e.g. anyOf, oneOf) - * - * @return the schema type - */ - public String getSchemaType() { - return schemaType; + if (o == null || getClass() != o.getClass()) { + return false; } + ArrayOfOneOfs arrayOfOneOfs = (ArrayOfOneOfs) o; + return Objects.equals(this.oneOfs, arrayOfOneOfs.oneOfs); + + } - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class ").append(getClass()).append(" {\\n"); - sb.append(" instance: ").append(toIndentedString(instance)).append("\\n"); - sb.append(" isNullable: ").append(toIndentedString(isNullable)).append("\\n"); - sb.append(" schemaType: ").append(toIndentedString(schemaType)).append("\\n"); - sb.append("}"); - return sb.toString(); + @Override + public int hashCode() { + return Objects.hash(oneOfs); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ArrayOfOneOfs {\\n"); + sb.append(" oneOfs: ").append(toIndentedString(oneOfs)).append("\\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; } + return o.toString().replace("\\n", "\\n "); + } + + + public static HashSet openapiFields; + public static HashSet openapiRequiredFields; + + static { + // a set of all properties/fields (JSON key names) + openapiFields = new HashSet(); + openapiFields.add("oneOfs"); - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; + // a set of required properties/fields (JSON key names) + openapiRequiredFields = new HashSet(); + } + + /** + * Validates the JSON Object and throws an exception if issues found + * + * @param jsonObj JSON Object + * @throws IOException if the JSON Object is invalid with respect to ArrayOfOneOfs + */ + public static void validateJsonObject(JsonObject jsonObj) throws IOException { + if (jsonObj == null) { + if (!ArrayOfOneOfs.openapiRequiredFields.isEmpty()) { // has required fields but JSON object is null + throw new IllegalArgumentException(String.format("The required field(s) %s in ArrayOfOneOfs is not found in the empty JSON string", ArrayOfOneOfs.openapiRequiredFields.toString())); } - return o.toString().replace("\\n", "\\n "); - } + } - public boolean equals(Object o) { - if (this == o) { - return true; + Set> entries = jsonObj.entrySet(); + // check to see if the JSON string contains additional fields + for (Entry entry : entries) { + if (!ArrayOfOneOfs.openapiFields.contains(entry.getKey())) { + throw new IllegalArgumentException(String.format("The field \`%s\` in the JSON string is not defined in the \`ArrayOfOneOfs\` properties. JSON: %s", entry.getKey(), jsonObj.toString())); } - if (o == null || getClass() != o.getClass()) { - return false; + } + if (jsonObj.get("oneOfs") != null && !jsonObj.get("oneOfs").isJsonNull()) { + JsonArray jsonArrayoneOfs = jsonObj.getAsJsonArray("oneOfs"); + if (jsonArrayoneOfs != null) { + // ensure the json data is an array + if (!jsonObj.get("oneOfs").isJsonArray()) { + throw new IllegalArgumentException(String.format("Expected the field \`oneOfs\` to be an array in the JSON string but got \`%s\`", jsonObj.get("oneOfs").toString())); + } + + // validate the optional field \`oneOfs\` (array) + for (int i = 0; i < jsonArrayoneOfs.size(); i++) { + NamedOneOfUnion.validateJsonObject(jsonArrayoneOfs.get(i).getAsJsonObject()); + }; } - AbstractOpenApiSchema a = (AbstractOpenApiSchema) o; - return Objects.equals(this.instance, a.instance) && - Objects.equals(this.isNullable, a.isNullable) && - Objects.equals(this.schemaType, a.schemaType); - } + } + } + public static class CustomTypeAdapterFactory implements TypeAdapterFactory { + @SuppressWarnings("unchecked") @Override - public int hashCode() { - return Objects.hash(instance, isNullable, schemaType); - } + public TypeAdapter create(Gson gson, TypeToken type) { + if (!ArrayOfOneOfs.class.isAssignableFrom(type.getRawType())) { + return null; // this class only serializes 'ArrayOfOneOfs' and its subtypes + } + final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); + final TypeAdapter thisAdapter + = gson.getDelegateAdapter(this, TypeToken.get(ArrayOfOneOfs.class)); - /** - * Is nullable - * - * @return true if it's nullable - */ - public Boolean isNullable() { - if (Boolean.TRUE.equals(isNullable)) { - return Boolean.TRUE; - } else { - return Boolean.FALSE; - } - } + return (TypeAdapter) new TypeAdapter() { + @Override + public void write(JsonWriter out, ArrayOfOneOfs value) throws IOException { + JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); + elementAdapter.write(out, obj); + } + + @Override + public ArrayOfOneOfs read(JsonReader in) throws IOException { + JsonObject jsonObj = elementAdapter.read(in).getAsJsonObject(); + validateJsonObject(jsonObj); + return thisAdapter.fromJsonTree(jsonObj); + } + }.nullSafe(); + } + } + /** + * Create an instance of ArrayOfOneOfs given an JSON string + * + * @param jsonString JSON string + * @return An instance of ArrayOfOneOfs + * @throws IOException if the JSON string is invalid with respect to ArrayOfOneOfs + */ + public static ArrayOfOneOfs fromJson(String jsonString) throws IOException { + return JSON.getGson().fromJson(jsonString, ArrayOfOneOfs.class); + } + /** + * Convert an instance of ArrayOfOneOfs to an JSON string + * + * @return JSON string + */ + public String toJson() { + return JSON.getGson().toJson(this); + } } ", - "src/main/java/test/test/runtime/model/AdditionalPropertiesResponse.java": "/* + "src/main/java/test/test/runtime/model/CycleArrayNode.java": "/* * Edge Cases * * @@ -39058,7 +40376,6 @@ package test.test.runtime.model; import java.util.Objects; import java.util.Arrays; -import test.test.runtime.model.Dictionary; import com.google.gson.TypeAdapter; import com.google.gson.annotations.JsonAdapter; import com.google.gson.annotations.SerializedName; @@ -39110,67 +40427,43 @@ import com.google.gson.JsonParseException; import test.test.runtime.JSON; /** - * AdditionalPropertiesResponse + * CycleArrayNode */ @lombok.AllArgsConstructor @lombok.experimental.SuperBuilder -public class AdditionalPropertiesResponse { - public static final String SERIALIZED_NAME_DICTIONARY_OF_OBJECTS = "dictionaryOfObjects"; - @SerializedName(SERIALIZED_NAME_DICTIONARY_OF_OBJECTS) - private Dictionary dictionaryOfObjects; - - public static final String SERIALIZED_NAME_DICTIONARY_OF_PRIMITIVES = "dictionaryOfPrimitives"; - @SerializedName(SERIALIZED_NAME_DICTIONARY_OF_PRIMITIVES) - private Map dictionaryOfPrimitives = null; - - public AdditionalPropertiesResponse() { - } - - public AdditionalPropertiesResponse dictionaryOfObjects(Dictionary dictionaryOfObjects) { - - this.dictionaryOfObjects = dictionaryOfObjects; - return this; - } - - /** - * Get dictionaryOfObjects - * @return dictionaryOfObjects - **/ - @javax.annotation.Nullable - public Dictionary getDictionaryOfObjects() { - return dictionaryOfObjects; - } - +public class CycleArrayNode { + public static final String SERIALIZED_NAME_NODES = "nodes"; + @SerializedName(SERIALIZED_NAME_NODES) + private List nodes = null; - public void setDictionaryOfObjects(Dictionary dictionaryOfObjects) { - this.dictionaryOfObjects = dictionaryOfObjects; + public CycleArrayNode() { } - public AdditionalPropertiesResponse dictionaryOfPrimitives(Map dictionaryOfPrimitives) { + public CycleArrayNode nodes(List nodes) { - this.dictionaryOfPrimitives = dictionaryOfPrimitives; + this.nodes = nodes; return this; } - public AdditionalPropertiesResponse putDictionaryOfPrimitivesItem(String key, String dictionaryOfPrimitivesItem) { - if (this.dictionaryOfPrimitives == null) { - this.dictionaryOfPrimitives = new HashMap<>(); + public CycleArrayNode addNodesItem(CycleArrayNode nodesItem) { + if (this.nodes == null) { + this.nodes = new ArrayList<>(); } - this.dictionaryOfPrimitives.put(key, dictionaryOfPrimitivesItem); + this.nodes.add(nodesItem); return this; } /** - * Get dictionaryOfPrimitives - * @return dictionaryOfPrimitives + * Get nodes + * @return nodes **/ @javax.annotation.Nullable - public Map getDictionaryOfPrimitives() { - return dictionaryOfPrimitives; + public List getNodes() { + return nodes; } - public void setDictionaryOfPrimitives(Map dictionaryOfPrimitives) { - this.dictionaryOfPrimitives = dictionaryOfPrimitives; + public void setNodes(List nodes) { + this.nodes = nodes; } @@ -39182,23 +40475,21 @@ public class AdditionalPropertiesResponse { if (o == null || getClass() != o.getClass()) { return false; } - AdditionalPropertiesResponse additionalPropertiesResponse = (AdditionalPropertiesResponse) o; - return Objects.equals(this.dictionaryOfObjects, additionalPropertiesResponse.dictionaryOfObjects) && - Objects.equals(this.dictionaryOfPrimitives, additionalPropertiesResponse.dictionaryOfPrimitives); + CycleArrayNode cycleArrayNode = (CycleArrayNode) o; + return Objects.equals(this.nodes, cycleArrayNode.nodes); } @Override public int hashCode() { - return Objects.hash(dictionaryOfObjects, dictionaryOfPrimitives); + return Objects.hash(nodes); } @Override public String toString() { StringBuilder sb = new StringBuilder(); - sb.append("class AdditionalPropertiesResponse {\\n"); - sb.append(" dictionaryOfObjects: ").append(toIndentedString(dictionaryOfObjects)).append("\\n"); - sb.append(" dictionaryOfPrimitives: ").append(toIndentedString(dictionaryOfPrimitives)).append("\\n"); + sb.append("class CycleArrayNode {\\n"); + sb.append(" nodes: ").append(toIndentedString(nodes)).append("\\n"); sb.append("}"); return sb.toString(); } @@ -39221,8 +40512,7 @@ public class AdditionalPropertiesResponse { static { // a set of all properties/fields (JSON key names) openapiFields = new HashSet(); - openapiFields.add("dictionaryOfObjects"); - openapiFields.add("dictionaryOfPrimitives"); + openapiFields.add("nodes"); // a set of required properties/fields (JSON key names) openapiRequiredFields = new HashSet(); @@ -39232,28 +40522,35 @@ public class AdditionalPropertiesResponse { * Validates the JSON Object and throws an exception if issues found * * @param jsonObj JSON Object - * @throws IOException if the JSON Object is invalid with respect to AdditionalPropertiesResponse + * @throws IOException if the JSON Object is invalid with respect to CycleArrayNode */ public static void validateJsonObject(JsonObject jsonObj) throws IOException { if (jsonObj == null) { - if (!AdditionalPropertiesResponse.openapiRequiredFields.isEmpty()) { // has required fields but JSON object is null - throw new IllegalArgumentException(String.format("The required field(s) %s in AdditionalPropertiesResponse is not found in the empty JSON string", AdditionalPropertiesResponse.openapiRequiredFields.toString())); + if (!CycleArrayNode.openapiRequiredFields.isEmpty()) { // has required fields but JSON object is null + throw new IllegalArgumentException(String.format("The required field(s) %s in CycleArrayNode is not found in the empty JSON string", CycleArrayNode.openapiRequiredFields.toString())); } } Set> entries = jsonObj.entrySet(); // check to see if the JSON string contains additional fields for (Entry entry : entries) { - if (!AdditionalPropertiesResponse.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field \`%s\` in the JSON string is not defined in the \`AdditionalPropertiesResponse\` properties. JSON: %s", entry.getKey(), jsonObj.toString())); + if (!CycleArrayNode.openapiFields.contains(entry.getKey())) { + throw new IllegalArgumentException(String.format("The field \`%s\` in the JSON string is not defined in the \`CycleArrayNode\` properties. JSON: %s", entry.getKey(), jsonObj.toString())); } } - // validate the optional field \`dictionaryOfObjects\` - if (jsonObj.get("dictionaryOfObjects") != null && !jsonObj.get("dictionaryOfObjects").isJsonNull()) { - Dictionary.validateJsonObject(jsonObj.getAsJsonObject("dictionaryOfObjects")); - } - if ((jsonObj.get("dictionaryOfPrimitives") != null && !jsonObj.get("dictionaryOfPrimitives").isJsonNull()) && !jsonObj.get("dictionaryOfPrimitives").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field \`dictionaryOfPrimitives\` to be a primitive type in the JSON string but got \`%s\`", jsonObj.get("dictionaryOfPrimitives").toString())); + if (jsonObj.get("nodes") != null && !jsonObj.get("nodes").isJsonNull()) { + JsonArray jsonArraynodes = jsonObj.getAsJsonArray("nodes"); + if (jsonArraynodes != null) { + // ensure the json data is an array + if (!jsonObj.get("nodes").isJsonArray()) { + throw new IllegalArgumentException(String.format("Expected the field \`nodes\` to be an array in the JSON string but got \`%s\`", jsonObj.get("nodes").toString())); + } + + // validate the optional field \`nodes\` (array) + for (int i = 0; i < jsonArraynodes.size(); i++) { + CycleArrayNode.validateJsonObject(jsonArraynodes.get(i).getAsJsonObject()); + }; + } } } @@ -39261,22 +40558,22 @@ public class AdditionalPropertiesResponse { @SuppressWarnings("unchecked") @Override public TypeAdapter create(Gson gson, TypeToken type) { - if (!AdditionalPropertiesResponse.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'AdditionalPropertiesResponse' and its subtypes + if (!CycleArrayNode.class.isAssignableFrom(type.getRawType())) { + return null; // this class only serializes 'CycleArrayNode' and its subtypes } final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(AdditionalPropertiesResponse.class)); + final TypeAdapter thisAdapter + = gson.getDelegateAdapter(this, TypeToken.get(CycleArrayNode.class)); - return (TypeAdapter) new TypeAdapter() { + return (TypeAdapter) new TypeAdapter() { @Override - public void write(JsonWriter out, AdditionalPropertiesResponse value) throws IOException { + public void write(JsonWriter out, CycleArrayNode value) throws IOException { JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); elementAdapter.write(out, obj); } @Override - public AdditionalPropertiesResponse read(JsonReader in) throws IOException { + public CycleArrayNode read(JsonReader in) throws IOException { JsonObject jsonObj = elementAdapter.read(in).getAsJsonObject(); validateJsonObject(jsonObj); return thisAdapter.fromJsonTree(jsonObj); @@ -39287,18 +40584,18 @@ public class AdditionalPropertiesResponse { } /** - * Create an instance of AdditionalPropertiesResponse given an JSON string + * Create an instance of CycleArrayNode given an JSON string * * @param jsonString JSON string - * @return An instance of AdditionalPropertiesResponse - * @throws IOException if the JSON string is invalid with respect to AdditionalPropertiesResponse + * @return An instance of CycleArrayNode + * @throws IOException if the JSON string is invalid with respect to CycleArrayNode */ - public static AdditionalPropertiesResponse fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, AdditionalPropertiesResponse.class); + public static CycleArrayNode fromJson(String jsonString) throws IOException { + return JSON.getGson().fromJson(jsonString, CycleArrayNode.class); } /** - * Convert an instance of AdditionalPropertiesResponse to an JSON string + * Convert an instance of CycleArrayNode to an JSON string * * @return JSON string */ @@ -39307,7 +40604,7 @@ public class AdditionalPropertiesResponse { } } ", - "src/main/java/test/test/runtime/model/AnotherNamedOneOf.java": "/* + "src/main/java/test/test/runtime/model/CycleDictionary.java": "/* * Edge Cases * * @@ -39374,35 +40671,11 @@ import com.google.gson.JsonParseException; import test.test.runtime.JSON; /** - * AnotherNamedOneOf + * CycleDictionary */ @lombok.AllArgsConstructor @lombok.experimental.SuperBuilder -public class AnotherNamedOneOf { - public static final String SERIALIZED_NAME_BAR = "bar"; - @SerializedName(SERIALIZED_NAME_BAR) - private String bar; - - public AnotherNamedOneOf() { - } - - public AnotherNamedOneOf bar(String bar) { - - this.bar = bar; - return this; - } - - /** - * Get bar - * @return bar - **/ - @javax.annotation.Nullable - public String getBar() { - return bar; - } - - - public void setBar(String bar) { - this.bar = bar; +public class CycleDictionary { + public CycleDictionary() { } @@ -39414,21 +40687,19 @@ public class AnotherNamedOneOf { if (o == null || getClass() != o.getClass()) { return false; } - AnotherNamedOneOf anotherNamedOneOf = (AnotherNamedOneOf) o; - return Objects.equals(this.bar, anotherNamedOneOf.bar); - + CycleDictionary cycleDictionary = (CycleDictionary) o; + return } @Override public int hashCode() { - return Objects.hash(bar); + return Objects.hash(); } @Override public String toString() { StringBuilder sb = new StringBuilder(); - sb.append("class AnotherNamedOneOf {\\n"); - sb.append(" bar: ").append(toIndentedString(bar)).append("\\n"); + sb.append("class CycleDictionary {\\n"); sb.append("}"); return sb.toString(); } @@ -39451,7 +40722,6 @@ public class AnotherNamedOneOf { static { // a set of all properties/fields (JSON key names) openapiFields = new HashSet(); - openapiFields.add("bar"); // a set of required properties/fields (JSON key names) openapiRequiredFields = new HashSet(); @@ -39461,47 +40731,44 @@ public class AnotherNamedOneOf { * Validates the JSON Object and throws an exception if issues found * * @param jsonObj JSON Object - * @throws IOException if the JSON Object is invalid with respect to AnotherNamedOneOf + * @throws IOException if the JSON Object is invalid with respect to CycleDictionary */ public static void validateJsonObject(JsonObject jsonObj) throws IOException { if (jsonObj == null) { - if (!AnotherNamedOneOf.openapiRequiredFields.isEmpty()) { // has required fields but JSON object is null - throw new IllegalArgumentException(String.format("The required field(s) %s in AnotherNamedOneOf is not found in the empty JSON string", AnotherNamedOneOf.openapiRequiredFields.toString())); + if (!CycleDictionary.openapiRequiredFields.isEmpty()) { // has required fields but JSON object is null + throw new IllegalArgumentException(String.format("The required field(s) %s in CycleDictionary is not found in the empty JSON string", CycleDictionary.openapiRequiredFields.toString())); } } Set> entries = jsonObj.entrySet(); // check to see if the JSON string contains additional fields for (Entry entry : entries) { - if (!AnotherNamedOneOf.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field \`%s\` in the JSON string is not defined in the \`AnotherNamedOneOf\` properties. JSON: %s", entry.getKey(), jsonObj.toString())); + if (!CycleDictionary.openapiFields.contains(entry.getKey())) { + throw new IllegalArgumentException(String.format("The field \`%s\` in the JSON string is not defined in the \`CycleDictionary\` properties. JSON: %s", entry.getKey(), jsonObj.toString())); } } - if ((jsonObj.get("bar") != null && !jsonObj.get("bar").isJsonNull()) && !jsonObj.get("bar").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field \`bar\` to be a primitive type in the JSON string but got \`%s\`", jsonObj.get("bar").toString())); - } } public static class CustomTypeAdapterFactory implements TypeAdapterFactory { @SuppressWarnings("unchecked") @Override public TypeAdapter create(Gson gson, TypeToken type) { - if (!AnotherNamedOneOf.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'AnotherNamedOneOf' and its subtypes + if (!CycleDictionary.class.isAssignableFrom(type.getRawType())) { + return null; // this class only serializes 'CycleDictionary' and its subtypes } final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(AnotherNamedOneOf.class)); + final TypeAdapter thisAdapter + = gson.getDelegateAdapter(this, TypeToken.get(CycleDictionary.class)); - return (TypeAdapter) new TypeAdapter() { + return (TypeAdapter) new TypeAdapter() { @Override - public void write(JsonWriter out, AnotherNamedOneOf value) throws IOException { + public void write(JsonWriter out, CycleDictionary value) throws IOException { JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); elementAdapter.write(out, obj); } @Override - public AnotherNamedOneOf read(JsonReader in) throws IOException { + public CycleDictionary read(JsonReader in) throws IOException { JsonObject jsonObj = elementAdapter.read(in).getAsJsonObject(); validateJsonObject(jsonObj); return thisAdapter.fromJsonTree(jsonObj); @@ -39512,18 +40779,18 @@ public class AnotherNamedOneOf { } /** - * Create an instance of AnotherNamedOneOf given an JSON string + * Create an instance of CycleDictionary given an JSON string * * @param jsonString JSON string - * @return An instance of AnotherNamedOneOf - * @throws IOException if the JSON string is invalid with respect to AnotherNamedOneOf + * @return An instance of CycleDictionary + * @throws IOException if the JSON string is invalid with respect to CycleDictionary */ - public static AnotherNamedOneOf fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, AnotherNamedOneOf.class); + public static CycleDictionary fromJson(String jsonString) throws IOException { + return JSON.getGson().fromJson(jsonString, CycleDictionary.class); } /** - * Convert an instance of AnotherNamedOneOf to an JSON string + * Convert an instance of CycleDictionary to an JSON string * * @return JSON string */ @@ -39532,7 +40799,7 @@ public class AnotherNamedOneOf { } } ", - "src/main/java/test/test/runtime/model/ArrayOfOneOfs.java": "/* + "src/main/java/test/test/runtime/model/CycleDictionaryNode.java": "/* * Edge Cases * * @@ -39548,7 +40815,7 @@ package test.test.runtime.model; import java.util.Objects; import java.util.Arrays; -import test.test.runtime.model.NamedOneOfUnion; +import test.test.runtime.model.CycleDictionary; import com.google.gson.TypeAdapter; import com.google.gson.annotations.JsonAdapter; import com.google.gson.annotations.SerializedName; @@ -39600,43 +40867,35 @@ import com.google.gson.JsonParseException; import test.test.runtime.JSON; /** - * ArrayOfOneOfs - */ -@lombok.AllArgsConstructor @lombok.experimental.SuperBuilder -public class ArrayOfOneOfs { - public static final String SERIALIZED_NAME_ONE_OFS = "oneOfs"; - @SerializedName(SERIALIZED_NAME_ONE_OFS) - private List oneOfs = null; - - public ArrayOfOneOfs() { - } - - public ArrayOfOneOfs oneOfs(List oneOfs) { + * CycleDictionaryNode + */ +@lombok.AllArgsConstructor @lombok.experimental.SuperBuilder +public class CycleDictionaryNode { + public static final String SERIALIZED_NAME_NODES = "nodes"; + @SerializedName(SERIALIZED_NAME_NODES) + private CycleDictionary nodes; - this.oneOfs = oneOfs; - return this; + public CycleDictionaryNode() { } - public ArrayOfOneOfs addOneOfsItem(NamedOneOfUnion oneOfsItem) { - if (this.oneOfs == null) { - this.oneOfs = new ArrayList<>(); - } - this.oneOfs.add(oneOfsItem); + public CycleDictionaryNode nodes(CycleDictionary nodes) { + + this.nodes = nodes; return this; } /** - * Get oneOfs - * @return oneOfs + * Get nodes + * @return nodes **/ @javax.annotation.Nullable - public List getOneOfs() { - return oneOfs; + public CycleDictionary getNodes() { + return nodes; } - public void setOneOfs(List oneOfs) { - this.oneOfs = oneOfs; + public void setNodes(CycleDictionary nodes) { + this.nodes = nodes; } @@ -39648,21 +40907,21 @@ public class ArrayOfOneOfs { if (o == null || getClass() != o.getClass()) { return false; } - ArrayOfOneOfs arrayOfOneOfs = (ArrayOfOneOfs) o; - return Objects.equals(this.oneOfs, arrayOfOneOfs.oneOfs); + CycleDictionaryNode cycleDictionaryNode = (CycleDictionaryNode) o; + return Objects.equals(this.nodes, cycleDictionaryNode.nodes); } @Override public int hashCode() { - return Objects.hash(oneOfs); + return Objects.hash(nodes); } @Override public String toString() { StringBuilder sb = new StringBuilder(); - sb.append("class ArrayOfOneOfs {\\n"); - sb.append(" oneOfs: ").append(toIndentedString(oneOfs)).append("\\n"); + sb.append("class CycleDictionaryNode {\\n"); + sb.append(" nodes: ").append(toIndentedString(nodes)).append("\\n"); sb.append("}"); return sb.toString(); } @@ -39685,7 +40944,7 @@ public class ArrayOfOneOfs { static { // a set of all properties/fields (JSON key names) openapiFields = new HashSet(); - openapiFields.add("oneOfs"); + openapiFields.add("nodes"); // a set of required properties/fields (JSON key names) openapiRequiredFields = new HashSet(); @@ -39695,25 +40954,25 @@ public class ArrayOfOneOfs { * Validates the JSON Object and throws an exception if issues found * * @param jsonObj JSON Object - * @throws IOException if the JSON Object is invalid with respect to ArrayOfOneOfs + * @throws IOException if the JSON Object is invalid with respect to CycleDictionaryNode */ public static void validateJsonObject(JsonObject jsonObj) throws IOException { if (jsonObj == null) { - if (!ArrayOfOneOfs.openapiRequiredFields.isEmpty()) { // has required fields but JSON object is null - throw new IllegalArgumentException(String.format("The required field(s) %s in ArrayOfOneOfs is not found in the empty JSON string", ArrayOfOneOfs.openapiRequiredFields.toString())); + if (!CycleDictionaryNode.openapiRequiredFields.isEmpty()) { // has required fields but JSON object is null + throw new IllegalArgumentException(String.format("The required field(s) %s in CycleDictionaryNode is not found in the empty JSON string", CycleDictionaryNode.openapiRequiredFields.toString())); } } Set> entries = jsonObj.entrySet(); // check to see if the JSON string contains additional fields for (Entry entry : entries) { - if (!ArrayOfOneOfs.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field \`%s\` in the JSON string is not defined in the \`ArrayOfOneOfs\` properties. JSON: %s", entry.getKey(), jsonObj.toString())); + if (!CycleDictionaryNode.openapiFields.contains(entry.getKey())) { + throw new IllegalArgumentException(String.format("The field \`%s\` in the JSON string is not defined in the \`CycleDictionaryNode\` properties. JSON: %s", entry.getKey(), jsonObj.toString())); } } - // ensure the optional json data is an array if present - if (jsonObj.get("oneOfs") != null && !jsonObj.get("oneOfs").isJsonArray()) { - throw new IllegalArgumentException(String.format("Expected the field \`oneOfs\` to be an array in the JSON string but got \`%s\`", jsonObj.get("oneOfs").toString())); + // validate the optional field \`nodes\` + if (jsonObj.get("nodes") != null && !jsonObj.get("nodes").isJsonNull()) { + CycleDictionary.validateJsonObject(jsonObj.getAsJsonObject("nodes")); } } @@ -39721,22 +40980,22 @@ public class ArrayOfOneOfs { @SuppressWarnings("unchecked") @Override public TypeAdapter create(Gson gson, TypeToken type) { - if (!ArrayOfOneOfs.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'ArrayOfOneOfs' and its subtypes + if (!CycleDictionaryNode.class.isAssignableFrom(type.getRawType())) { + return null; // this class only serializes 'CycleDictionaryNode' and its subtypes } final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(ArrayOfOneOfs.class)); + final TypeAdapter thisAdapter + = gson.getDelegateAdapter(this, TypeToken.get(CycleDictionaryNode.class)); - return (TypeAdapter) new TypeAdapter() { + return (TypeAdapter) new TypeAdapter() { @Override - public void write(JsonWriter out, ArrayOfOneOfs value) throws IOException { + public void write(JsonWriter out, CycleDictionaryNode value) throws IOException { JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); elementAdapter.write(out, obj); } @Override - public ArrayOfOneOfs read(JsonReader in) throws IOException { + public CycleDictionaryNode read(JsonReader in) throws IOException { JsonObject jsonObj = elementAdapter.read(in).getAsJsonObject(); validateJsonObject(jsonObj); return thisAdapter.fromJsonTree(jsonObj); @@ -39747,18 +41006,18 @@ public class ArrayOfOneOfs { } /** - * Create an instance of ArrayOfOneOfs given an JSON string + * Create an instance of CycleDictionaryNode given an JSON string * * @param jsonString JSON string - * @return An instance of ArrayOfOneOfs - * @throws IOException if the JSON string is invalid with respect to ArrayOfOneOfs + * @return An instance of CycleDictionaryNode + * @throws IOException if the JSON string is invalid with respect to CycleDictionaryNode */ - public static ArrayOfOneOfs fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, ArrayOfOneOfs.class); + public static CycleDictionaryNode fromJson(String jsonString) throws IOException { + return JSON.getGson().fromJson(jsonString, CycleDictionaryNode.class); } /** - * Convert an instance of ArrayOfOneOfs to an JSON string + * Convert an instance of CycleDictionaryNode to an JSON string * * @return JSON string */ @@ -40629,30 +41888,255 @@ public enum MyEnum { return String.valueOf(value); } - public static MyEnum fromValue(String value) { - for (MyEnum b : MyEnum.values()) { - if (b.value.equals(value)) { - return b; - } + public static MyEnum fromValue(String value) { + for (MyEnum b : MyEnum.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } + + public static class Adapter extends TypeAdapter { + @Override + public void write(final JsonWriter jsonWriter, final MyEnum enumeration) throws IOException { + jsonWriter.value(enumeration.getValue()); + } + + @Override + public MyEnum read(final JsonReader jsonReader) throws IOException { + String value = jsonReader.nextString(); + return MyEnum.fromValue(value); + } + } +} +", + "src/main/java/test/test/runtime/model/NamedOneOf.java": "/* + * Edge Cases + * + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated. + * Do not edit the class manually. + */ + + +package test.test.runtime.model; + +import java.util.Objects; +import java.util.Arrays; +import com.google.gson.TypeAdapter; +import com.google.gson.annotations.JsonAdapter; +import com.google.gson.annotations.SerializedName; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; +import java.io.IOException; + +import javax.ws.rs.core.GenericType; + +import java.io.IOException; +import java.io.File; +import java.math.BigDecimal; +import java.net.URI; +import java.time.LocalDate; +import java.time.OffsetDateTime; +import java.util.UUID; +import java.lang.reflect.Type; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.List; +import java.util.Set; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonArray; +import com.google.gson.JsonParseException; +import com.google.gson.TypeAdapter; +import com.google.gson.TypeAdapterFactory; +import com.google.gson.reflect.TypeToken; +import com.google.gson.JsonPrimitive; +import com.google.gson.annotations.JsonAdapter; +import com.google.gson.annotations.SerializedName; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; + +import test.test.runtime.JSON; + +/** + * NamedOneOf + */ +@lombok.AllArgsConstructor @lombok.experimental.SuperBuilder +public class NamedOneOf { + public static final String SERIALIZED_NAME_FOO = "foo"; + @SerializedName(SERIALIZED_NAME_FOO) + private String foo; + + public NamedOneOf() { + } + + public NamedOneOf foo(String foo) { + + this.foo = foo; + return this; + } + + /** + * Get foo + * @return foo + **/ + @javax.annotation.Nullable + public String getFoo() { + return foo; + } + + + public void setFoo(String foo) { + this.foo = foo; + } + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + NamedOneOf namedOneOf = (NamedOneOf) o; + return Objects.equals(this.foo, namedOneOf.foo); + + } + + @Override + public int hashCode() { + return Objects.hash(foo); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class NamedOneOf {\\n"); + sb.append(" foo: ").append(toIndentedString(foo)).append("\\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\\n", "\\n "); + } + + + public static HashSet openapiFields; + public static HashSet openapiRequiredFields; + + static { + // a set of all properties/fields (JSON key names) + openapiFields = new HashSet(); + openapiFields.add("foo"); + + // a set of required properties/fields (JSON key names) + openapiRequiredFields = new HashSet(); + } + + /** + * Validates the JSON Object and throws an exception if issues found + * + * @param jsonObj JSON Object + * @throws IOException if the JSON Object is invalid with respect to NamedOneOf + */ + public static void validateJsonObject(JsonObject jsonObj) throws IOException { + if (jsonObj == null) { + if (!NamedOneOf.openapiRequiredFields.isEmpty()) { // has required fields but JSON object is null + throw new IllegalArgumentException(String.format("The required field(s) %s in NamedOneOf is not found in the empty JSON string", NamedOneOf.openapiRequiredFields.toString())); + } + } + + Set> entries = jsonObj.entrySet(); + // check to see if the JSON string contains additional fields + for (Entry entry : entries) { + if (!NamedOneOf.openapiFields.contains(entry.getKey())) { + throw new IllegalArgumentException(String.format("The field \`%s\` in the JSON string is not defined in the \`NamedOneOf\` properties. JSON: %s", entry.getKey(), jsonObj.toString())); + } + } + if ((jsonObj.get("foo") != null && !jsonObj.get("foo").isJsonNull()) && !jsonObj.get("foo").isJsonPrimitive()) { + throw new IllegalArgumentException(String.format("Expected the field \`foo\` to be a primitive type in the JSON string but got \`%s\`", jsonObj.get("foo").toString())); + } + } + + public static class CustomTypeAdapterFactory implements TypeAdapterFactory { + @SuppressWarnings("unchecked") + @Override + public TypeAdapter create(Gson gson, TypeToken type) { + if (!NamedOneOf.class.isAssignableFrom(type.getRawType())) { + return null; // this class only serializes 'NamedOneOf' and its subtypes + } + final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); + final TypeAdapter thisAdapter + = gson.getDelegateAdapter(this, TypeToken.get(NamedOneOf.class)); + + return (TypeAdapter) new TypeAdapter() { + @Override + public void write(JsonWriter out, NamedOneOf value) throws IOException { + JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); + elementAdapter.write(out, obj); + } + + @Override + public NamedOneOf read(JsonReader in) throws IOException { + JsonObject jsonObj = elementAdapter.read(in).getAsJsonObject(); + validateJsonObject(jsonObj); + return thisAdapter.fromJsonTree(jsonObj); + } + + }.nullSafe(); } - throw new IllegalArgumentException("Unexpected value '" + value + "'"); } - public static class Adapter extends TypeAdapter { - @Override - public void write(final JsonWriter jsonWriter, final MyEnum enumeration) throws IOException { - jsonWriter.value(enumeration.getValue()); - } + /** + * Create an instance of NamedOneOf given an JSON string + * + * @param jsonString JSON string + * @return An instance of NamedOneOf + * @throws IOException if the JSON string is invalid with respect to NamedOneOf + */ + public static NamedOneOf fromJson(String jsonString) throws IOException { + return JSON.getGson().fromJson(jsonString, NamedOneOf.class); + } - @Override - public MyEnum read(final JsonReader jsonReader) throws IOException { - String value = jsonReader.nextString(); - return MyEnum.fromValue(value); - } + /** + * Convert an instance of NamedOneOf to an JSON string + * + * @return JSON string + */ + public String toJson() { + return JSON.getGson().toJson(this); } } ", - "src/main/java/test/test/runtime/model/NamedOneOf.java": "/* + "src/main/java/test/test/runtime/model/NamedOneOfUnion.java": "/* * Edge Cases * * @@ -40668,6 +42152,8 @@ package test.test.runtime.model; import java.util.Objects; import java.util.Arrays; +import test.test.runtime.model.AnotherNamedOneOf; +import test.test.runtime.model.NamedOneOf; import com.google.gson.TypeAdapter; import com.google.gson.annotations.JsonAdapter; import com.google.gson.annotations.SerializedName; @@ -40718,166 +42204,233 @@ import com.google.gson.JsonParseException; import test.test.runtime.JSON; -/** - * NamedOneOf - */ -@lombok.AllArgsConstructor @lombok.experimental.SuperBuilder -public class NamedOneOf { - public static final String SERIALIZED_NAME_FOO = "foo"; - @SerializedName(SERIALIZED_NAME_FOO) - private String foo; +@lombok.experimental.SuperBuilder +public class NamedOneOfUnion extends AbstractOpenApiSchema { + private static final Logger log = Logger.getLogger(NamedOneOfUnion.class.getName()); - public NamedOneOf() { - } + public static class CustomTypeAdapterFactory implements TypeAdapterFactory { + @SuppressWarnings("unchecked") + @Override + public TypeAdapter create(Gson gson, TypeToken type) { + if (!NamedOneOfUnion.class.isAssignableFrom(type.getRawType())) { + return null; // this class only serializes 'NamedOneOfUnion' and its subtypes + } + final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); + final TypeAdapter adapterNamedOneOf = gson.getDelegateAdapter(this, TypeToken.get(NamedOneOf.class)); + final TypeAdapter adapterAnotherNamedOneOf = gson.getDelegateAdapter(this, TypeToken.get(AnotherNamedOneOf.class)); - public NamedOneOf foo(String foo) { + return (TypeAdapter) new TypeAdapter() { + @Override + public void write(JsonWriter out, NamedOneOfUnion value) throws IOException { + if (value == null || value.getActualInstance() == null) { + elementAdapter.write(out, null); + return; + } - this.foo = foo; - return this; - } + // check if the actual instance is of the type \`NamedOneOf\` + if (value.getActualInstance() instanceof NamedOneOf) { + JsonObject obj = adapterNamedOneOf.toJsonTree((NamedOneOf)value.getActualInstance()).getAsJsonObject(); + elementAdapter.write(out, obj); + return; + } - /** - * Get foo - * @return foo - **/ - @javax.annotation.Nullable - public String getFoo() { - return foo; - } + // check if the actual instance is of the type \`AnotherNamedOneOf\` + if (value.getActualInstance() instanceof AnotherNamedOneOf) { + JsonObject obj = adapterAnotherNamedOneOf.toJsonTree((AnotherNamedOneOf)value.getActualInstance()).getAsJsonObject(); + elementAdapter.write(out, obj); + return; + } + throw new IOException("Failed to serialize as the type doesn't match oneOf schemas: NamedOneOf, AnotherNamedOneOf"); + } - public void setFoo(String foo) { - this.foo = foo; - } + @Override + public NamedOneOfUnion read(JsonReader in) throws IOException { + Object deserialized = null; + JsonObject jsonObject = elementAdapter.read(in).getAsJsonObject(); + int match = 0; + ArrayList errorMessages = new ArrayList<>(); + TypeAdapter actualAdapter = elementAdapter; - @Override - public boolean equals(Object o) { - if (this == o) { - return true; + // deserialize NamedOneOf + try { + // validate the JSON object to see if any exception is thrown + NamedOneOf.validateJsonObject(jsonObject); + actualAdapter = adapterNamedOneOf; + match++; + log.log(Level.FINER, "Input data matches schema 'NamedOneOf'"); + } catch (Exception e) { + // deserialization failed, continue + errorMessages.add(String.format("Deserialization for NamedOneOf failed with \`%s\`.", e.getMessage())); + log.log(Level.FINER, "Input data does not match schema 'NamedOneOf'", e); + } + + // deserialize AnotherNamedOneOf + try { + // validate the JSON object to see if any exception is thrown + AnotherNamedOneOf.validateJsonObject(jsonObject); + actualAdapter = adapterAnotherNamedOneOf; + match++; + log.log(Level.FINER, "Input data matches schema 'AnotherNamedOneOf'"); + } catch (Exception e) { + // deserialization failed, continue + errorMessages.add(String.format("Deserialization for AnotherNamedOneOf failed with \`%s\`.", e.getMessage())); + log.log(Level.FINER, "Input data does not match schema 'AnotherNamedOneOf'", e); + } + + if (match == 1) { + NamedOneOfUnion ret = new NamedOneOfUnion(); + ret.setActualInstance(actualAdapter.fromJsonTree(jsonObject)); + return ret; + } + + throw new IOException(String.format("Failed deserialization for NamedOneOfUnion: %d classes match result, expected 1. Detailed failure message for oneOf schemas: %s. JSON: %s", match, errorMessages, jsonObject.toString())); + } + }.nullSafe(); + } } - if (o == null || getClass() != o.getClass()) { - return false; + + // store a list of schema names defined in oneOf + public static final Map schemas = new HashMap(); + + public NamedOneOfUnion() { + super("oneOf", Boolean.FALSE); } - NamedOneOf namedOneOf = (NamedOneOf) o; - return Objects.equals(this.foo, namedOneOf.foo); - - } - @Override - public int hashCode() { - return Objects.hash(foo); - } + public NamedOneOfUnion(NamedOneOf o) { + super("oneOf", Boolean.FALSE); + setActualInstance(o); + } - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class NamedOneOf {\\n"); - sb.append(" foo: ").append(toIndentedString(foo)).append("\\n"); - sb.append("}"); - return sb.toString(); - } + public NamedOneOfUnion(AnotherNamedOneOf o) { + super("oneOf", Boolean.FALSE); + setActualInstance(o); + } - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; + static { + schemas.put("NamedOneOf", new GenericType() { + }); + schemas.put("AnotherNamedOneOf", new GenericType() { + }); } - return o.toString().replace("\\n", "\\n "); - } + @Override + public Map getSchemas() { + return NamedOneOfUnion.schemas; + } - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; + /** + * Set the instance that matches the oneOf child schema, check + * the instance parameter is valid against the oneOf child schemas: + * NamedOneOf, AnotherNamedOneOf + * + * It could be an instance of the 'oneOf' schemas. + * The oneOf child schemas may themselves be a composed schema (allOf, anyOf, oneOf). + */ + @Override + public void setActualInstance(Object instance) { + if (instance instanceof NamedOneOf) { + super.setActualInstance(instance); + return; + } - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("foo"); + if (instance instanceof AnotherNamedOneOf) { + super.setActualInstance(instance); + return; + } + + throw new RuntimeException("Invalid instance type. Must be NamedOneOf, AnotherNamedOneOf"); + } + + /** + * Get the actual instance, which can be the following: + * NamedOneOf, AnotherNamedOneOf + * + * @return The actual instance (NamedOneOf, AnotherNamedOneOf) + */ + @Override + public Object getActualInstance() { + return super.getActualInstance(); + } + + /** + * Get the actual instance of \`NamedOneOf\`. If the actual instance is not \`NamedOneOf\`, + * the ClassCastException will be thrown. + * + * @return The actual instance of \`NamedOneOf\` + * @throws ClassCastException if the instance is not \`NamedOneOf\` + */ + public NamedOneOf getNamedOneOf() throws ClassCastException { + return (NamedOneOf)super.getActualInstance(); + } + + /** + * Get the actual instance of \`AnotherNamedOneOf\`. If the actual instance is not \`AnotherNamedOneOf\`, + * the ClassCastException will be thrown. + * + * @return The actual instance of \`AnotherNamedOneOf\` + * @throws ClassCastException if the instance is not \`AnotherNamedOneOf\` + */ + public AnotherNamedOneOf getAnotherNamedOneOf() throws ClassCastException { + return (AnotherNamedOneOf)super.getActualInstance(); + } - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - } /** * Validates the JSON Object and throws an exception if issues found * * @param jsonObj JSON Object - * @throws IOException if the JSON Object is invalid with respect to NamedOneOf + * @throws IOException if the JSON Object is invalid with respect to NamedOneOfUnion */ public static void validateJsonObject(JsonObject jsonObj) throws IOException { - if (jsonObj == null) { - if (!NamedOneOf.openapiRequiredFields.isEmpty()) { // has required fields but JSON object is null - throw new IllegalArgumentException(String.format("The required field(s) %s in NamedOneOf is not found in the empty JSON string", NamedOneOf.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonObj.entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!NamedOneOf.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field \`%s\` in the JSON string is not defined in the \`NamedOneOf\` properties. JSON: %s", entry.getKey(), jsonObj.toString())); - } - } - if ((jsonObj.get("foo") != null && !jsonObj.get("foo").isJsonNull()) && !jsonObj.get("foo").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field \`foo\` to be a primitive type in the JSON string but got \`%s\`", jsonObj.get("foo").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!NamedOneOf.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'NamedOneOf' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(NamedOneOf.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, NamedOneOf value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public NamedOneOf read(JsonReader in) throws IOException { - JsonObject jsonObj = elementAdapter.read(in).getAsJsonObject(); - validateJsonObject(jsonObj); - return thisAdapter.fromJsonTree(jsonObj); - } - - }.nullSafe(); + // validate oneOf schemas one by one + int validCount = 0; + ArrayList errorMessages = new ArrayList<>(); + // validate the json string with NamedOneOf + try { + NamedOneOf.validateJsonObject(jsonObj); + validCount++; + } catch (Exception e) { + errorMessages.add(String.format("Deserialization for NamedOneOf failed with \`%s\`.", e.getMessage())); + // continue to the next one + } + // validate the json string with AnotherNamedOneOf + try { + AnotherNamedOneOf.validateJsonObject(jsonObj); + validCount++; + } catch (Exception e) { + errorMessages.add(String.format("Deserialization for AnotherNamedOneOf failed with \`%s\`.", e.getMessage())); + // continue to the next one + } + if (validCount != 1) { + throw new IOException(String.format("The JSON string is invalid for NamedOneOfUnion with oneOf schemas: NamedOneOf, AnotherNamedOneOf. %d class(es) match the result, expected 1. Detailed failure message for oneOf schemas: %s. JSON: %s", validCount, errorMessages, jsonObj.toString())); } } /** - * Create an instance of NamedOneOf given an JSON string + * Create an instance of NamedOneOfUnion given an JSON string * * @param jsonString JSON string - * @return An instance of NamedOneOf - * @throws IOException if the JSON string is invalid with respect to NamedOneOf + * @return An instance of NamedOneOfUnion + * @throws IOException if the JSON string is invalid with respect to NamedOneOfUnion */ - public static NamedOneOf fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, NamedOneOf.class); + public static NamedOneOfUnion fromJson(String jsonString) throws IOException { + return JSON.getGson().fromJson(jsonString, NamedOneOfUnion.class); } /** - * Convert an instance of NamedOneOf to an JSON string + * Convert an instance of NamedOneOfUnion to an JSON string * * @return JSON string */ public String toJson() { return JSON.getGson().toJson(this); } + } ", - "src/main/java/test/test/runtime/model/NamedOneOfUnion.java": "/* + "src/main/java/test/test/runtime/model/NestedCollections.java": "/* * Edge Cases * * @@ -40893,8 +42446,9 @@ package test.test.runtime.model; import java.util.Objects; import java.util.Arrays; -import test.test.runtime.model.AnotherNamedOneOf; -import test.test.runtime.model.NamedOneOf; +import test.test.runtime.model.CycleArrayNode; +import test.test.runtime.model.CycleDictionary; +import test.test.runtime.model.SomeObject; import com.google.gson.TypeAdapter; import com.google.gson.annotations.JsonAdapter; import com.google.gson.annotations.SerializedName; @@ -40945,230 +42499,563 @@ import com.google.gson.JsonParseException; import test.test.runtime.JSON; -@lombok.experimental.SuperBuilder -public class NamedOneOfUnion extends AbstractOpenApiSchema { - private static final Logger log = Logger.getLogger(NamedOneOfUnion.class.getName()); +/** + * NestedCollections + */ +@lombok.AllArgsConstructor @lombok.experimental.SuperBuilder +public class NestedCollections { + public static final String SERIALIZED_NAME_NESTED_ARRAY_OF_STRINGS = "nestedArrayOfStrings"; + @SerializedName(SERIALIZED_NAME_NESTED_ARRAY_OF_STRINGS) + private List> nestedArrayOfStrings = null; - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!NamedOneOfUnion.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'NamedOneOfUnion' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter adapterNamedOneOf = gson.getDelegateAdapter(this, TypeToken.get(NamedOneOf.class)); - final TypeAdapter adapterAnotherNamedOneOf = gson.getDelegateAdapter(this, TypeToken.get(AnotherNamedOneOf.class)); + public static final String SERIALIZED_NAME_NESTED_ARRAY_OF_DATES = "nestedArrayOfDates"; + @SerializedName(SERIALIZED_NAME_NESTED_ARRAY_OF_DATES) + private List> nestedArrayOfDates = null; - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, NamedOneOfUnion value) throws IOException { - if (value == null || value.getActualInstance() == null) { - elementAdapter.write(out, null); - return; - } + public static final String SERIALIZED_NAME_NESTED_ARRAY_OF_OBJECTS = "nestedArrayOfObjects"; + @SerializedName(SERIALIZED_NAME_NESTED_ARRAY_OF_OBJECTS) + private List> nestedArrayOfObjects = null; - // check if the actual instance is of the type \`NamedOneOf\` - if (value.getActualInstance() instanceof NamedOneOf) { - JsonObject obj = adapterNamedOneOf.toJsonTree((NamedOneOf)value.getActualInstance()).getAsJsonObject(); - elementAdapter.write(out, obj); - return; - } + public static final String SERIALIZED_NAME_FOUR_DIMENSIONAL_NESTED_ARRAY_OF_OBJECTS = "fourDimensionalNestedArrayOfObjects"; + @SerializedName(SERIALIZED_NAME_FOUR_DIMENSIONAL_NESTED_ARRAY_OF_OBJECTS) + private List>>> fourDimensionalNestedArrayOfObjects = null; + + public static final String SERIALIZED_NAME_NESTED_DICTIONARY_OF_STRINGS = "nestedDictionaryOfStrings"; + @SerializedName(SERIALIZED_NAME_NESTED_DICTIONARY_OF_STRINGS) + private Map> nestedDictionaryOfStrings = null; + + public static final String SERIALIZED_NAME_NESTED_DICTIONARY_OF_OBJECTS = "nestedDictionaryOfObjects"; + @SerializedName(SERIALIZED_NAME_NESTED_DICTIONARY_OF_OBJECTS) + private Map> nestedDictionaryOfObjects = null; + + public static final String SERIALIZED_NAME_FOUR_DIMENSIONAL_NESTED_DICTIONARY_OF_OBJECTS = "fourDimensionalNestedDictionaryOfObjects"; + @SerializedName(SERIALIZED_NAME_FOUR_DIMENSIONAL_NESTED_DICTIONARY_OF_OBJECTS) + private Map>>> fourDimensionalNestedDictionaryOfObjects = null; + + public static final String SERIALIZED_NAME_NESTED_MIX_OF_DICTIONARIES_AND_ARRAYS = "nestedMixOfDictionariesAndArrays"; + @SerializedName(SERIALIZED_NAME_NESTED_MIX_OF_DICTIONARIES_AND_ARRAYS) + private List>>>>> nestedMixOfDictionariesAndArrays = null; + + public static final String SERIALIZED_NAME_CYCLE_ARRAY = "cycleArray"; + @SerializedName(SERIALIZED_NAME_CYCLE_ARRAY) + private List cycleArray = null; + + public static final String SERIALIZED_NAME_CYCLE_DICTIONARY = "cycleDictionary"; + @SerializedName(SERIALIZED_NAME_CYCLE_DICTIONARY) + private CycleDictionary cycleDictionary; + + public NestedCollections() { + } + + public NestedCollections nestedArrayOfStrings(List> nestedArrayOfStrings) { + + this.nestedArrayOfStrings = nestedArrayOfStrings; + return this; + } + + public NestedCollections addNestedArrayOfStringsItem(List nestedArrayOfStringsItem) { + if (this.nestedArrayOfStrings == null) { + this.nestedArrayOfStrings = new ArrayList<>(); + } + this.nestedArrayOfStrings.add(nestedArrayOfStringsItem); + return this; + } + + /** + * Get nestedArrayOfStrings + * @return nestedArrayOfStrings + **/ + @javax.annotation.Nullable + public List> getNestedArrayOfStrings() { + return nestedArrayOfStrings; + } + + + public void setNestedArrayOfStrings(List> nestedArrayOfStrings) { + this.nestedArrayOfStrings = nestedArrayOfStrings; + } + + public NestedCollections nestedArrayOfDates(List> nestedArrayOfDates) { + + this.nestedArrayOfDates = nestedArrayOfDates; + return this; + } + + public NestedCollections addNestedArrayOfDatesItem(List nestedArrayOfDatesItem) { + if (this.nestedArrayOfDates == null) { + this.nestedArrayOfDates = new ArrayList<>(); + } + this.nestedArrayOfDates.add(nestedArrayOfDatesItem); + return this; + } + + /** + * Get nestedArrayOfDates + * @return nestedArrayOfDates + **/ + @javax.annotation.Nullable + public List> getNestedArrayOfDates() { + return nestedArrayOfDates; + } + + + public void setNestedArrayOfDates(List> nestedArrayOfDates) { + this.nestedArrayOfDates = nestedArrayOfDates; + } + + public NestedCollections nestedArrayOfObjects(List> nestedArrayOfObjects) { + + this.nestedArrayOfObjects = nestedArrayOfObjects; + return this; + } + + public NestedCollections addNestedArrayOfObjectsItem(List nestedArrayOfObjectsItem) { + if (this.nestedArrayOfObjects == null) { + this.nestedArrayOfObjects = new ArrayList<>(); + } + this.nestedArrayOfObjects.add(nestedArrayOfObjectsItem); + return this; + } + + /** + * Get nestedArrayOfObjects + * @return nestedArrayOfObjects + **/ + @javax.annotation.Nullable + public List> getNestedArrayOfObjects() { + return nestedArrayOfObjects; + } + + + public void setNestedArrayOfObjects(List> nestedArrayOfObjects) { + this.nestedArrayOfObjects = nestedArrayOfObjects; + } + + public NestedCollections fourDimensionalNestedArrayOfObjects(List>>> fourDimensionalNestedArrayOfObjects) { + + this.fourDimensionalNestedArrayOfObjects = fourDimensionalNestedArrayOfObjects; + return this; + } + + public NestedCollections addFourDimensionalNestedArrayOfObjectsItem(List>> fourDimensionalNestedArrayOfObjectsItem) { + if (this.fourDimensionalNestedArrayOfObjects == null) { + this.fourDimensionalNestedArrayOfObjects = new ArrayList<>(); + } + this.fourDimensionalNestedArrayOfObjects.add(fourDimensionalNestedArrayOfObjectsItem); + return this; + } + + /** + * Get fourDimensionalNestedArrayOfObjects + * @return fourDimensionalNestedArrayOfObjects + **/ + @javax.annotation.Nullable + public List>>> getFourDimensionalNestedArrayOfObjects() { + return fourDimensionalNestedArrayOfObjects; + } + + + public void setFourDimensionalNestedArrayOfObjects(List>>> fourDimensionalNestedArrayOfObjects) { + this.fourDimensionalNestedArrayOfObjects = fourDimensionalNestedArrayOfObjects; + } + + public NestedCollections nestedDictionaryOfStrings(Map> nestedDictionaryOfStrings) { + + this.nestedDictionaryOfStrings = nestedDictionaryOfStrings; + return this; + } + + public NestedCollections putNestedDictionaryOfStringsItem(String key, Map nestedDictionaryOfStringsItem) { + if (this.nestedDictionaryOfStrings == null) { + this.nestedDictionaryOfStrings = new HashMap<>(); + } + this.nestedDictionaryOfStrings.put(key, nestedDictionaryOfStringsItem); + return this; + } + + /** + * Get nestedDictionaryOfStrings + * @return nestedDictionaryOfStrings + **/ + @javax.annotation.Nullable + public Map> getNestedDictionaryOfStrings() { + return nestedDictionaryOfStrings; + } + + + public void setNestedDictionaryOfStrings(Map> nestedDictionaryOfStrings) { + this.nestedDictionaryOfStrings = nestedDictionaryOfStrings; + } + + public NestedCollections nestedDictionaryOfObjects(Map> nestedDictionaryOfObjects) { + + this.nestedDictionaryOfObjects = nestedDictionaryOfObjects; + return this; + } + + public NestedCollections putNestedDictionaryOfObjectsItem(String key, Map nestedDictionaryOfObjectsItem) { + if (this.nestedDictionaryOfObjects == null) { + this.nestedDictionaryOfObjects = new HashMap<>(); + } + this.nestedDictionaryOfObjects.put(key, nestedDictionaryOfObjectsItem); + return this; + } + + /** + * Get nestedDictionaryOfObjects + * @return nestedDictionaryOfObjects + **/ + @javax.annotation.Nullable + public Map> getNestedDictionaryOfObjects() { + return nestedDictionaryOfObjects; + } + + + public void setNestedDictionaryOfObjects(Map> nestedDictionaryOfObjects) { + this.nestedDictionaryOfObjects = nestedDictionaryOfObjects; + } + + public NestedCollections fourDimensionalNestedDictionaryOfObjects(Map>>> fourDimensionalNestedDictionaryOfObjects) { + + this.fourDimensionalNestedDictionaryOfObjects = fourDimensionalNestedDictionaryOfObjects; + return this; + } + + public NestedCollections putFourDimensionalNestedDictionaryOfObjectsItem(String key, Map>> fourDimensionalNestedDictionaryOfObjectsItem) { + if (this.fourDimensionalNestedDictionaryOfObjects == null) { + this.fourDimensionalNestedDictionaryOfObjects = new HashMap<>(); + } + this.fourDimensionalNestedDictionaryOfObjects.put(key, fourDimensionalNestedDictionaryOfObjectsItem); + return this; + } + + /** + * Get fourDimensionalNestedDictionaryOfObjects + * @return fourDimensionalNestedDictionaryOfObjects + **/ + @javax.annotation.Nullable + public Map>>> getFourDimensionalNestedDictionaryOfObjects() { + return fourDimensionalNestedDictionaryOfObjects; + } + + + public void setFourDimensionalNestedDictionaryOfObjects(Map>>> fourDimensionalNestedDictionaryOfObjects) { + this.fourDimensionalNestedDictionaryOfObjects = fourDimensionalNestedDictionaryOfObjects; + } + + public NestedCollections nestedMixOfDictionariesAndArrays(List>>>>> nestedMixOfDictionariesAndArrays) { + + this.nestedMixOfDictionariesAndArrays = nestedMixOfDictionariesAndArrays; + return this; + } + + public NestedCollections addNestedMixOfDictionariesAndArraysItem(Map>>>> nestedMixOfDictionariesAndArraysItem) { + if (this.nestedMixOfDictionariesAndArrays == null) { + this.nestedMixOfDictionariesAndArrays = new ArrayList<>(); + } + this.nestedMixOfDictionariesAndArrays.add(nestedMixOfDictionariesAndArraysItem); + return this; + } + + /** + * Get nestedMixOfDictionariesAndArrays + * @return nestedMixOfDictionariesAndArrays + **/ + @javax.annotation.Nullable + public List>>>>> getNestedMixOfDictionariesAndArrays() { + return nestedMixOfDictionariesAndArrays; + } + + + public void setNestedMixOfDictionariesAndArrays(List>>>>> nestedMixOfDictionariesAndArrays) { + this.nestedMixOfDictionariesAndArrays = nestedMixOfDictionariesAndArrays; + } - // check if the actual instance is of the type \`AnotherNamedOneOf\` - if (value.getActualInstance() instanceof AnotherNamedOneOf) { - JsonObject obj = adapterAnotherNamedOneOf.toJsonTree((AnotherNamedOneOf)value.getActualInstance()).getAsJsonObject(); - elementAdapter.write(out, obj); - return; - } + public NestedCollections cycleArray(List cycleArray) { - throw new IOException("Failed to serialize as the type doesn't match oneOf schemas: NamedOneOf, AnotherNamedOneOf"); - } + this.cycleArray = cycleArray; + return this; + } - @Override - public NamedOneOfUnion read(JsonReader in) throws IOException { - Object deserialized = null; - JsonObject jsonObject = elementAdapter.read(in).getAsJsonObject(); + public NestedCollections addCycleArrayItem(CycleArrayNode cycleArrayItem) { + if (this.cycleArray == null) { + this.cycleArray = new ArrayList<>(); + } + this.cycleArray.add(cycleArrayItem); + return this; + } - int match = 0; - ArrayList errorMessages = new ArrayList<>(); - TypeAdapter actualAdapter = elementAdapter; + /** + * Get cycleArray + * @return cycleArray + **/ + @javax.annotation.Nullable + public List getCycleArray() { + return cycleArray; + } - // deserialize NamedOneOf - try { - // validate the JSON object to see if any exception is thrown - NamedOneOf.validateJsonObject(jsonObject); - actualAdapter = adapterNamedOneOf; - match++; - log.log(Level.FINER, "Input data matches schema 'NamedOneOf'"); - } catch (Exception e) { - // deserialization failed, continue - errorMessages.add(String.format("Deserialization for NamedOneOf failed with \`%s\`.", e.getMessage())); - log.log(Level.FINER, "Input data does not match schema 'NamedOneOf'", e); - } - // deserialize AnotherNamedOneOf - try { - // validate the JSON object to see if any exception is thrown - AnotherNamedOneOf.validateJsonObject(jsonObject); - actualAdapter = adapterAnotherNamedOneOf; - match++; - log.log(Level.FINER, "Input data matches schema 'AnotherNamedOneOf'"); - } catch (Exception e) { - // deserialization failed, continue - errorMessages.add(String.format("Deserialization for AnotherNamedOneOf failed with \`%s\`.", e.getMessage())); - log.log(Level.FINER, "Input data does not match schema 'AnotherNamedOneOf'", e); - } + public void setCycleArray(List cycleArray) { + this.cycleArray = cycleArray; + } - if (match == 1) { - NamedOneOfUnion ret = new NamedOneOfUnion(); - ret.setActualInstance(actualAdapter.fromJsonTree(jsonObject)); - return ret; - } + public NestedCollections cycleDictionary(CycleDictionary cycleDictionary) { - throw new IOException(String.format("Failed deserialization for NamedOneOfUnion: %d classes match result, expected 1. Detailed failure message for oneOf schemas: %s. JSON: %s", match, errorMessages, jsonObject.toString())); - } - }.nullSafe(); - } - } + this.cycleDictionary = cycleDictionary; + return this; + } - // store a list of schema names defined in oneOf - public static final Map schemas = new HashMap(); + /** + * Get cycleDictionary + * @return cycleDictionary + **/ + @javax.annotation.Nullable + public CycleDictionary getCycleDictionary() { + return cycleDictionary; + } - public NamedOneOfUnion() { - super("oneOf", Boolean.FALSE); - } - public NamedOneOfUnion(NamedOneOf o) { - super("oneOf", Boolean.FALSE); - setActualInstance(o); - } + public void setCycleDictionary(CycleDictionary cycleDictionary) { + this.cycleDictionary = cycleDictionary; + } - public NamedOneOfUnion(AnotherNamedOneOf o) { - super("oneOf", Boolean.FALSE); - setActualInstance(o); - } - static { - schemas.put("NamedOneOf", new GenericType() { - }); - schemas.put("AnotherNamedOneOf", new GenericType() { - }); + @Override + public boolean equals(Object o) { + if (this == o) { + return true; } - - @Override - public Map getSchemas() { - return NamedOneOfUnion.schemas; + if (o == null || getClass() != o.getClass()) { + return false; } + NestedCollections nestedCollections = (NestedCollections) o; + return Objects.equals(this.nestedArrayOfStrings, nestedCollections.nestedArrayOfStrings) && + Objects.equals(this.nestedArrayOfDates, nestedCollections.nestedArrayOfDates) && + Objects.equals(this.nestedArrayOfObjects, nestedCollections.nestedArrayOfObjects) && + Objects.equals(this.fourDimensionalNestedArrayOfObjects, nestedCollections.fourDimensionalNestedArrayOfObjects) && + Objects.equals(this.nestedDictionaryOfStrings, nestedCollections.nestedDictionaryOfStrings) && + Objects.equals(this.nestedDictionaryOfObjects, nestedCollections.nestedDictionaryOfObjects) && + Objects.equals(this.fourDimensionalNestedDictionaryOfObjects, nestedCollections.fourDimensionalNestedDictionaryOfObjects) && + Objects.equals(this.nestedMixOfDictionariesAndArrays, nestedCollections.nestedMixOfDictionariesAndArrays) && + Objects.equals(this.cycleArray, nestedCollections.cycleArray) && + Objects.equals(this.cycleDictionary, nestedCollections.cycleDictionary); + + } - /** - * Set the instance that matches the oneOf child schema, check - * the instance parameter is valid against the oneOf child schemas: - * NamedOneOf, AnotherNamedOneOf - * - * It could be an instance of the 'oneOf' schemas. - * The oneOf child schemas may themselves be a composed schema (allOf, anyOf, oneOf). - */ - @Override - public void setActualInstance(Object instance) { - if (instance instanceof NamedOneOf) { - super.setActualInstance(instance); - return; - } + @Override + public int hashCode() { + return Objects.hash(nestedArrayOfStrings, nestedArrayOfDates, nestedArrayOfObjects, fourDimensionalNestedArrayOfObjects, nestedDictionaryOfStrings, nestedDictionaryOfObjects, fourDimensionalNestedDictionaryOfObjects, nestedMixOfDictionariesAndArrays, cycleArray, cycleDictionary); + } - if (instance instanceof AnotherNamedOneOf) { - super.setActualInstance(instance); - return; - } + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class NestedCollections {\\n"); + sb.append(" nestedArrayOfStrings: ").append(toIndentedString(nestedArrayOfStrings)).append("\\n"); + sb.append(" nestedArrayOfDates: ").append(toIndentedString(nestedArrayOfDates)).append("\\n"); + sb.append(" nestedArrayOfObjects: ").append(toIndentedString(nestedArrayOfObjects)).append("\\n"); + sb.append(" fourDimensionalNestedArrayOfObjects: ").append(toIndentedString(fourDimensionalNestedArrayOfObjects)).append("\\n"); + sb.append(" nestedDictionaryOfStrings: ").append(toIndentedString(nestedDictionaryOfStrings)).append("\\n"); + sb.append(" nestedDictionaryOfObjects: ").append(toIndentedString(nestedDictionaryOfObjects)).append("\\n"); + sb.append(" fourDimensionalNestedDictionaryOfObjects: ").append(toIndentedString(fourDimensionalNestedDictionaryOfObjects)).append("\\n"); + sb.append(" nestedMixOfDictionariesAndArrays: ").append(toIndentedString(nestedMixOfDictionariesAndArrays)).append("\\n"); + sb.append(" cycleArray: ").append(toIndentedString(cycleArray)).append("\\n"); + sb.append(" cycleDictionary: ").append(toIndentedString(cycleDictionary)).append("\\n"); + sb.append("}"); + return sb.toString(); + } - throw new RuntimeException("Invalid instance type. Must be NamedOneOf, AnotherNamedOneOf"); + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; } + return o.toString().replace("\\n", "\\n "); + } - /** - * Get the actual instance, which can be the following: - * NamedOneOf, AnotherNamedOneOf - * - * @return The actual instance (NamedOneOf, AnotherNamedOneOf) - */ - @Override - public Object getActualInstance() { - return super.getActualInstance(); - } - /** - * Get the actual instance of \`NamedOneOf\`. If the actual instance is not \`NamedOneOf\`, - * the ClassCastException will be thrown. - * - * @return The actual instance of \`NamedOneOf\` - * @throws ClassCastException if the instance is not \`NamedOneOf\` - */ - public NamedOneOf getNamedOneOf() throws ClassCastException { - return (NamedOneOf)super.getActualInstance(); - } + public static HashSet openapiFields; + public static HashSet openapiRequiredFields; - /** - * Get the actual instance of \`AnotherNamedOneOf\`. If the actual instance is not \`AnotherNamedOneOf\`, - * the ClassCastException will be thrown. - * - * @return The actual instance of \`AnotherNamedOneOf\` - * @throws ClassCastException if the instance is not \`AnotherNamedOneOf\` - */ - public AnotherNamedOneOf getAnotherNamedOneOf() throws ClassCastException { - return (AnotherNamedOneOf)super.getActualInstance(); - } + static { + // a set of all properties/fields (JSON key names) + openapiFields = new HashSet(); + openapiFields.add("nestedArrayOfStrings"); + openapiFields.add("nestedArrayOfDates"); + openapiFields.add("nestedArrayOfObjects"); + openapiFields.add("fourDimensionalNestedArrayOfObjects"); + openapiFields.add("nestedDictionaryOfStrings"); + openapiFields.add("nestedDictionaryOfObjects"); + openapiFields.add("fourDimensionalNestedDictionaryOfObjects"); + openapiFields.add("nestedMixOfDictionariesAndArrays"); + openapiFields.add("cycleArray"); + openapiFields.add("cycleDictionary"); + // a set of required properties/fields (JSON key names) + openapiRequiredFields = new HashSet(); + } /** * Validates the JSON Object and throws an exception if issues found * * @param jsonObj JSON Object - * @throws IOException if the JSON Object is invalid with respect to NamedOneOfUnion + * @throws IOException if the JSON Object is invalid with respect to NestedCollections */ public static void validateJsonObject(JsonObject jsonObj) throws IOException { - // validate oneOf schemas one by one - int validCount = 0; - ArrayList errorMessages = new ArrayList<>(); - // validate the json string with NamedOneOf - try { - NamedOneOf.validateJsonObject(jsonObj); - validCount++; - } catch (Exception e) { - errorMessages.add(String.format("Deserialization for NamedOneOf failed with \`%s\`.", e.getMessage())); - // continue to the next one - } - // validate the json string with AnotherNamedOneOf - try { - AnotherNamedOneOf.validateJsonObject(jsonObj); - validCount++; - } catch (Exception e) { - errorMessages.add(String.format("Deserialization for AnotherNamedOneOf failed with \`%s\`.", e.getMessage())); - // continue to the next one - } - if (validCount != 1) { - throw new IOException(String.format("The JSON string is invalid for NamedOneOfUnion with oneOf schemas: NamedOneOf, AnotherNamedOneOf. %d class(es) match the result, expected 1. Detailed failure message for oneOf schemas: %s. JSON: %s", validCount, errorMessages, jsonObj.toString())); + if (jsonObj == null) { + if (!NestedCollections.openapiRequiredFields.isEmpty()) { // has required fields but JSON object is null + throw new IllegalArgumentException(String.format("The required field(s) %s in NestedCollections is not found in the empty JSON string", NestedCollections.openapiRequiredFields.toString())); + } + } + + Set> entries = jsonObj.entrySet(); + // check to see if the JSON string contains additional fields + for (Entry entry : entries) { + if (!NestedCollections.openapiFields.contains(entry.getKey())) { + throw new IllegalArgumentException(String.format("The field \`%s\` in the JSON string is not defined in the \`NestedCollections\` properties. JSON: %s", entry.getKey(), jsonObj.toString())); + } + } + if (jsonObj.get("nestedArrayOfStrings") != null && !jsonObj.get("nestedArrayOfStrings").isJsonNull()) { + JsonArray jsonArraynestedArrayOfStrings = jsonObj.getAsJsonArray("nestedArrayOfStrings"); + if (jsonArraynestedArrayOfStrings != null) { + // ensure the json data is an array + if (!jsonObj.get("nestedArrayOfStrings").isJsonArray()) { + throw new IllegalArgumentException(String.format("Expected the field \`nestedArrayOfStrings\` to be an array in the JSON string but got \`%s\`", jsonObj.get("nestedArrayOfStrings").toString())); + } + + // validate the optional field \`nestedArrayOfStrings\` (array) + for (int i = 0; i < jsonArraynestedArrayOfStrings.size(); i++) { + List.validateJsonObject(jsonArraynestedArrayOfStrings.get(i).getAsJsonObject()); + }; + } + } + if (jsonObj.get("nestedArrayOfDates") != null && !jsonObj.get("nestedArrayOfDates").isJsonNull()) { + JsonArray jsonArraynestedArrayOfDates = jsonObj.getAsJsonArray("nestedArrayOfDates"); + if (jsonArraynestedArrayOfDates != null) { + // ensure the json data is an array + if (!jsonObj.get("nestedArrayOfDates").isJsonArray()) { + throw new IllegalArgumentException(String.format("Expected the field \`nestedArrayOfDates\` to be an array in the JSON string but got \`%s\`", jsonObj.get("nestedArrayOfDates").toString())); + } + + // validate the optional field \`nestedArrayOfDates\` (array) + for (int i = 0; i < jsonArraynestedArrayOfDates.size(); i++) { + List.validateJsonObject(jsonArraynestedArrayOfDates.get(i).getAsJsonObject()); + }; + } + } + if (jsonObj.get("nestedArrayOfObjects") != null && !jsonObj.get("nestedArrayOfObjects").isJsonNull()) { + JsonArray jsonArraynestedArrayOfObjects = jsonObj.getAsJsonArray("nestedArrayOfObjects"); + if (jsonArraynestedArrayOfObjects != null) { + // ensure the json data is an array + if (!jsonObj.get("nestedArrayOfObjects").isJsonArray()) { + throw new IllegalArgumentException(String.format("Expected the field \`nestedArrayOfObjects\` to be an array in the JSON string but got \`%s\`", jsonObj.get("nestedArrayOfObjects").toString())); + } + + // validate the optional field \`nestedArrayOfObjects\` (array) + for (int i = 0; i < jsonArraynestedArrayOfObjects.size(); i++) { + List.validateJsonObject(jsonArraynestedArrayOfObjects.get(i).getAsJsonObject()); + }; + } + } + if (jsonObj.get("fourDimensionalNestedArrayOfObjects") != null && !jsonObj.get("fourDimensionalNestedArrayOfObjects").isJsonNull()) { + JsonArray jsonArrayfourDimensionalNestedArrayOfObjects = jsonObj.getAsJsonArray("fourDimensionalNestedArrayOfObjects"); + if (jsonArrayfourDimensionalNestedArrayOfObjects != null) { + // ensure the json data is an array + if (!jsonObj.get("fourDimensionalNestedArrayOfObjects").isJsonArray()) { + throw new IllegalArgumentException(String.format("Expected the field \`fourDimensionalNestedArrayOfObjects\` to be an array in the JSON string but got \`%s\`", jsonObj.get("fourDimensionalNestedArrayOfObjects").toString())); + } + + // validate the optional field \`fourDimensionalNestedArrayOfObjects\` (array) + for (int i = 0; i < jsonArrayfourDimensionalNestedArrayOfObjects.size(); i++) { + List>>.validateJsonObject(jsonArrayfourDimensionalNestedArrayOfObjects.get(i).getAsJsonObject()); + }; + } + } + if (jsonObj.get("nestedMixOfDictionariesAndArrays") != null && !jsonObj.get("nestedMixOfDictionariesAndArrays").isJsonNull()) { + JsonArray jsonArraynestedMixOfDictionariesAndArrays = jsonObj.getAsJsonArray("nestedMixOfDictionariesAndArrays"); + if (jsonArraynestedMixOfDictionariesAndArrays != null) { + // ensure the json data is an array + if (!jsonObj.get("nestedMixOfDictionariesAndArrays").isJsonArray()) { + throw new IllegalArgumentException(String.format("Expected the field \`nestedMixOfDictionariesAndArrays\` to be an array in the JSON string but got \`%s\`", jsonObj.get("nestedMixOfDictionariesAndArrays").toString())); + } + + // validate the optional field \`nestedMixOfDictionariesAndArrays\` (array) + for (int i = 0; i < jsonArraynestedMixOfDictionariesAndArrays.size(); i++) { + Map>>>>.validateJsonObject(jsonArraynestedMixOfDictionariesAndArrays.get(i).getAsJsonObject()); + }; + } + } + if (jsonObj.get("cycleArray") != null && !jsonObj.get("cycleArray").isJsonNull()) { + JsonArray jsonArraycycleArray = jsonObj.getAsJsonArray("cycleArray"); + if (jsonArraycycleArray != null) { + // ensure the json data is an array + if (!jsonObj.get("cycleArray").isJsonArray()) { + throw new IllegalArgumentException(String.format("Expected the field \`cycleArray\` to be an array in the JSON string but got \`%s\`", jsonObj.get("cycleArray").toString())); + } + + // validate the optional field \`cycleArray\` (array) + for (int i = 0; i < jsonArraycycleArray.size(); i++) { + CycleArrayNode.validateJsonObject(jsonArraycycleArray.get(i).getAsJsonObject()); + }; + } + } + // validate the optional field \`cycleDictionary\` + if (jsonObj.get("cycleDictionary") != null && !jsonObj.get("cycleDictionary").isJsonNull()) { + CycleDictionary.validateJsonObject(jsonObj.getAsJsonObject("cycleDictionary")); + } + } + + public static class CustomTypeAdapterFactory implements TypeAdapterFactory { + @SuppressWarnings("unchecked") + @Override + public TypeAdapter create(Gson gson, TypeToken type) { + if (!NestedCollections.class.isAssignableFrom(type.getRawType())) { + return null; // this class only serializes 'NestedCollections' and its subtypes + } + final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); + final TypeAdapter thisAdapter + = gson.getDelegateAdapter(this, TypeToken.get(NestedCollections.class)); + + return (TypeAdapter) new TypeAdapter() { + @Override + public void write(JsonWriter out, NestedCollections value) throws IOException { + JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); + elementAdapter.write(out, obj); + } + + @Override + public NestedCollections read(JsonReader in) throws IOException { + JsonObject jsonObj = elementAdapter.read(in).getAsJsonObject(); + validateJsonObject(jsonObj); + return thisAdapter.fromJsonTree(jsonObj); + } + + }.nullSafe(); } } /** - * Create an instance of NamedOneOfUnion given an JSON string + * Create an instance of NestedCollections given an JSON string * * @param jsonString JSON string - * @return An instance of NamedOneOfUnion - * @throws IOException if the JSON string is invalid with respect to NamedOneOfUnion + * @return An instance of NestedCollections + * @throws IOException if the JSON string is invalid with respect to NestedCollections */ - public static NamedOneOfUnion fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, NamedOneOfUnion.class); + public static NestedCollections fromJson(String jsonString) throws IOException { + return JSON.getGson().fromJson(jsonString, NestedCollections.class); } /** - * Convert an instance of NamedOneOfUnion to an JSON string + * Convert an instance of NestedCollections to an JSON string * * @return JSON string */ public String toJson() { return JSON.getGson().toJson(this); } - } ", "src/main/java/test/test/runtime/model/SomeObject.java": "/* diff --git a/packages/type-safe-api/test/scripts/generators/__snapshots__/python.test.ts.snap b/packages/type-safe-api/test/scripts/generators/__snapshots__/python.test.ts.snap index b4683b19b..589fcc4ea 100644 --- a/packages/type-safe-api/test/scripts/generators/__snapshots__/python.test.ts.snap +++ b/packages/type-safe-api/test/scripts/generators/__snapshots__/python.test.ts.snap @@ -12705,6 +12705,9 @@ class DataTypes200Response(BaseModel): }, exclude_none=True, ) + # override the default output from pydantic by calling \`to_dict()\` of my_date_array + if self.my_date_array: + _dict['myDateArray'] = self.my_date_array.to_dict() # override the default output from pydantic by calling \`to_dict()\` of my_one_of if self.my_one_of: _dict['myOneOf'] = self.my_one_of.to_dict() @@ -12714,6 +12717,13 @@ class DataTypes200Response(BaseModel): # override the default output from pydantic by calling \`to_dict()\` of my_all_of if self.my_all_of: _dict['myAllOf'] = self.my_all_of.to_dict() + # override the default output from pydantic by calling \`to_dict()\` of each value in my_additional_properties (dict) + _field_dict = {} + if self.my_additional_properties: + for _key in self.my_additional_properties: + if self.my_additional_properties[_key]: + _field_dict[_key] = self.my_additional_properties[_key].to_dict() + _dict['myAdditionalProperties'] = _field_dict # override the default output from pydantic by calling \`to_dict()\` of my_object if self.my_object: _dict['myObject'] = self.my_object.to_dict() @@ -12747,7 +12757,7 @@ class DataTypes200Response(BaseModel): "myLongMinStringLength": obj.get("myLongMinStringLength"), "myBool": obj.get("myBool"), "myNumber": obj.get("myNumber"), - "myDateArray": obj.get("myDateArray"), + "myDateArray": List[date].from_dict(obj.get("myDateArray")) if obj.get("myDateArray") is not None else None, "myEmail": obj.get("myEmail"), "myUrl": obj.get("myUrl"), "myHostname": obj.get("myHostname"), @@ -12763,7 +12773,12 @@ class DataTypes200Response(BaseModel): "myAllOf": DataTypes200ResponseMyAllOf.from_dict(obj.get("myAllOf")) if obj.get("myAllOf") is not None else None, "myNot": obj.get("myNot"), "myNotString": obj.get("myNotString"), - "myAdditionalProperties": obj.get("myAdditionalProperties"), + "myAdditionalProperties": dict( + (_k, List[int].from_dict(_v)) + for _k, _v in obj.get("myAdditionalProperties").items() + ) + if obj.get("myAdditionalProperties") is not None + else None, "myObject": DataTypes200ResponseMyObject.from_dict(obj.get("myObject")) if obj.get("myObject") is not None else None }) return _obj @@ -17431,6 +17446,9 @@ test_project/models/__init__.py test_project/models/additional_properties_response.py test_project/models/another_named_one_of.py test_project/models/array_of_one_ofs.py +test_project/models/cycle_array_node.py +test_project/models/cycle_dictionary.py +test_project/models/cycle_dictionary_node.py test_project/models/dictionary.py test_project/models/inline_enum200_response.py test_project/models/inline_enum200_response_category_enum.py @@ -17438,6 +17456,7 @@ test_project/models/inline_request_body_request_content.py test_project/models/my_enum.py test_project/models/named_one_of.py test_project/models/named_one_of_union.py +test_project/models/nested_collections.py test_project/models/some_object.py test_project/py.typed test_project/rest.py @@ -17445,6 +17464,9 @@ docs/DefaultApi.md docs/AdditionalPropertiesResponse.md docs/AnotherNamedOneOf.md docs/ArrayOfOneOfs.md +docs/CycleArrayNode.md +docs/CycleDictionary.md +docs/CycleDictionaryNode.md docs/Dictionary.md docs/InlineEnum200Response.md docs/InlineEnum200ResponseCategoryEnum.md @@ -17452,6 +17474,7 @@ docs/InlineRequestBodyRequestContent.md docs/MyEnum.md docs/NamedOneOf.md docs/NamedOneOfUnion.md +docs/NestedCollections.md docs/SomeObject.md README.md test_project/interceptors/try_catch.py @@ -17512,6 +17535,7 @@ Class | Method | HTTP request | Description *DefaultApi* | [**inline_enum**](docs/DefaultApi.md#inline_enum) | **GET** /inline-enum | *DefaultApi* | [**inline_request_body**](docs/DefaultApi.md#inline_request_body) | **POST** /inline-request-body | *DefaultApi* | [**named_one_of**](docs/DefaultApi.md#named_one_of) | **POST** /named-one-of | +*DefaultApi* | [**nested_collections**](docs/DefaultApi.md#nested_collections) | **POST** /nested-collections | *DefaultApi* | [**reserved_keywords**](docs/DefaultApi.md#reserved_keywords) | **GET** /reserved-keywords | ## Documentation For Models @@ -17519,6 +17543,9 @@ Class | Method | HTTP request | Description - [AdditionalPropertiesResponse](docs/AdditionalPropertiesResponse.md) - [AnotherNamedOneOf](docs/AnotherNamedOneOf.md) - [ArrayOfOneOfs](docs/ArrayOfOneOfs.md) + - [CycleArrayNode](docs/CycleArrayNode.md) + - [CycleDictionary](docs/CycleDictionary.md) + - [CycleDictionaryNode](docs/CycleDictionaryNode.md) - [Dictionary](docs/Dictionary.md) - [InlineEnum200Response](docs/InlineEnum200Response.md) - [InlineEnum200ResponseCategoryEnum](docs/InlineEnum200ResponseCategoryEnum.md) @@ -17526,6 +17553,7 @@ Class | Method | HTTP request | Description - [MyEnum](docs/MyEnum.md) - [NamedOneOf](docs/NamedOneOf.md) - [NamedOneOfUnion](docs/NamedOneOfUnion.md) + - [NestedCollections](docs/NestedCollections.md) - [SomeObject](docs/SomeObject.md) ", "docs/AdditionalPropertiesResponse.md": "# AdditionalPropertiesResponse @@ -17609,6 +17637,86 @@ array_of_one_ofs_form_dict = array_of_one_ofs.from_dict(array_of_one_ofs_dict) \`\`\` [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) +", + "docs/CycleArrayNode.md": "# CycleArrayNode + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**nodes** | **List[CycleArrayNode]** | | [optional] + +## Example + +\`\`\`python +from test_project.models.cycle_array_node import CycleArrayNode + +# TODO update the JSON string below +json = "{}" +# create an instance of CycleArrayNode from a JSON string +cycle_array_node_instance = CycleArrayNode.from_json(json) +# print the JSON string representation of the object +print(CycleArrayNode.to_json()) + +# convert the object into a dict +cycle_array_node_dict = cycle_array_node_instance.to_dict() +# create an instance of CycleArrayNode from a dict +cycle_array_node_form_dict = cycle_array_node.from_dict(cycle_array_node_dict) +\`\`\` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + +", + "docs/CycleDictionary.md": "# CycleDictionary + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +## Example + +\`\`\`python +from test_project.models.cycle_dictionary import CycleDictionary + +# TODO update the JSON string below +json = "{}" +# create an instance of CycleDictionary from a JSON string +cycle_dictionary_instance = CycleDictionary.from_json(json) +# print the JSON string representation of the object +print(CycleDictionary.to_json()) + +# convert the object into a dict +cycle_dictionary_dict = cycle_dictionary_instance.to_dict() +# create an instance of CycleDictionary from a dict +cycle_dictionary_form_dict = cycle_dictionary.from_dict(cycle_dictionary_dict) +\`\`\` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + +", + "docs/CycleDictionaryNode.md": "# CycleDictionaryNode + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**nodes** | [**CycleDictionary**](CycleDictionary.md) | | [optional] + +## Example + +\`\`\`python +from test_project.models.cycle_dictionary_node import CycleDictionaryNode + +# TODO update the JSON string below +json = "{}" +# create an instance of CycleDictionaryNode from a JSON string +cycle_dictionary_node_instance = CycleDictionaryNode.from_json(json) +# print the JSON string representation of the object +print(CycleDictionaryNode.to_json()) + +# convert the object into a dict +cycle_dictionary_node_dict = cycle_dictionary_node_instance.to_dict() +# create an instance of CycleDictionaryNode from a dict +cycle_dictionary_node_form_dict = cycle_dictionary_node.from_dict(cycle_dictionary_node_dict) +\`\`\` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + ", "docs/DefaultApi.md": "# test_project.DefaultApi @@ -17620,6 +17728,7 @@ Method | HTTP request | Description [**inline_enum**](DefaultApi.md#inline_enum) | **GET** /inline-enum | [**inline_request_body**](DefaultApi.md#inline_request_body) | **POST** /inline-request-body | [**named_one_of**](DefaultApi.md#named_one_of) | **POST** /named-one-of | +[**nested_collections**](DefaultApi.md#nested_collections) | **POST** /nested-collections | [**reserved_keywords**](DefaultApi.md#reserved_keywords) | **GET** /reserved-keywords | # **array_of_one_ofs** @@ -17940,6 +18049,56 @@ This endpoint does not need any parameters. [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) +# **nested_collections** +> NestedCollections nested_collections() + + +### Example + +\`\`\`python +import time +import test_project +from test_project.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = test_project.Configuration( + host = "http://localhost" +) + +# Enter a context with an instance of the API client +with test_project.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = test_project.DefaultApi(api_client) + + try: + api_response = api_instance.nested_collections() + print("The response of DefaultApi->nested_collections:\\n") + pprint(api_response) + except ApiException as e: + print("Exception when calling DefaultApi->nested_collections: %s\\n" % e) +\`\`\` + +### Parameters +This endpoint does not need any parameters. + +### Return type + +[**NestedCollections**](NestedCollections.md) + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +### HTTP response details +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | ok | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + # **reserved_keywords** > reserved_keywords(var_with=var_with, var_if=var_if, var_class=var_class) @@ -18151,6 +18310,42 @@ named_one_of_union_form_dict = named_one_of_union.from_dict(named_one_of_union_d \`\`\` [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) +", + "docs/NestedCollections.md": "# NestedCollections + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**nested_array_of_strings** | **List[List[str]]** | | [optional] +**nested_array_of_dates** | **List[List[date]]** | | [optional] +**nested_array_of_objects** | **List[List[SomeObject]]** | | [optional] +**four_dimensional_nested_array_of_objects** | **List[List[List[List[SomeObject]]]]** | | [optional] +**nested_dictionary_of_strings** | **Dict[str, Dict[str, str]]** | | [optional] +**nested_dictionary_of_objects** | **Dict[str, Dict[str, SomeObject]]** | | [optional] +**four_dimensional_nested_dictionary_of_objects** | **Dict[str, Dict[str, Dict[str, Dict[str, SomeObject]]]]** | | [optional] +**nested_mix_of_dictionaries_and_arrays** | **List[Dict[str, List[List[Dict[str, List[SomeObject]]]]]]** | | [optional] +**cycle_array** | **List[CycleArrayNode]** | | [optional] +**cycle_dictionary** | [**CycleDictionary**](CycleDictionary.md) | | [optional] + +## Example + +\`\`\`python +from test_project.models.nested_collections import NestedCollections + +# TODO update the JSON string below +json = "{}" +# create an instance of NestedCollections from a JSON string +nested_collections_instance = NestedCollections.from_json(json) +# print the JSON string representation of the object +print(NestedCollections.to_json()) + +# convert the object into a dict +nested_collections_dict = nested_collections_instance.to_dict() +# create an instance of NestedCollections from a dict +nested_collections_form_dict = nested_collections.from_dict(nested_collections_dict) +\`\`\` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + ", "docs/SomeObject.md": "# SomeObject @@ -18250,6 +18445,9 @@ from test_project.exceptions import ApiException from test_project.models.additional_properties_response import AdditionalPropertiesResponse from test_project.models.another_named_one_of import AnotherNamedOneOf from test_project.models.array_of_one_ofs import ArrayOfOneOfs +from test_project.models.cycle_array_node import CycleArrayNode +from test_project.models.cycle_dictionary import CycleDictionary +from test_project.models.cycle_dictionary_node import CycleDictionaryNode from test_project.models.dictionary import Dictionary from test_project.models.inline_enum200_response import InlineEnum200Response from test_project.models.inline_enum200_response_category_enum import InlineEnum200ResponseCategoryEnum @@ -18257,6 +18455,7 @@ from test_project.models.inline_request_body_request_content import InlineReques from test_project.models.my_enum import MyEnum from test_project.models.named_one_of import NamedOneOf from test_project.models.named_one_of_union import NamedOneOfUnion +from test_project.models.nested_collections import NestedCollections from test_project.models.some_object import SomeObject ", "test_project/api/__init__.py": "# flake8: noqa @@ -18294,6 +18493,7 @@ from test_project.models.inline_enum200_response import InlineEnum200Response from test_project.models.inline_request_body_request_content import InlineRequestBodyRequestContent from test_project.models.my_enum import MyEnum from test_project.models.named_one_of_union import NamedOneOfUnion +from test_project.models.nested_collections import NestedCollections from test_project.api_client import ApiClient from test_project.api_response import ApiResponse @@ -19875,11 +20075,8 @@ class DefaultApi: @validate_call - def reserved_keywords( + def nested_collections( self, - var_with: Optional[StrictStr] = None, - var_if: Optional[StrictStr] = None, - var_class: Optional[StrictStr] = None, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], @@ -19892,14 +20089,8 @@ class DefaultApi: _content_type: Optional[StrictStr] = None, _headers: Optional[Dict[StrictStr, Any]] = None, _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, - ) -> None: - """reserved_keywords - :param var_with: (optional) - :type var_with: str, optional - :param var_if: (optional) - :type var_if: str, optional - :param var_class: (optional) - :type var_class: str, optional + ) -> NestedCollections: + """nested_collections :param _request_timeout: timeout setting for this request. If one number provided, it will be total request timeout. It can also be a pair (tuple) of @@ -19922,10 +20113,7 @@ class DefaultApi: :return: Returns the result object. """ # noqa: E501 - _param = self._reserved_keywords_serialize( - var_with=var_with, - var_if=var_if, - var_class=var_class, + _param = self._nested_collections_serialize( _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, @@ -19933,6 +20121,7 @@ class DefaultApi: ) _response_types_map: Dict[str, Optional[str]] = { + '200': "NestedCollections" } response_data = self.api_client.call_api( @@ -19947,11 +20136,8 @@ class DefaultApi: @validate_call - def reserved_keywords_with_http_info( + def nested_collections_with_http_info( self, - var_with: Optional[StrictStr] = None, - var_if: Optional[StrictStr] = None, - var_class: Optional[StrictStr] = None, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], @@ -19964,14 +20150,8 @@ class DefaultApi: _content_type: Optional[StrictStr] = None, _headers: Optional[Dict[StrictStr, Any]] = None, _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, - ) -> ApiResponse[None]: - """reserved_keywords - :param var_with: (optional) - :type var_with: str, optional - :param var_if: (optional) - :type var_if: str, optional - :param var_class: (optional) - :type var_class: str, optional + ) -> ApiResponse[NestedCollections]: + """nested_collections :param _request_timeout: timeout setting for this request. If one number provided, it will be total request timeout. It can also be a pair (tuple) of @@ -19994,10 +20174,7 @@ class DefaultApi: :return: Returns the result object. """ # noqa: E501 - _param = self._reserved_keywords_serialize( - var_with=var_with, - var_if=var_if, - var_class=var_class, + _param = self._nested_collections_serialize( _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, @@ -20005,6 +20182,7 @@ class DefaultApi: ) _response_types_map: Dict[str, Optional[str]] = { + '200': "NestedCollections" } response_data = self.api_client.call_api( @@ -20019,11 +20197,8 @@ class DefaultApi: @validate_call - def reserved_keywords_without_preload_content( + def nested_collections_without_preload_content( self, - var_with: Optional[StrictStr] = None, - var_if: Optional[StrictStr] = None, - var_class: Optional[StrictStr] = None, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], @@ -20037,13 +20212,7 @@ class DefaultApi: _headers: Optional[Dict[StrictStr, Any]] = None, _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, ) -> RESTResponseType: - """reserved_keywords - :param var_with: (optional) - :type var_with: str, optional - :param var_if: (optional) - :type var_if: str, optional - :param var_class: (optional) - :type var_class: str, optional + """nested_collections :param _request_timeout: timeout setting for this request. If one number provided, it will be total request timeout. It can also be a pair (tuple) of @@ -20066,10 +20235,7 @@ class DefaultApi: :return: Returns the result object. """ # noqa: E501 - _param = self._reserved_keywords_serialize( - var_with=var_with, - var_if=var_if, - var_class=var_class, + _param = self._nested_collections_serialize( _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, @@ -20077,6 +20243,7 @@ class DefaultApi: ) _response_types_map: Dict[str, Optional[str]] = { + '200': "NestedCollections" } response_data = self.api_client.call_api( @@ -20086,11 +20253,8 @@ class DefaultApi: return response_data.response - def _reserved_keywords_serialize( + def _nested_collections_serialize( self, - var_with, - var_if, - var_class, _request_auth, _content_type, _headers, @@ -20111,17 +20275,17 @@ class DefaultApi: # process the path parameters # process the query parameters - if var_with is not None: - _query_params.append(('with', var_with)) - if var_if is not None: - _query_params.append(('if', var_if)) - if var_class is not None: - _query_params.append(('class', var_class)) # process the header parameters # process the form parameters # process the body parameter + # set the HTTP header \`Accept\` + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) # authentication setting @@ -20129,8 +20293,8 @@ class DefaultApi: ] return self.api_client.param_serialize( - method='GET', - resource_path='/reserved-keywords', + method='POST', + resource_path='/nested-collections', path_params=_path_params, query_params=_query_params, header_params=_header_params, @@ -20144,30 +20308,302 @@ class DefaultApi: ) -", - "test_project/api/operation_config.py": "from __future__ import annotations -import urllib.parse -import json -from typing import Callable, Any, Dict, List, NamedTuple, TypeVar, Generic, Union, TypedDict, Protocol, Optional, Literal, Annotated -from functools import wraps -from dataclasses import dataclass, fields -from datetime import datetime -import dateutil.parser -from pydantic import BaseModel, Field, StrictStr, conlist, StrictBool, StrictInt, StrictFloat -from test_project.models import * + @validate_call + def reserved_keywords( + self, + var_with: Optional[StrictStr] = None, + var_if: Optional[StrictStr] = None, + var_class: Optional[StrictStr] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> None: + """reserved_keywords + :param var_with: (optional) + :type var_with: str, optional + :param var_if: (optional) + :type var_if: str, optional + :param var_class: (optional) + :type var_class: str, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 -T = TypeVar('T') + _param = self._reserved_keywords_serialize( + var_with=var_with, + var_if=var_if, + var_class=var_class, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) -# Generic type for object keyed by operation names -@dataclass -class OperationConfig(Generic[T]): - array_of_one_ofs: T + _response_types_map: Dict[str, Optional[str]] = { + } + + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def reserved_keywords_with_http_info( + self, + var_with: Optional[StrictStr] = None, + var_if: Optional[StrictStr] = None, + var_class: Optional[StrictStr] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[None]: + """reserved_keywords + :param var_with: (optional) + :type var_with: str, optional + :param var_if: (optional) + :type var_if: str, optional + :param var_class: (optional) + :type var_class: str, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._reserved_keywords_serialize( + var_with=var_with, + var_if=var_if, + var_class=var_class, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + } + + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def reserved_keywords_without_preload_content( + self, + var_with: Optional[StrictStr] = None, + var_if: Optional[StrictStr] = None, + var_class: Optional[StrictStr] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """reserved_keywords + :param var_with: (optional) + :type var_with: str, optional + :param var_if: (optional) + :type var_if: str, optional + :param var_class: (optional) + :type var_class: str, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._reserved_keywords_serialize( + var_with=var_with, + var_if=var_if, + var_class=var_class, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + } + + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _reserved_keywords_serialize( + self, + var_with, + var_if, + var_class, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> Tuple: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[str, str] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + # process the query parameters + if var_with is not None: + _query_params.append(('with', var_with)) + if var_if is not None: + _query_params.append(('if', var_if)) + if var_class is not None: + _query_params.append(('class', var_class)) + # process the header parameters + # process the form parameters + # process the body parameter + + + + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='GET', + resource_path='/reserved-keywords', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + +", + "test_project/api/operation_config.py": "from __future__ import annotations +import urllib.parse +import json +from typing import Callable, Any, Dict, List, NamedTuple, TypeVar, Generic, Union, TypedDict, Protocol, Optional, Literal, Annotated +from functools import wraps +from dataclasses import dataclass, fields +from datetime import datetime +import dateutil.parser +from pydantic import BaseModel, Field, StrictStr, conlist, StrictBool, StrictInt, StrictFloat + +from test_project.models import * + +T = TypeVar('T') + +# Generic type for object keyed by operation names +@dataclass +class OperationConfig(Generic[T]): + array_of_one_ofs: T array_request_parameters: T dictionary: T inline_enum: T inline_request_body: T named_one_of: T + nested_collections: T reserved_keywords: T ... @@ -20203,6 +20639,11 @@ OperationLookup = { "method": "POST", "contentTypes": ["application/json"] }, + "nested_collections": { + "path": "/nested-collections", + "method": "POST", + "contentTypes": ["application/json"] + }, "reserved_keywords": { "path": "/reserved-keywords", "method": "GET", @@ -21082,13 +21523,10 @@ def named_one_of_handler(_handler: NamedOneOfHandlerFunction = None, interceptor else: raise Exception("Positional arguments are not supported by named_one_of_handler.") -class ReservedKeywordsRequestParameters(BaseModel): +class NestedCollectionsRequestParameters(BaseModel): """ - Query, path and header parameters for the ReservedKeywords operation + Query, path and header parameters for the NestedCollections operation """ - var_with: Optional[StrictStr] - var_if: Optional[StrictStr] - var_class: Optional[StrictStr] class Config: """Pydantic configuration""" @@ -21099,41 +21537,41 @@ class ReservedKeywordsRequestParameters(BaseModel): return json.dumps(self.to_dict()) @classmethod - def from_json(cls, json_str: str) -> ReservedKeywordsRequestParameters: + def from_json(cls, json_str: str) -> NestedCollectionsRequestParameters: return cls.from_dict(json.loads(json_str)) def to_dict(self): return self.model_dump(exclude={}, exclude_none=True) @classmethod - def from_dict(cls, obj: dict) -> ReservedKeywordsRequestParameters: + def from_dict(cls, obj: dict) -> NestedCollectionsRequestParameters: if obj is None: return None - return ReservedKeywordsRequestParameters.model_validate(obj) + return NestedCollectionsRequestParameters.model_validate(obj) # Request body type (default to Any when no body parameters exist, or leave unchanged as str if it's a primitive type) -ReservedKeywordsRequestBody = Any +NestedCollectionsRequestBody = Any -ReservedKeywords200OperationResponse = ApiResponse[Literal[200], None] +NestedCollections200OperationResponse = ApiResponse[Literal[200], NestedCollections] -ReservedKeywordsOperationResponses = Union[ReservedKeywords200OperationResponse, ] +NestedCollectionsOperationResponses = Union[NestedCollections200OperationResponse, ] -# Request type for reserved_keywords -ReservedKeywordsRequest = ApiRequest[ReservedKeywordsRequestParameters, ReservedKeywordsRequestBody] -ReservedKeywordsChainedRequest = ChainedApiRequest[ReservedKeywordsRequestParameters, ReservedKeywordsRequestBody] +# Request type for nested_collections +NestedCollectionsRequest = ApiRequest[NestedCollectionsRequestParameters, NestedCollectionsRequestBody] +NestedCollectionsChainedRequest = ChainedApiRequest[NestedCollectionsRequestParameters, NestedCollectionsRequestBody] -class ReservedKeywordsHandlerFunction(Protocol): - def __call__(self, input: ReservedKeywordsRequest, **kwargs) -> ReservedKeywordsOperationResponses: +class NestedCollectionsHandlerFunction(Protocol): + def __call__(self, input: NestedCollectionsRequest, **kwargs) -> NestedCollectionsOperationResponses: ... -ReservedKeywordsInterceptor = Callable[[ReservedKeywordsChainedRequest], ReservedKeywordsOperationResponses] +NestedCollectionsInterceptor = Callable[[NestedCollectionsChainedRequest], NestedCollectionsOperationResponses] -def reserved_keywords_handler(_handler: ReservedKeywordsHandlerFunction = None, interceptors: List[ReservedKeywordsInterceptor] = []): +def nested_collections_handler(_handler: NestedCollectionsHandlerFunction = None, interceptors: List[NestedCollectionsInterceptor] = []): """ - Decorator for an api handler for the reserved_keywords operation, providing a typed interface for inputs and outputs + Decorator for an api handler for the nested_collections operation, providing a typed interface for inputs and outputs """ - def _handler_wrapper(handler: ReservedKeywordsHandlerFunction): + def _handler_wrapper(handler: NestedCollectionsHandlerFunction): @wraps(handler) def wrapper(event, context, additional_interceptors = [], **kwargs): all_interceptors = additional_interceptors + interceptors @@ -21154,8 +21592,126 @@ def reserved_keywords_handler(_handler: ReservedKeywordsHandlerFunction = None, request_parameters = None try: - request_parameters = ReservedKeywordsRequestParameters.from_dict({ - "var_with": coerce_parameter("with", "str", raw_string_parameters, raw_string_array_parameters, False), + request_parameters = NestedCollectionsRequestParameters.from_dict({ + }) + except Exception as e: + return { + 'statusCode': 400, + 'headers': {**response_headers_for_status_code(400), **extract_response_headers_from_interceptors(all_interceptors)}, + 'body': '{"message": "' + str(e) + '"}', + } + + body = {} + interceptor_context = { + "operationId": "nested_collections", + } + + chain = _build_handler_chain(all_interceptors, handler) + response = chain.next(ApiRequest( + request_parameters, + body, + event, + context, + interceptor_context, + ), **kwargs) + + response_headers = {** (response.headers or {}), **response_headers_for_status_code(response.status_code)} + response_body = '' + if response.body is None: + pass + elif response.status_code == 200: + response_body = response.body.to_json() + + return { + 'statusCode': response.status_code, + 'headers': response_headers, + 'multiValueHeaders': response.multi_value_headers or {}, + 'body': response_body, + } + return wrapper + + # Support use as a decorator with no arguments, or with interceptor arguments + if callable(_handler): + return _handler_wrapper(_handler) + elif _handler is None: + return _handler_wrapper + else: + raise Exception("Positional arguments are not supported by nested_collections_handler.") + +class ReservedKeywordsRequestParameters(BaseModel): + """ + Query, path and header parameters for the ReservedKeywords operation + """ + var_with: Optional[StrictStr] + var_if: Optional[StrictStr] + var_class: Optional[StrictStr] + + class Config: + """Pydantic configuration""" + populate_by_name = True + validate_assignment = True + + def to_json(self) -> str: + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> ReservedKeywordsRequestParameters: + return cls.from_dict(json.loads(json_str)) + + def to_dict(self): + return self.model_dump(exclude={}, exclude_none=True) + + @classmethod + def from_dict(cls, obj: dict) -> ReservedKeywordsRequestParameters: + if obj is None: + return None + return ReservedKeywordsRequestParameters.model_validate(obj) + + +# Request body type (default to Any when no body parameters exist, or leave unchanged as str if it's a primitive type) +ReservedKeywordsRequestBody = Any + +ReservedKeywords200OperationResponse = ApiResponse[Literal[200], None] + +ReservedKeywordsOperationResponses = Union[ReservedKeywords200OperationResponse, ] + +# Request type for reserved_keywords +ReservedKeywordsRequest = ApiRequest[ReservedKeywordsRequestParameters, ReservedKeywordsRequestBody] +ReservedKeywordsChainedRequest = ChainedApiRequest[ReservedKeywordsRequestParameters, ReservedKeywordsRequestBody] + +class ReservedKeywordsHandlerFunction(Protocol): + def __call__(self, input: ReservedKeywordsRequest, **kwargs) -> ReservedKeywordsOperationResponses: + ... + +ReservedKeywordsInterceptor = Callable[[ReservedKeywordsChainedRequest], ReservedKeywordsOperationResponses] + +def reserved_keywords_handler(_handler: ReservedKeywordsHandlerFunction = None, interceptors: List[ReservedKeywordsInterceptor] = []): + """ + Decorator for an api handler for the reserved_keywords operation, providing a typed interface for inputs and outputs + """ + def _handler_wrapper(handler: ReservedKeywordsHandlerFunction): + @wraps(handler) + def wrapper(event, context, additional_interceptors = [], **kwargs): + all_interceptors = additional_interceptors + interceptors + + raw_string_parameters = decode_request_parameters({ + **(event.get('pathParameters', {}) or {}), + **(event.get('queryStringParameters', {}) or {}), + **(event.get('headers', {}) or {}), + }) + raw_string_array_parameters = decode_request_parameters({ + **(event.get('multiValueQueryStringParameters', {}) or {}), + **(event.get('multiValueHeaders', {}) or {}), + }) + + def response_headers_for_status_code(status_code): + headers_for_status = {} + return headers_for_status + + request_parameters = None + try: + request_parameters = ReservedKeywordsRequestParameters.from_dict({ + "var_with": coerce_parameter("with", "str", raw_string_parameters, raw_string_array_parameters, False), "var_if": coerce_parameter("if", "str", raw_string_parameters, raw_string_array_parameters, False), "var_class": coerce_parameter("class", "str", raw_string_parameters, raw_string_array_parameters, False), }) @@ -21218,6 +21774,7 @@ class HandlerRouterHandlers: inline_enum: Callable[[Dict, Any], Dict] inline_request_body: Callable[[Dict, Any], Dict] named_one_of: Callable[[Dict, Any], Dict] + nested_collections: Callable[[Dict, Any], Dict] reserved_keywords: Callable[[Dict, Any], Dict] def handler_router(handlers: HandlerRouterHandlers, interceptors: List[Interceptor] = []): @@ -22790,6 +23347,9 @@ def try_catch_interceptor(request: ChainedApiRequest) -> ApiResponse: from test_project.models.additional_properties_response import AdditionalPropertiesResponse from test_project.models.another_named_one_of import AnotherNamedOneOf from test_project.models.array_of_one_ofs import ArrayOfOneOfs +from test_project.models.cycle_array_node import CycleArrayNode +from test_project.models.cycle_dictionary import CycleDictionary +from test_project.models.cycle_dictionary_node import CycleDictionaryNode from test_project.models.dictionary import Dictionary from test_project.models.inline_enum200_response import InlineEnum200Response from test_project.models.inline_enum200_response_category_enum import InlineEnum200ResponseCategoryEnum @@ -22797,6 +23357,7 @@ from test_project.models.inline_request_body_request_content import InlineReques from test_project.models.my_enum import MyEnum from test_project.models.named_one_of import NamedOneOf from test_project.models.named_one_of_union import NamedOneOfUnion +from test_project.models.nested_collections import NestedCollections from test_project.models.some_object import SomeObject ", "test_project/models/additional_properties_response.py": "# coding: utf-8 @@ -22875,6 +23436,9 @@ class AdditionalPropertiesResponse(BaseModel): # override the default output from pydantic by calling \`to_dict()\` of dictionary_of_objects if self.dictionary_of_objects: _dict['dictionaryOfObjects'] = self.dictionary_of_objects.to_dict() + # override the default output from pydantic by calling \`to_dict()\` of dictionary_of_primitives + if self.dictionary_of_primitives: + _dict['dictionaryOfPrimitives'] = self.dictionary_of_primitives.to_dict() return _dict @classmethod @@ -22889,7 +23453,7 @@ class AdditionalPropertiesResponse(BaseModel): _obj = cls.model_validate({ "dictionaryOfObjects": Dictionary.from_dict(obj.get("dictionaryOfObjects")) if obj.get("dictionaryOfObjects") is not None else None, - "dictionaryOfPrimitives": obj.get("dictionaryOfPrimitives") + "dictionaryOfPrimitives": Dict[str, str].from_dict(obj.get("dictionaryOfPrimitives")) if obj.get("dictionaryOfPrimitives") is not None else None }) return _obj @@ -23016,7 +23580,7 @@ class ArrayOfOneOfs(BaseModel): """ ArrayOfOneOfs """ # noqa: E501 - one_ofs: Optional[List[Any]] = Field(default=None, alias="oneOfs") + one_ofs: Optional[List[any]] = Field(default=None, alias="oneOfs") __properties: ClassVar[List[str]] = ["oneOfs"] @@ -23055,9 +23619,13 @@ class ArrayOfOneOfs(BaseModel): }, exclude_none=True, ) - # override the default output from pydantic by calling \`to_dict()\` of one_ofs + # override the default output from pydantic by calling \`to_dict()\` of each item in one_ofs (list) + _items = [] if self.one_ofs: - _dict['oneOfs'] = self.one_ofs.to_dict() + for _item in self.one_ofs: + if _item: + _items.append(_item.to_dict()) + _dict['oneOfs'] = _items return _dict @classmethod @@ -23071,7 +23639,296 @@ class ArrayOfOneOfs(BaseModel): return cls.model_validate(obj) _obj = cls.model_validate({ - "oneOfs": List[NamedOneOfUnion].from_dict(obj.get("oneOfs")) if obj.get("oneOfs") is not None else None + "oneOfs": [NamedOneOfUnion.from_dict(_item) for _item in obj.get("oneOfs")] if obj.get("oneOfs") is not None else None + }) + return _obj + +", + "test_project/models/cycle_array_node.py": "# coding: utf-8 + +""" + Edge Cases + + No description provided + + The version of the OpenAPI document: 1.0.0 + + NOTE: This class is auto generated. + Do not edit the class manually. +""" # noqa: E501 + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json +from enum import Enum +from datetime import date, datetime +from typing import Any, List, Union, ClassVar, Dict, Optional, TYPE_CHECKING +from pydantic import Field, StrictStr, ValidationError, field_validator, BaseModel, SecretStr, StrictFloat, StrictInt, StrictBytes, StrictBool +from decimal import Decimal +from typing_extensions import Annotated, Literal +try: + from typing import Self +except ImportError: + from typing_extensions import Self + +class CycleArrayNode(BaseModel): + """ + CycleArrayNode + """ # noqa: E501 + nodes: Optional[List[CycleArrayNode]] = None + __properties: ClassVar[List[str]] = ["nodes"] + + + model_config = { + "populate_by_name": True, + "validate_assignment": True + } + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Create an instance of CycleArrayNode from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + \`self.model_dump(by_alias=True)\`: + + * \`None\` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value \`None\` + are ignored. + """ + _dict = self.model_dump( + by_alias=True, + exclude={ + }, + exclude_none=True, + ) + # override the default output from pydantic by calling \`to_dict()\` of each item in nodes (list) + _items = [] + if self.nodes: + for _item in self.nodes: + if _item: + _items.append(_item.to_dict()) + _dict['nodes'] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Dict) -> Self: + """Create an instance of CycleArrayNode from a dict""" + + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "nodes": [CycleArrayNode.from_dict(_item) for _item in obj.get("nodes")] if obj.get("nodes") is not None else None + }) + return _obj + +", + "test_project/models/cycle_dictionary.py": "# coding: utf-8 + +""" + Edge Cases + + No description provided + + The version of the OpenAPI document: 1.0.0 + + NOTE: This class is auto generated. + Do not edit the class manually. +""" # noqa: E501 + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json +from enum import Enum +from datetime import date, datetime +from typing import Any, List, Union, ClassVar, Dict, Optional, TYPE_CHECKING +from pydantic import Field, StrictStr, ValidationError, field_validator, BaseModel, SecretStr, StrictFloat, StrictInt, StrictBytes, StrictBool +from decimal import Decimal +from typing_extensions import Annotated, Literal +try: + from typing import Self +except ImportError: + from typing_extensions import Self + +class CycleDictionary(BaseModel): + """ + CycleDictionary + """ # noqa: E501 + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = [] + + + model_config = { + "populate_by_name": True, + "validate_assignment": True + } + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Create an instance of CycleDictionary from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + \`self.model_dump(by_alias=True)\`: + + * \`None\` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value \`None\` + are ignored. + * Fields in \`self.additional_properties\` are added to the output dict. + """ + _dict = self.model_dump( + by_alias=True, + exclude={ + "additional_properties", + }, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Dict) -> Self: + """Create an instance of CycleDictionary from a dict""" + + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + +", + "test_project/models/cycle_dictionary_node.py": "# coding: utf-8 + +""" + Edge Cases + + No description provided + + The version of the OpenAPI document: 1.0.0 + + NOTE: This class is auto generated. + Do not edit the class manually. +""" # noqa: E501 + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json +from enum import Enum +from datetime import date, datetime +from typing import Any, List, Union, ClassVar, Dict, Optional, TYPE_CHECKING +from pydantic import Field, StrictStr, ValidationError, field_validator, BaseModel, SecretStr, StrictFloat, StrictInt, StrictBytes, StrictBool +from decimal import Decimal +from typing_extensions import Annotated, Literal +from test_project.models.cycle_dictionary import CycleDictionary +try: + from typing import Self +except ImportError: + from typing_extensions import Self + +class CycleDictionaryNode(BaseModel): + """ + CycleDictionaryNode + """ # noqa: E501 + nodes: Optional[CycleDictionary] = None + __properties: ClassVar[List[str]] = ["nodes"] + + + model_config = { + "populate_by_name": True, + "validate_assignment": True + } + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Create an instance of CycleDictionaryNode from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + \`self.model_dump(by_alias=True)\`: + + * \`None\` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value \`None\` + are ignored. + """ + _dict = self.model_dump( + by_alias=True, + exclude={ + }, + exclude_none=True, + ) + # override the default output from pydantic by calling \`to_dict()\` of nodes + if self.nodes: + _dict['nodes'] = self.nodes.to_dict() + return _dict + + @classmethod + def from_dict(cls, obj: Dict) -> Self: + """Create an instance of CycleDictionaryNode from a dict""" + + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "nodes": CycleDictionary.from_dict(obj.get("nodes")) if obj.get("nodes") is not None else None }) return _obj @@ -23683,6 +24540,219 @@ class NamedOneOfUnion(BaseModel): """Returns the string representation of the actual instance""" return pprint.pformat(self.model_dump()) +", + "test_project/models/nested_collections.py": "# coding: utf-8 + +""" + Edge Cases + + No description provided + + The version of the OpenAPI document: 1.0.0 + + NOTE: This class is auto generated. + Do not edit the class manually. +""" # noqa: E501 + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json +from enum import Enum +from datetime import date, datetime +from typing import Any, List, Union, ClassVar, Dict, Optional, TYPE_CHECKING +from pydantic import Field, StrictStr, ValidationError, field_validator, BaseModel, SecretStr, StrictFloat, StrictInt, StrictBytes, StrictBool +from decimal import Decimal +from typing_extensions import Annotated, Literal +from test_project.models.cycle_array_node import CycleArrayNode +from test_project.models.cycle_dictionary import CycleDictionary +from test_project.models.some_object import SomeObject +try: + from typing import Self +except ImportError: + from typing_extensions import Self + +class NestedCollections(BaseModel): + """ + NestedCollections + """ # noqa: E501 + nested_array_of_strings: Optional[List[List[StrictStr]]] = Field(default=None, alias="nestedArrayOfStrings") + nested_array_of_dates: Optional[List[List[date]]] = Field(default=None, alias="nestedArrayOfDates") + nested_array_of_objects: Optional[List[List[SomeObject]]] = Field(default=None, alias="nestedArrayOfObjects") + four_dimensional_nested_array_of_objects: Optional[List[List[List[List[SomeObject]]]]] = Field(default=None, alias="fourDimensionalNestedArrayOfObjects") + nested_dictionary_of_strings: Optional[Dict[str, Dict[str, StrictStr]]] = Field(default=None, alias="nestedDictionaryOfStrings") + nested_dictionary_of_objects: Optional[Dict[str, Dict[str, SomeObject]]] = Field(default=None, alias="nestedDictionaryOfObjects") + four_dimensional_nested_dictionary_of_objects: Optional[Dict[str, Dict[str, Dict[str, Dict[str, SomeObject]]]]] = Field(default=None, alias="fourDimensionalNestedDictionaryOfObjects") + nested_mix_of_dictionaries_and_arrays: Optional[List[Dict[str, List[List[Dict[str, List[SomeObject]]]]]]] = Field(default=None, alias="nestedMixOfDictionariesAndArrays") + cycle_array: Optional[List[CycleArrayNode]] = Field(default=None, alias="cycleArray") + cycle_dictionary: Optional[CycleDictionary] = Field(default=None, alias="cycleDictionary") + __properties: ClassVar[List[str]] = ["nestedArrayOfStrings", "nestedArrayOfDates", "nestedArrayOfObjects", "fourDimensionalNestedArrayOfObjects", "nestedDictionaryOfStrings", "nestedDictionaryOfObjects", "fourDimensionalNestedDictionaryOfObjects", "nestedMixOfDictionariesAndArrays", "cycleArray", "cycleDictionary"] + + + model_config = { + "populate_by_name": True, + "validate_assignment": True + } + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Create an instance of NestedCollections from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + \`self.model_dump(by_alias=True)\`: + + * \`None\` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value \`None\` + are ignored. + """ + _dict = self.model_dump( + by_alias=True, + exclude={ + }, + exclude_none=True, + ) + # override the default output from pydantic by calling \`to_dict()\` of each item in nested_array_of_strings (list) + _items = [] + if self.nested_array_of_strings: + for _item in self.nested_array_of_strings: + if _item: + _items.append(_item.to_dict()) + _dict['nestedArrayOfStrings'] = _items + # override the default output from pydantic by calling \`to_dict()\` of each item in nested_array_of_dates (list) + _items = [] + if self.nested_array_of_dates: + for _item in self.nested_array_of_dates: + if _item: + _items.append(_item.to_dict()) + _dict['nestedArrayOfDates'] = _items + # override the default output from pydantic by calling \`to_dict()\` of each item in nested_array_of_objects (list of list) + _items = [] + if self.nested_array_of_objects: + for _item in self.nested_array_of_objects: + if _item: + _items.append( + [_inner_item.to_dict() for _inner_item in _item if _inner_item is not None] + ) + _dict['nestedArrayOfObjects'] = _items + # override the default output from pydantic by calling \`to_dict()\` of each item in four_dimensional_nested_array_of_objects (list of list) + _items = [] + if self.four_dimensional_nested_array_of_objects: + for _item in self.four_dimensional_nested_array_of_objects: + if _item: + _items.append( + [_inner_item.to_dict() for _inner_item in _item if _inner_item is not None] + ) + _dict['fourDimensionalNestedArrayOfObjects'] = _items + # override the default output from pydantic by calling \`to_dict()\` of each value in nested_dictionary_of_strings (dict) + _field_dict = {} + if self.nested_dictionary_of_strings: + for _key in self.nested_dictionary_of_strings: + if self.nested_dictionary_of_strings[_key]: + _field_dict[_key] = self.nested_dictionary_of_strings[_key].to_dict() + _dict['nestedDictionaryOfStrings'] = _field_dict + # override the default output from pydantic by calling \`to_dict()\` of each value in nested_dictionary_of_objects (dict) + _field_dict = {} + if self.nested_dictionary_of_objects: + for _key in self.nested_dictionary_of_objects: + if self.nested_dictionary_of_objects[_key]: + _field_dict[_key] = self.nested_dictionary_of_objects[_key].to_dict() + _dict['nestedDictionaryOfObjects'] = _field_dict + # override the default output from pydantic by calling \`to_dict()\` of each value in four_dimensional_nested_dictionary_of_objects (dict) + _field_dict = {} + if self.four_dimensional_nested_dictionary_of_objects: + for _key in self.four_dimensional_nested_dictionary_of_objects: + if self.four_dimensional_nested_dictionary_of_objects[_key]: + _field_dict[_key] = self.four_dimensional_nested_dictionary_of_objects[_key].to_dict() + _dict['fourDimensionalNestedDictionaryOfObjects'] = _field_dict + # override the default output from pydantic by calling \`to_dict()\` of each item in nested_mix_of_dictionaries_and_arrays (list) + _items = [] + if self.nested_mix_of_dictionaries_and_arrays: + for _item in self.nested_mix_of_dictionaries_and_arrays: + if _item: + _items.append(_item.to_dict()) + _dict['nestedMixOfDictionariesAndArrays'] = _items + # override the default output from pydantic by calling \`to_dict()\` of each item in cycle_array (list) + _items = [] + if self.cycle_array: + for _item in self.cycle_array: + if _item: + _items.append(_item.to_dict()) + _dict['cycleArray'] = _items + # override the default output from pydantic by calling \`to_dict()\` of cycle_dictionary + if self.cycle_dictionary: + _dict['cycleDictionary'] = self.cycle_dictionary.to_dict() + return _dict + + @classmethod + def from_dict(cls, obj: Dict) -> Self: + """Create an instance of NestedCollections from a dict""" + + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "nestedArrayOfStrings": obj.get("nestedArrayOfStrings"), + "nestedArrayOfDates": obj.get("nestedArrayOfDates"), + "nestedArrayOfObjects": [ + [SomeObject.from_dict(_inner_item) for _inner_item in _item] + for _item in obj.get("nestedArrayOfObjects") + ] if obj.get("nestedArrayOfObjects") is not None else None, + "fourDimensionalNestedArrayOfObjects": [ + [List[List[SomeObject]].from_dict(_inner_item) for _inner_item in _item] + for _item in obj.get("fourDimensionalNestedArrayOfObjects") + ] if obj.get("fourDimensionalNestedArrayOfObjects") is not None else None, + "nestedDictionaryOfStrings": dict( + (_k, Dict[str, str].from_dict(_v)) + for _k, _v in obj.get("nestedDictionaryOfStrings").items() + ) + if obj.get("nestedDictionaryOfStrings") is not None + else None, + "nestedDictionaryOfObjects": dict( + (_k, dict( + (_ik, SomeObject.from_dict(_iv)) + for _ik, _iv in _v.items() + ) + if _v is not None + else None + ) + for _k, _v in obj.get("nestedDictionaryOfObjects").items() + ) + if obj.get("nestedDictionaryOfObjects") is not None + else None, + "fourDimensionalNestedDictionaryOfObjects": dict( + (_k, dict( + (_ik, Dict[str, Dict[str, SomeObject]].from_dict(_iv)) + for _ik, _iv in _v.items() + ) + if _v is not None + else None + ) + for _k, _v in obj.get("fourDimensionalNestedDictionaryOfObjects").items() + ) + if obj.get("fourDimensionalNestedDictionaryOfObjects") is not None + else None, + "nestedMixOfDictionariesAndArrays": [Dict[str, List[List[Dict[str, List[SomeObject]]]]].from_dict(_item) for _item in obj.get("nestedMixOfDictionariesAndArrays")] if obj.get("nestedMixOfDictionariesAndArrays") is not None else None, + "cycleArray": [CycleArrayNode.from_dict(_item) for _item in obj.get("cycleArray")] if obj.get("cycleArray") is not None else None, + "cycleDictionary": CycleDictionary.from_dict(obj.get("cycleDictionary")) if obj.get("cycleDictionary") is not None else None + }) + return _obj + ", "test_project/models/some_object.py": "# coding: utf-8 diff --git a/packages/type-safe-api/test/scripts/generators/__snapshots__/typescript-react-query-hooks.test.ts.snap b/packages/type-safe-api/test/scripts/generators/__snapshots__/typescript-react-query-hooks.test.ts.snap index 9f8d3ebaf..b4108dae7 100644 --- a/packages/type-safe-api/test/scripts/generators/__snapshots__/typescript-react-query-hooks.test.ts.snap +++ b/packages/type-safe-api/test/scripts/generators/__snapshots__/typescript-react-query-hooks.test.ts.snap @@ -1775,7 +1775,7 @@ export function PaginatedGet200ResponseToJSON(value?: PaginatedGet200Response | return { 'outputNextToken': value.outputNextToken, - 'results': value.results, + 'results': value.results === undefined ? undefined : value.results, }; } diff --git a/packages/type-safe-api/test/scripts/generators/__snapshots__/typescript.test.ts.snap b/packages/type-safe-api/test/scripts/generators/__snapshots__/typescript.test.ts.snap index 4d498d4bf..3a27cdd32 100644 --- a/packages/type-safe-api/test/scripts/generators/__snapshots__/typescript.test.ts.snap +++ b/packages/type-safe-api/test/scripts/generators/__snapshots__/typescript.test.ts.snap @@ -5638,7 +5638,7 @@ export function DataTypes200ResponseFromJSONTyped(json: any, ignoreDiscriminator 'myLongMinStringLength': !exists(json, 'myLongMinStringLength') ? undefined : json['myLongMinStringLength'], 'myBool': !exists(json, 'myBool') ? undefined : json['myBool'], 'myNumber': !exists(json, 'myNumber') ? undefined : json['myNumber'], - 'myDateArray': !exists(json, 'myDateArray') ? undefined : json['myDateArray'], + 'myDateArray': !exists(json, 'myDateArray') ? undefined : ((json['myDateArray'] as Array).map((item0) => new Date(item0))), 'myEmail': !exists(json, 'myEmail') ? undefined : json['myEmail'], 'myUrl': !exists(json, 'myUrl') ? undefined : json['myUrl'], 'myHostname': !exists(json, 'myHostname') ? undefined : json['myHostname'], @@ -5675,7 +5675,7 @@ export function DataTypes200ResponseToJSON(value?: DataTypes200Response | null): 'myLongMinStringLength': value.myLongMinStringLength, 'myBool': value.myBool, 'myNumber': value.myNumber, - 'myDateArray': value.myDateArray, + 'myDateArray': value.myDateArray === undefined ? undefined : ((value.myDateArray as Array).map((item0) => item0.toISOString().substr(0,10))), 'myEmail': value.myEmail, 'myUrl': value.myUrl, 'myHostname': value.myHostname, @@ -5691,7 +5691,7 @@ export function DataTypes200ResponseToJSON(value?: DataTypes200Response | null): 'myAllOf': DataTypes200ResponseMyAllOfToJSON(value.myAllOf), 'myNot': value.myNot, 'myNotString': value.myNotString, - 'myAdditionalProperties': value.myAdditionalProperties, + 'myAdditionalProperties': value.myAdditionalProperties === undefined ? undefined : value.myAdditionalProperties, 'myObject': DataTypes200ResponseMyObjectToJSON(value.myObject), }; } @@ -8230,6 +8230,9 @@ src/models/model-utils.ts src/models/AdditionalPropertiesResponse.ts src/models/AnotherNamedOneOf.ts src/models/ArrayOfOneOfs.ts +src/models/CycleArrayNode.ts +src/models/CycleDictionary.ts +src/models/CycleDictionaryNode.ts src/models/Dictionary.ts src/models/InlineEnum200Response.ts src/models/InlineEnum200ResponseCategoryEnum.ts @@ -8237,6 +8240,7 @@ src/models/InlineRequestBodyRequestContent.ts src/models/MyEnum.ts src/models/NamedOneOf.ts src/models/NamedOneOfUnion.ts +src/models/NestedCollections.ts src/models/SomeObject.ts src/runtime.ts src/index.ts @@ -8269,6 +8273,7 @@ import type { InlineRequestBodyRequestContent, MyEnum, NamedOneOfUnion, + NestedCollections, } from '../models'; import { AdditionalPropertiesResponseFromJSON, @@ -8283,6 +8288,8 @@ import { MyEnumToJSON, NamedOneOfUnionFromJSON, NamedOneOfUnionToJSON, + NestedCollectionsFromJSON, + NestedCollectionsToJSON, } from '../models'; @@ -8305,6 +8312,7 @@ export interface InlineRequestBodyRequest { } + export interface ReservedKeywordsRequest { _with?: string; _if?: string; @@ -8525,6 +8533,35 @@ export class DefaultApi extends runtime.BaseAPI { return await response.value(); } + /** + * + */ + async nestedCollectionsRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + + const headerParameters: runtime.HTTPHeaders = {}; + + + + const response = await this.request({ + path: \`/nested-collections\`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => NestedCollectionsFromJSON(jsonValue)); + } + + /** + * + */ + async nestedCollections(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.nestedCollectionsRaw(initOverrides); + return await response.value(); + } + /** * */ @@ -8579,6 +8616,15 @@ import { ArrayOfOneOfs, ArrayOfOneOfsFromJSON, ArrayOfOneOfsToJSON, + CycleArrayNode, + CycleArrayNodeFromJSON, + CycleArrayNodeToJSON, + CycleDictionary, + CycleDictionaryFromJSON, + CycleDictionaryToJSON, + CycleDictionaryNode, + CycleDictionaryNodeFromJSON, + CycleDictionaryNodeToJSON, Dictionary, DictionaryFromJSON, DictionaryToJSON, @@ -8600,6 +8646,9 @@ import { NamedOneOfUnion, NamedOneOfUnionFromJSON, NamedOneOfUnionToJSON, + NestedCollections, + NestedCollectionsFromJSON, + NestedCollectionsToJSON, SomeObject, SomeObjectFromJSON, SomeObjectToJSON, @@ -8622,6 +8671,7 @@ export interface OperationConfig { inlineEnum: T; inlineRequestBody: T; namedOneOf: T; + nestedCollections: T; reservedKeywords: T; } @@ -8657,6 +8707,11 @@ export const OperationLookup = { method: 'POST', contentTypes: ['application/json'], }, + nestedCollections: { + path: '/nested-collections', + method: 'POST', + contentTypes: ['application/json'], + }, reservedKeywords: { path: '/reserved-keywords', method: 'GET', @@ -8778,7 +8833,7 @@ const extractResponseHeadersFromInterceptors = (interceptors: any[]): { [key: st }), {} as { [key: string]: string }); }; -export type OperationIds = | 'arrayOfOneOfs' | 'arrayRequestParameters' | 'dictionary' | 'inlineEnum' | 'inlineRequestBody' | 'namedOneOf' | 'reservedKeywords'; +export type OperationIds = | 'arrayOfOneOfs' | 'arrayRequestParameters' | 'dictionary' | 'inlineEnum' | 'inlineRequestBody' | 'namedOneOf' | 'nestedCollections' | 'reservedKeywords'; export type OperationApiGatewayProxyResult = APIGatewayProxyResult & { __operationId?: T }; // Api gateway lambda handler type @@ -9524,6 +9579,115 @@ export const namedOneOfHandler = ( body: response.body ? marshal(response.statusCode, response.body) : '', }; }; +/** + * Path, Query and Header parameters for NestedCollections + */ +export interface NestedCollectionsRequestParameters { +} + +/** + * Request body parameter for NestedCollections + */ +export type NestedCollectionsRequestBody = never; + +export type NestedCollections200OperationResponse = OperationResponse<200, NestedCollections>; + +export type NestedCollectionsOperationResponses = | NestedCollections200OperationResponse ; + +// Type that the handler function provided to the wrapper must conform to +export type NestedCollectionsHandlerFunction = LambdaHandlerFunction; +export type NestedCollectionsChainedHandlerFunction = ChainedLambdaHandlerFunction; +export type NestedCollectionsChainedRequestInput = ChainedRequestInput; + +/** + * Lambda handler wrapper to provide typed interface for the implementation of nestedCollections + */ +export const nestedCollectionsHandler = ( + ...handlers: [NestedCollectionsChainedHandlerFunction, ...NestedCollectionsChainedHandlerFunction[]] +): OperationApiGatewayLambdaHandler<'nestedCollections'> => async (event: any, context: any, _callback?: any, additionalInterceptors: NestedCollectionsChainedHandlerFunction[] = []): Promise => { + const operationId = "nestedCollections"; + + const rawSingleValueParameters = decodeRequestParameters({ + ...(event.pathParameters || {}), + ...(event.queryStringParameters || {}), + ...(event.headers || {}), + }) as { [key: string]: string | undefined }; + const rawMultiValueParameters = decodeRequestParameters({ + ...(event.multiValueQueryStringParameters || {}), + ...(event.multiValueHeaders || {}), + }) as { [key: string]: string[] | undefined }; + + const marshal = (statusCode: number, responseBody: any): string => { + let marshalledBody = responseBody; + switch(statusCode) { + case 200: + marshalledBody = JSON.stringify(NestedCollectionsToJSON(marshalledBody)); + break; + default: + break; + } + + return marshalledBody; + }; + + const errorHeaders = (statusCode: number): { [key: string]: string } => { + let headers = {}; + + switch(statusCode) { + default: + break; + } + + return headers; + }; + + let requestParameters: NestedCollectionsRequestParameters | undefined = undefined; + + try { + requestParameters = { + + }; + } catch (e: any) { + const res = { + statusCode: 400, + body: { message: e.message }, + headers: extractResponseHeadersFromInterceptors(handlers), + }; + return { + ...res, + headers: { + ...errorHeaders(res.statusCode), + ...res.headers, + }, + body: res.body ? marshal(res.statusCode, res.body) : '', + }; + } + + const demarshal = (bodyString: string): any => { + return {}; + }; + const body = parseBody(event.body, demarshal, ['application/json']) as NestedCollectionsRequestBody; + + const chain = buildHandlerChain(...additionalInterceptors, ...handlers); + const response = await chain.next({ + input: { + requestParameters, + body, + }, + event, + context, + interceptorContext: { operationId }, + }); + + return { + ...response, + headers: { + ...errorHeaders(response.statusCode), + ...response.headers, + }, + body: response.body ? marshal(response.statusCode, response.body) : '', + }; +}; /** * Path, Query and Header parameters for ReservedKeywords */ @@ -9646,12 +9810,13 @@ export interface HandlerRouterHandlers { readonly inlineEnum: OperationApiGatewayLambdaHandler<'inlineEnum'>; readonly inlineRequestBody: OperationApiGatewayLambdaHandler<'inlineRequestBody'>; readonly namedOneOf: OperationApiGatewayLambdaHandler<'namedOneOf'>; + readonly nestedCollections: OperationApiGatewayLambdaHandler<'nestedCollections'>; readonly reservedKeywords: OperationApiGatewayLambdaHandler<'reservedKeywords'>; } -export type AnyOperationRequestParameters = | ArrayOfOneOfsRequestParameters| ArrayRequestParametersRequestParameters| DictionaryRequestParameters| InlineEnumRequestParameters| InlineRequestBodyRequestParameters| NamedOneOfRequestParameters| ReservedKeywordsRequestParameters; -export type AnyOperationRequestBodies = | ArrayOfOneOfsRequestBody| ArrayRequestParametersRequestBody| DictionaryRequestBody| InlineEnumRequestBody| InlineRequestBodyRequestBody| NamedOneOfRequestBody| ReservedKeywordsRequestBody; -export type AnyOperationResponses = | ArrayOfOneOfsOperationResponses| ArrayRequestParametersOperationResponses| DictionaryOperationResponses| InlineEnumOperationResponses| InlineRequestBodyOperationResponses| NamedOneOfOperationResponses| ReservedKeywordsOperationResponses; +export type AnyOperationRequestParameters = | ArrayOfOneOfsRequestParameters| ArrayRequestParametersRequestParameters| DictionaryRequestParameters| InlineEnumRequestParameters| InlineRequestBodyRequestParameters| NamedOneOfRequestParameters| NestedCollectionsRequestParameters| ReservedKeywordsRequestParameters; +export type AnyOperationRequestBodies = | ArrayOfOneOfsRequestBody| ArrayRequestParametersRequestBody| DictionaryRequestBody| InlineEnumRequestBody| InlineRequestBodyRequestBody| NamedOneOfRequestBody| NestedCollectionsRequestBody| ReservedKeywordsRequestBody; +export type AnyOperationResponses = | ArrayOfOneOfsOperationResponses| ArrayRequestParametersOperationResponses| DictionaryOperationResponses| InlineEnumOperationResponses| InlineRequestBodyOperationResponses| NamedOneOfOperationResponses| NestedCollectionsOperationResponses| ReservedKeywordsOperationResponses; export interface HandlerRouterProps< RequestParameters, @@ -10071,7 +10236,7 @@ export function AdditionalPropertiesResponseToJSON(value?: AdditionalPropertiesR return { 'dictionaryOfObjects': DictionaryToJSON(value.dictionaryOfObjects), - 'dictionaryOfPrimitives': value.dictionaryOfPrimitives, + 'dictionaryOfPrimitives': value.dictionaryOfPrimitives === undefined ? undefined : value.dictionaryOfPrimitives, }; } @@ -10212,6 +10377,195 @@ export function ArrayOfOneOfsToJSON(value?: ArrayOfOneOfs | null): any { }; } +", + "src/models/CycleArrayNode.ts": "/* tslint:disable */ +/* eslint-disable */ +/** + * Edge Cases + * + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated. + * Do not edit the class manually. + */ +import { exists, mapValues } from './model-utils'; + +/** + * + * @export + * @interface CycleArrayNode + */ +export interface CycleArrayNode { + /** + * + * @type {Array} + * @memberof CycleArrayNode + */ + nodes?: Array; +} + + +/** + * Check if a given object implements the CycleArrayNode interface. + */ +export function instanceOfCycleArrayNode(value: object): boolean { + let isInstance = true; + return isInstance; +} + +export function CycleArrayNodeFromJSON(json: any): CycleArrayNode { + return CycleArrayNodeFromJSONTyped(json, false); +} + +export function CycleArrayNodeFromJSONTyped(json: any, ignoreDiscriminator: boolean): CycleArrayNode { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'nodes': !exists(json, 'nodes') ? undefined : ((json['nodes'] as Array).map(CycleArrayNodeFromJSON)), + }; +} + +export function CycleArrayNodeToJSON(value?: CycleArrayNode | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'nodes': value.nodes === undefined ? undefined : ((value.nodes as Array).map(CycleArrayNodeToJSON)), + }; +} + +", + "src/models/CycleDictionary.ts": "/* tslint:disable */ +/* eslint-disable */ +/** + * Edge Cases + * + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated. + * Do not edit the class manually. + */ +import { exists, mapValues } from './model-utils'; +import type { CycleDictionaryNode } from './CycleDictionaryNode'; +import { + CycleDictionaryNodeFromJSON, + CycleDictionaryNodeFromJSONTyped, + CycleDictionaryNodeToJSON, + instanceOfCycleDictionaryNode, +} from './CycleDictionaryNode'; + +/** + * + * @export + * @interface CycleDictionary + */ +export interface CycleDictionary { + [key: string]: CycleDictionaryNode; +} + + +/** + * Check if a given object implements the CycleDictionary interface. + */ +export function instanceOfCycleDictionary(value: object): boolean { + let isInstance = true; + return isInstance; +} + +export function CycleDictionaryFromJSON(json: any): CycleDictionary { + return CycleDictionaryFromJSONTyped(json, false); +} + +export function CycleDictionaryFromJSONTyped(json: any, ignoreDiscriminator: boolean): CycleDictionary { + return json; +} + +export function CycleDictionaryToJSON(value?: CycleDictionary | null): any { + return value; +} + +", + "src/models/CycleDictionaryNode.ts": "/* tslint:disable */ +/* eslint-disable */ +/** + * Edge Cases + * + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated. + * Do not edit the class manually. + */ +import { exists, mapValues } from './model-utils'; +import type { CycleDictionary } from './CycleDictionary'; +import { + CycleDictionaryFromJSON, + CycleDictionaryFromJSONTyped, + CycleDictionaryToJSON, + instanceOfCycleDictionary, +} from './CycleDictionary'; + +/** + * + * @export + * @interface CycleDictionaryNode + */ +export interface CycleDictionaryNode { + /** + * + * @type {CycleDictionary} + * @memberof CycleDictionaryNode + */ + nodes?: CycleDictionary; +} + + +/** + * Check if a given object implements the CycleDictionaryNode interface. + */ +export function instanceOfCycleDictionaryNode(value: object): boolean { + let isInstance = true; + return isInstance; +} + +export function CycleDictionaryNodeFromJSON(json: any): CycleDictionaryNode { + return CycleDictionaryNodeFromJSONTyped(json, false); +} + +export function CycleDictionaryNodeFromJSONTyped(json: any, ignoreDiscriminator: boolean): CycleDictionaryNode { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'nodes': !exists(json, 'nodes') ? undefined : CycleDictionaryFromJSON(json['nodes']), + }; +} + +export function CycleDictionaryNodeToJSON(value?: CycleDictionaryNode | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'nodes': CycleDictionaryToJSON(value.nodes), + }; +} + ", "src/models/Dictionary.ts": "/* tslint:disable */ /* eslint-disable */ @@ -10616,6 +10970,164 @@ export function NamedOneOfUnionToJSON(value?: NamedOneOfUnion | null): any { }; } +", + "src/models/NestedCollections.ts": "/* tslint:disable */ +/* eslint-disable */ +/** + * Edge Cases + * + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated. + * Do not edit the class manually. + */ +import { exists, mapValues } from './model-utils'; +import type { CycleArrayNode } from './CycleArrayNode'; +import { + CycleArrayNodeFromJSON, + CycleArrayNodeFromJSONTyped, + CycleArrayNodeToJSON, + instanceOfCycleArrayNode, +} from './CycleArrayNode'; +import type { CycleDictionary } from './CycleDictionary'; +import { + CycleDictionaryFromJSON, + CycleDictionaryFromJSONTyped, + CycleDictionaryToJSON, + instanceOfCycleDictionary, +} from './CycleDictionary'; +import type { SomeObject } from './SomeObject'; +import { + SomeObjectFromJSON, + SomeObjectFromJSONTyped, + SomeObjectToJSON, + instanceOfSomeObject, +} from './SomeObject'; + +/** + * + * @export + * @interface NestedCollections + */ +export interface NestedCollections { + /** + * + * @type {Array>} + * @memberof NestedCollections + */ + nestedArrayOfStrings?: Array>; + /** + * + * @type {Array>} + * @memberof NestedCollections + */ + nestedArrayOfDates?: Array>; + /** + * + * @type {Array>} + * @memberof NestedCollections + */ + nestedArrayOfObjects?: Array>; + /** + * + * @type {Array>>>} + * @memberof NestedCollections + */ + fourDimensionalNestedArrayOfObjects?: Array>>>; + /** + * + * @type {{ [key: string]: { [key: string]: string; }; }} + * @memberof NestedCollections + */ + nestedDictionaryOfStrings?: { [key: string]: { [key: string]: string; }; }; + /** + * + * @type {{ [key: string]: { [key: string]: SomeObject; }; }} + * @memberof NestedCollections + */ + nestedDictionaryOfObjects?: { [key: string]: { [key: string]: SomeObject; }; }; + /** + * + * @type {{ [key: string]: { [key: string]: { [key: string]: { [key: string]: SomeObject; }; }; }; }} + * @memberof NestedCollections + */ + fourDimensionalNestedDictionaryOfObjects?: { [key: string]: { [key: string]: { [key: string]: { [key: string]: SomeObject; }; }; }; }; + /** + * + * @type {Array<{ [key: string]: Array; }>>; }>} + * @memberof NestedCollections + */ + nestedMixOfDictionariesAndArrays?: Array<{ [key: string]: Array; }>>; }>; + /** + * + * @type {Array} + * @memberof NestedCollections + */ + cycleArray?: Array; + /** + * + * @type {CycleDictionary} + * @memberof NestedCollections + */ + cycleDictionary?: CycleDictionary; +} + + +/** + * Check if a given object implements the NestedCollections interface. + */ +export function instanceOfNestedCollections(value: object): boolean { + let isInstance = true; + return isInstance; +} + +export function NestedCollectionsFromJSON(json: any): NestedCollections { + return NestedCollectionsFromJSONTyped(json, false); +} + +export function NestedCollectionsFromJSONTyped(json: any, ignoreDiscriminator: boolean): NestedCollections { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'nestedArrayOfStrings': !exists(json, 'nestedArrayOfStrings') ? undefined : json['nestedArrayOfStrings'], + 'nestedArrayOfDates': !exists(json, 'nestedArrayOfDates') ? undefined : ((json['nestedArrayOfDates'] as Array).map((item0) => item0.map((item1) => new Date(item1)))), + 'nestedArrayOfObjects': !exists(json, 'nestedArrayOfObjects') ? undefined : ((json['nestedArrayOfObjects'] as Array).map((item0) => item0.map(SomeObjectFromJSON))), + 'fourDimensionalNestedArrayOfObjects': !exists(json, 'fourDimensionalNestedArrayOfObjects') ? undefined : ((json['fourDimensionalNestedArrayOfObjects'] as Array).map((item0) => item0.map((item1) => item1.map((item2) => item2.map(SomeObjectFromJSON))))), + 'nestedDictionaryOfStrings': !exists(json, 'nestedDictionaryOfStrings') ? undefined : json['nestedDictionaryOfStrings'], + 'nestedDictionaryOfObjects': !exists(json, 'nestedDictionaryOfObjects') ? undefined : (mapValues(json['nestedDictionaryOfObjects'], (item0) => mapValues(item0, SomeObjectFromJSON))), + 'fourDimensionalNestedDictionaryOfObjects': !exists(json, 'fourDimensionalNestedDictionaryOfObjects') ? undefined : (mapValues(json['fourDimensionalNestedDictionaryOfObjects'], (item0) => mapValues(item0, (item1) => mapValues(item1, (item2) => mapValues(item2, SomeObjectFromJSON))))), + 'nestedMixOfDictionariesAndArrays': !exists(json, 'nestedMixOfDictionariesAndArrays') ? undefined : ((json['nestedMixOfDictionariesAndArrays'] as Array).map((item0) => mapValues(item0, (item1) => item1.map((item2) => item2.map((item3) => mapValues(item3, (item4) => item4.map(SomeObjectFromJSON))))))), + 'cycleArray': !exists(json, 'cycleArray') ? undefined : ((json['cycleArray'] as Array).map(CycleArrayNodeFromJSON)), + 'cycleDictionary': !exists(json, 'cycleDictionary') ? undefined : CycleDictionaryFromJSON(json['cycleDictionary']), + }; +} + +export function NestedCollectionsToJSON(value?: NestedCollections | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'nestedArrayOfStrings': value.nestedArrayOfStrings === undefined ? undefined : value.nestedArrayOfStrings, + 'nestedArrayOfDates': value.nestedArrayOfDates === undefined ? undefined : ((value.nestedArrayOfDates as Array).map((item0) => item0.map((item1) => item1.toISOString().substr(0,10)))), + 'nestedArrayOfObjects': value.nestedArrayOfObjects === undefined ? undefined : ((value.nestedArrayOfObjects as Array).map((item0) => item0.map(SomeObjectToJSON))), + 'fourDimensionalNestedArrayOfObjects': value.fourDimensionalNestedArrayOfObjects === undefined ? undefined : ((value.fourDimensionalNestedArrayOfObjects as Array).map((item0) => item0.map((item1) => item1.map((item2) => item2.map(SomeObjectToJSON))))), + 'nestedDictionaryOfStrings': value.nestedDictionaryOfStrings === undefined ? undefined : value.nestedDictionaryOfStrings, + 'nestedDictionaryOfObjects': value.nestedDictionaryOfObjects === undefined ? undefined : (mapValues(value.nestedDictionaryOfObjects, (item0) => mapValues(item0, SomeObjectToJSON))), + 'fourDimensionalNestedDictionaryOfObjects': value.fourDimensionalNestedDictionaryOfObjects === undefined ? undefined : (mapValues(value.fourDimensionalNestedDictionaryOfObjects, (item0) => mapValues(item0, (item1) => mapValues(item1, (item2) => mapValues(item2, SomeObjectToJSON))))), + 'nestedMixOfDictionariesAndArrays': value.nestedMixOfDictionariesAndArrays === undefined ? undefined : ((value.nestedMixOfDictionariesAndArrays as Array).map((item0) => mapValues(item0, (item1) => item1.map((item2) => item2.map((item3) => mapValues(item3, (item4) => item4.map(SomeObjectToJSON))))))), + 'cycleArray': value.cycleArray === undefined ? undefined : ((value.cycleArray as Array).map(CycleArrayNodeToJSON)), + 'cycleDictionary': CycleDictionaryToJSON(value.cycleDictionary), + }; +} + ", "src/models/SomeObject.ts": "/* tslint:disable */ /* eslint-disable */ @@ -10687,6 +11199,9 @@ export function SomeObjectToJSON(value?: SomeObject | null): any { export * from './AdditionalPropertiesResponse'; export * from './AnotherNamedOneOf'; export * from './ArrayOfOneOfs'; +export * from './CycleArrayNode'; +export * from './CycleDictionary'; +export * from './CycleDictionaryNode'; export * from './Dictionary'; export * from './InlineEnum200Response'; export * from './InlineEnum200ResponseCategoryEnum'; @@ -10694,6 +11209,7 @@ export * from './InlineRequestBodyRequestContent'; export * from './MyEnum'; export * from './NamedOneOf'; export * from './NamedOneOfUnion'; +export * from './NestedCollections'; export * from './SomeObject'; ", "src/models/model-utils.ts": "/* tslint:disable */