diff --git a/bin/configs/typescript-fetch-any-of-union.yaml b/bin/configs/typescript-fetch-any-of-union.yaml new file mode 100644 index 000000000000..829ea38dbe82 --- /dev/null +++ b/bin/configs/typescript-fetch-any-of-union.yaml @@ -0,0 +1,9 @@ +generatorName: typescript-fetch +outputDir: samples/client/petstore/typescript-fetch/builds/any-of-union +inputSpec: modules/openapi-generator/src/test/resources/3_0/typescript-fetch/anyOf.yaml +templateDir: modules/openapi-generator/src/main/resources/typescript-fetch +additionalProperties: + generateAnyOfAsUnion: true + npmVersion: 1.0.0 + npmName: '@openapitools/typescript-fetch-petstore' + npmRepository: https://skimdb.npmjs.com/registry diff --git a/docs/generators/typescript-fetch.md b/docs/generators/typescript-fetch.md index 543e13061808..2dfc95b2f26d 100644 --- a/docs/generators/typescript-fetch.md +++ b/docs/generators/typescript-fetch.md @@ -27,6 +27,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |enumPropertyNamingReplaceSpecialChar|Set to true to replace '-' and '+' symbols with 'minus_' and 'plus_' in enum of type string| |false| |enumUnknownDefaultCase|If the server adds new enum cases, that are unknown by an old spec/client, the client will fail to parse the network response. With this option enabled, each enum will have a new case, 'unknown_default_open_api', so that when the server sends an enum case that is not known by the client/spec, they can safely fallback to this case.|
**false**
No changes to the enums are made, this is the default option.
**true**
With this option enabled, each enum will have a new case, 'unknown_default_open_api', so that when the enum case sent by the server is not known by the client/spec, can safely be decoded to this case.
|false| |fileNaming|Naming convention for the output files: 'PascalCase', 'camelCase', 'kebab-case'.| |PascalCase| +|generateAnyOfAsUnion|Generate anyOf schemas as TypeScript union types instead of one interface merging all members' properties. A value matching several object members keeps the properties of all of them. An anyOf schema that also declares its own properties stays an interface.| |false| |importFileExtension|File extension to use with relative imports. Set it to '.js' or '.mjs' when using [ESM](https://nodejs.org/api/esm.html).| || |legacyDiscriminatorBehavior|Set to false for generators with better support for discriminators. (Python, Java, Go, PowerShell, C# have this enabled by default).|
**true**
The mapping in the discriminator includes descendent schemas that allOf inherit from self and the discriminator mapping schemas in the OAS document.
**false**
The mapping in the discriminator includes any descendent schemas that allOf inherit from self, any oneOf schemas, any anyOf schemas, any x-discriminator-values, and the discriminator mapping schemas in the OAS document AND Codegen validates that oneOf and anyOf schemas contain the required discriminator and throws an error if the discriminator is missing.
|true| |licenseName|The name of the license| |null| diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptFetchClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptFetchClientCodegen.java index 91991d569d74..bf6cc375765a 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptFetchClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptFetchClientCodegen.java @@ -73,6 +73,8 @@ public class TypeScriptFetchClientCodegen extends AbstractTypeScriptClientCodege public static final String DATE_LIBRARY_DATE = "date"; public static final String DATE_LIBRARY_STRING = "string"; public static final String DATE_LIBRARY_TEMPORAL = "temporal"; + public static final String GENERATE_ANY_OF_AS_UNION = "generateAnyOfAsUnion"; + public static final String GENERATE_ANY_OF_AS_UNION_DESC = "Generate anyOf schemas as TypeScript union types instead of one interface merging all members' properties. A value matching several object members keeps the properties of all of them. An anyOf schema that also declares its own properties stays an interface."; public static final String STRING_ENUMS = "stringEnums"; public static final String STRING_ENUMS_DESC = "Generate string enums instead of objects for enum values."; public static final String IMPORT_FILE_EXTENSION_SWITCH = "importFileExtension"; @@ -96,6 +98,7 @@ public class TypeScriptFetchClientCodegen extends AbstractTypeScriptClientCodege protected boolean addedModelIndex = false; protected boolean withoutRuntimeChecks = false; protected String dateLibrary = DATE_LIBRARY_DATE; + protected boolean generateAnyOfAsUnion = false; protected boolean stringEnums = false; protected String fileNaming = PASCAL_CASE; protected String apiDocPath = "docs"; @@ -171,6 +174,7 @@ public TypeScriptFetchClientCodegen() { dateLibraryOption.setEnum(dateOptions); this.cliOptions.add(dateLibraryOption); this.cliOptions.add(new CliOption(SAGAS_AND_RECORDS, "Setting this property to true will generate additional files for use with redux-saga and immutablejs.", SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.FALSE.toString())); + this.cliOptions.add(new CliOption(GENERATE_ANY_OF_AS_UNION, GENERATE_ANY_OF_AS_UNION_DESC, SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.FALSE.toString())); this.cliOptions.add(new CliOption(STRING_ENUMS, STRING_ENUMS_DESC, SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.FALSE.toString())); this.cliOptions.add(new CliOption(IMPORT_FILE_EXTENSION_SWITCH, IMPORT_FILE_EXTENSION_SWITCH_DESC).defaultValue("")); this.cliOptions.add(new CliOption(FILE_NAMING, "Naming convention for the output files: 'PascalCase', 'camelCase', 'kebab-case'.").defaultValue(this.fileNaming)); @@ -236,6 +240,14 @@ public void setDateLibrary(String dateLibrary) { this.dateLibrary = dateLibrary; } + public Boolean getGenerateAnyOfAsUnion() { + return this.generateAnyOfAsUnion; + } + + public void setGenerateAnyOfAsUnion(Boolean generateAnyOfAsUnion) { + this.generateAnyOfAsUnion = generateAnyOfAsUnion; + } + public Boolean getStringEnums() { return this.stringEnums; } @@ -344,6 +356,10 @@ public void processOpts() { this.setWithoutRuntimeChecks(convertPropertyToBoolean(WITHOUT_RUNTIME_CHECKS)); } + if (additionalProperties.containsKey(GENERATE_ANY_OF_AS_UNION)) { + this.setGenerateAnyOfAsUnion(convertPropertyToBoolean(GENERATE_ANY_OF_AS_UNION)); + } + if (additionalProperties.containsKey(STRING_ENUMS)) { this.setStringEnums(convertPropertyToBoolean(STRING_ENUMS)); additionalProperties.put("stringEnums", this.stringEnums); @@ -604,6 +620,22 @@ public Map postProcessAllModels(Map objs) } } + // Split the oneOf/anyOf model members: the instanceOf check of an enum takes the primitive value itself, + // while the one of an object model needs an object. + Set enumModelNames = allModels.stream() + .filter(m -> m.isEnum) + .map(m -> m.classname) + .collect(Collectors.toSet()); + for (ExtendedCodegenModel m : allModels) { + for (String member : m.oneOfModels) { + if (enumModelNames.contains(member)) { + m.oneOfEnumModels.add(member); + } else { + m.oneOfObjectModels.add(member); + } + } + } + for (ExtendedCodegenModel rootModel : allModels) { for (String curImport : rootModel.imports) { boolean isModelImport = false; @@ -834,7 +866,11 @@ public ExtendedCodegenProperty fromProperty(String name, Schema p, boolean requi @Override public ExtendedCodegenModel fromModel(String name, Schema model) { CodegenModel cm = super.fromModel(name, model); - return new ExtendedCodegenModel(cm); + ExtendedCodegenModel result = new ExtendedCodegenModel(cm); + // The union template renders no properties, so an anyOf declaring its own properties stays an interface. + result.anyOfHasOwnProperties = model.getAnyOf() != null && !model.getAnyOf().isEmpty() + && model.getProperties() != null && !model.getProperties().isEmpty(); + return result; } @Override @@ -1081,8 +1117,20 @@ private ExtendedCodegenModel processCodeGenModel(ExtendedCodegenModel cm) { .map(CodegenComposedSchemas::getOneOf) .orElse(Collections.emptyList()); - // Type names omit branch nullability. Null is valid only when exactly one branch accepts it. - if (oneOfsList.stream().filter(cp -> cp.isNullable).count() == 1) { + // With generateAnyOfAsUnion an anyOf is modeled like a oneOf, so the oneOf templates render it as a union. + boolean fromAnyOf = this.generateAnyOfAsUnion && cm.oneOf.isEmpty() && !cm.anyOf.isEmpty() && !cm.anyOfHasOwnProperties; + if (fromAnyOf) { + oneOfsList = Optional.ofNullable(cm.getComposedSchemas()) + .map(CodegenComposedSchemas::getAnyOf) + .orElse(Collections.emptyList()); + cm.oneOf.addAll(cm.anyOf); + cm.isAnyOfUnion = true; + } + + // Type names omit branch nullability. For oneOf, null is valid only when exactly one branch accepts it; + // for anyOf, when at least one branch does. + long nullableBranches = oneOfsList.stream().filter(cp -> cp.isNullable).count(); + if (fromAnyOf ? nullableBranches >= 1 : nullableBranches == 1) { cm.oneOf.add("null"); } @@ -2107,6 +2155,9 @@ public class ExtendedCodegenModel extends CodegenModel { // 'TypedJSON' conversion methods in the composed model classes. @Getter @Setter public Set oneOfModels = new TreeSet<>(); + // oneOfModels split by kind, see postProcessAllModels + public Set oneOfObjectModels = new TreeSet<>(); + public Set oneOfEnumModels = new TreeSet<>(); @Getter @Setter public Set oneOfArrays = new TreeSet<>(); @Getter @Setter @@ -2115,6 +2166,9 @@ public class ExtendedCodegenModel extends CodegenModel { public CodegenDiscriminator.MappedModel selfReferencingDiscriminatorMapping; @Getter @Setter public boolean parentIsOneOf; // true when this model's parent is a oneOf union type + @Getter @Setter + public boolean isAnyOfUnion; // true when an anyOf is generated as a union type (generateAnyOfAsUnion) + public boolean anyOfHasOwnProperties; // true when an anyOf schema declares properties next to its members public boolean isEntity; // Is a model containing an "id" property marked as isUniqueId public String returnPassthrough; diff --git a/modules/openapi-generator/src/main/resources/typescript-fetch/modelOneOf.mustache b/modules/openapi-generator/src/main/resources/typescript-fetch/modelOneOf.mustache index 62f9f104f7bf..717284d6d040 100644 --- a/modules/openapi-generator/src/main/resources/typescript-fetch/modelOneOf.mustache +++ b/modules/openapi-generator/src/main/resources/typescript-fetch/modelOneOf.mustache @@ -44,20 +44,44 @@ export function {{classname}}FromJSONTyped(json: any, ignoreDiscriminator: boole } {{/discriminator}} {{^discriminator}} - {{#oneOfModels}} + {{#oneOfObjectModels}} {{#-first}} - if (typeof json !== 'object') { - return json; - } + if (typeof json === 'object') { + {{#isAnyOfUnion}} + // anyOf: a value may match several members, so combine all of them instead of keeping the first match + let anyOfResult: any = {}; + let anyOfMatched = false; + {{/isAnyOfUnion}} {{/-first}} + {{#isAnyOfUnion}} + if (instanceOf{{{.}}}(json)) { + anyOfResult = { ...anyOfResult, ...{{{.}}}FromJSONTyped(json, true) }; + anyOfMatched = true; + } + {{/isAnyOfUnion}} + {{^isAnyOfUnion}} + if (instanceOf{{{.}}}(json)) { + return {{{.}}}FromJSONTyped(json, true); + } + {{/isAnyOfUnion}} + {{#-last}} + {{#isAnyOfUnion}} + if (anyOfMatched) { + return anyOfResult; + } + {{/isAnyOfUnion}} + } + {{/-last}} + {{/oneOfObjectModels}} + {{#oneOfEnumModels}} if (instanceOf{{{.}}}(json)) { return {{{.}}}FromJSONTyped(json, true); } - {{/oneOfModels}} + {{/oneOfEnumModels}} {{#oneOfArrays}} {{#-first}} if (Array.isArray(json)) { - if (json.every(item => typeof item === 'object')) { + if (json.every(item => item !== null && typeof item === 'object')) { {{/-first}} if (json.every(item => instanceOf{{{.}}}(item))) { return json.map(value => {{{.}}}FromJSONTyped(value, true)); @@ -197,20 +221,44 @@ export function {{classname}}ToJSONTyped(value?: {{classname}} | null, ignoreDis } {{/discriminator}} {{^discriminator}} - {{#oneOfModels}} + {{#oneOfObjectModels}} {{#-first}} - if (typeof value !== 'object') { - return value; - } + if (typeof value === 'object') { + {{#isAnyOfUnion}} + // anyOf: a value may match several members, so combine all of them instead of keeping the first match + let anyOfResult: any = {}; + let anyOfMatched = false; + {{/isAnyOfUnion}} {{/-first}} + {{#isAnyOfUnion}} + if (instanceOf{{{.}}}(value)) { + anyOfResult = { ...anyOfResult, ...{{{.}}}ToJSON(value as {{{.}}}) }; + anyOfMatched = true; + } + {{/isAnyOfUnion}} + {{^isAnyOfUnion}} + if (instanceOf{{{.}}}(value)) { + return {{{.}}}ToJSON(value as {{{.}}}); + } + {{/isAnyOfUnion}} + {{#-last}} + {{#isAnyOfUnion}} + if (anyOfMatched) { + return anyOfResult; + } + {{/isAnyOfUnion}} + } + {{/-last}} + {{/oneOfObjectModels}} + {{#oneOfEnumModels}} if (instanceOf{{{.}}}(value)) { return {{{.}}}ToJSON(value as {{{.}}}); } - {{/oneOfModels}} + {{/oneOfEnumModels}} {{#oneOfArrays}} {{#-first}} if (Array.isArray(value)) { - if (value.every(item => typeof item === 'object')) { + if (value.every(item => item !== null && typeof item === 'object')) { {{/-first}} if (value.every(item => instanceOf{{{.}}}(item))) { return value.map(value => {{{.}}}ToJSON(value as {{{.}}})); diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/TypeScriptFetchClientOptionsProvider.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/TypeScriptFetchClientOptionsProvider.java index 9b35b5074d35..efbeac0c2b23 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/TypeScriptFetchClientOptionsProvider.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/TypeScriptFetchClientOptionsProvider.java @@ -30,6 +30,7 @@ public class TypeScriptFetchClientOptionsProvider implements TypeScriptSharedCli private static final String NPM_REPOSITORY = "https://registry.npmjs.org"; public static final String SAGAS_AND_RECORDS = "false"; public static final String STRING_ENUMS = "false"; + public static final String GENERATE_ANY_OF_AS_UNION = "false"; public static final String FILE_NAMING_VALUE = PASCAL_CASE; public static final String DATE_LIBRARY_VALUE = TypeScriptFetchClientCodegen.DATE_LIBRARY_STRING; @@ -53,6 +54,7 @@ public Map createOptions() { .put(TypeScriptFetchClientCodegen.FILE_NAMING, FILE_NAMING_VALUE) .put(TypeScriptFetchClientCodegen.DATE_LIBRARY, DATE_LIBRARY_VALUE) .put(TypeScriptFetchClientCodegen.STRING_ENUMS, STRING_ENUMS) + .put(TypeScriptFetchClientCodegen.GENERATE_ANY_OF_AS_UNION, GENERATE_ANY_OF_AS_UNION) .put(TypeScriptFetchClientCodegen.USE_SQUARE_BRACKETS_IN_ARRAY_NAMES, Boolean.FALSE.toString()) .put(TypeScriptFetchClientCodegen.VALIDATION_ATTRIBUTES, Boolean.FALSE.toString()) .put(TypeScriptFetchClientCodegen.WITH_REQUEST_OPTS_IN_INTERFACE, Boolean.TRUE.toString()) diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/fetch/TypeScriptFetchClientCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/fetch/TypeScriptFetchClientCodegenTest.java index b9ad0d49bf0c..b980b9110f22 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/fetch/TypeScriptFetchClientCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/fetch/TypeScriptFetchClientCodegenTest.java @@ -28,6 +28,7 @@ import java.nio.file.Paths; import java.util.HashMap; import java.util.List; +import java.util.function.Function; import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; @@ -799,7 +800,7 @@ public void givenSchemaIsOneOfAndComposedSchemasArePrimitiveThenReturnStatements Path exampleModelPath = Paths.get(outputPath + "/models/MyCustomSpeed.ts"); //FromJSON - TestUtils.assertFileContains(exampleModelPath, "(typeof json !== 'object')"); + TestUtils.assertFileContains(exampleModelPath, "(typeof json === 'object')"); TestUtils.assertFileContains(exampleModelPath, "(instanceOfMyNumericValue(json))"); TestUtils.assertFileContains(exampleModelPath, "(typeof json === 'number' && (json === 10 || json === 20 || json === 30))"); TestUtils.assertFileContains(exampleModelPath, "(typeof json === 'string' && (json === 'fixed-value-a' || json === 'fixed-value-b' || json === 'fixed-value-c'))"); @@ -807,7 +808,7 @@ public void givenSchemaIsOneOfAndComposedSchemasArePrimitiveThenReturnStatements TestUtils.assertFileContains(exampleModelPath, "(json.every(item => typeof item === 'number'))"); TestUtils.assertFileContains(exampleModelPath, "(json.every(item => typeof item === 'string' && (item === 'oneof-array-enum-a' || item === 'oneof-array-enum-b' || item === 'oneof-array-enum-c')))"); //ToJSON - TestUtils.assertFileContains(exampleModelPath, "(typeof value !== 'object')"); + TestUtils.assertFileContains(exampleModelPath, "(typeof value === 'object')"); TestUtils.assertFileContains(exampleModelPath, "(instanceOfMyNumericValue(value))"); TestUtils.assertFileContains(exampleModelPath, "(typeof value === 'number' && (value === 10 || value === 20 || value === 30))"); TestUtils.assertFileContains(exampleModelPath, "(typeof value === 'string' && (value === 'fixed-value-a' || value === 'fixed-value-b' || value === 'fixed-value-c'))"); @@ -1417,6 +1418,154 @@ public void testExplodedObjectQueryParameter() throws IOException { TestUtils.assertFileNotContains(api, "Object.keys(requestParameters['flatFilter'])"); } + private static final String ANY_OF_SPEC = "src/test/resources/3_0/typescript-fetch/anyOf.yaml"; + + @Test(description = "Verify anyOf stays one interface merging all members' properties by default") + public void testAnyOfIsMergedInterfaceByDefault() throws IOException { + File output = generate(new HashMap<>(), ANY_OF_SPEC); + + Path petData = Paths.get(output + "/models/PetData.ts"); + TestUtils.assertFileContains(petData, "export interface PetData {"); + TestUtils.assertFileContains(petData, "meowCount: number;"); + TestUtils.assertFileContains(petData, "barkCount: number;"); + TestUtils.assertFileNotContains(petData, "export type PetData ="); + } + + @DataProvider + public Object[][] anyOfUnionRuntimeCheckModes() { + return new Object[][] {{false}, {true}}; + } + + @Test(dataProvider = "anyOfUnionRuntimeCheckModes", description = "Verify generateAnyOfAsUnion generates anyOf schemas as union types") + public void testGenerateAnyOfAsUnion(boolean withoutRuntimeChecks) throws IOException { + Map properties = new HashMap<>(); + properties.put(TypeScriptFetchClientCodegen.GENERATE_ANY_OF_AS_UNION, true); + properties.put(TypeScriptFetchClientCodegen.WITHOUT_RUNTIME_CHECKS, withoutRuntimeChecks); + File output = generate(properties, ANY_OF_SPEC); + + // without runtime checks all types are declared in models/index.ts + Function modelFile = name -> + withoutRuntimeChecks ? Paths.get(output + "/models/index.ts") : Paths.get(output + "/models/" + name + ".ts"); + + // top-level anyOf of refs, and the anyOf hoisted from an inline property + TestUtils.assertFileContains(modelFile.apply("PetData"), "export type PetData = Cat | Dog;"); + TestUtils.assertFileContains(modelFile.apply("CreatePetData"), "export type CreatePetData = Cat | Dog;"); + // inline anyOf of primitives on a property (#19155) + TestUtils.assertFileContains(modelFile.apply("CreatePetContent"), "export type CreatePetContent = number | string;"); + // model, array and primitive members + TestUtils.assertFileContains(modelFile.apply("MixedPet"), "export type MixedPet = Array | Cat | string;"); + // null is valid when at least one branch is nullable (for oneOf: exactly one) + TestUtils.assertFileContains(modelFile.apply("NullableValue"), "export type NullableValue = null | number | string;"); + TestUtils.assertFileContains(modelFile.apply("MultipleNullableValue"), "export type MultipleNullableValue = null | number | string;"); + + if (!withoutRuntimeChecks) { + Path petData = Paths.get(output + "/models/PetData.ts"); + TestUtils.assertFileNotContains(petData, "export interface PetData"); + TestUtils.assertFileContains(petData, "import type { Cat } from './Cat';"); + TestUtils.assertFileContains(petData, "if (instanceOfCat(json)) {"); + // a value matching several members keeps the fields of all of them + TestUtils.assertFileContains(petData, "anyOfResult = { ...anyOfResult, ...CatFromJSONTyped(json, true) };"); + TestUtils.assertFileContains(petData, "anyOfResult = { ...anyOfResult, ...DogFromJSONTyped(json, true) };"); + TestUtils.assertFileContains(petData, "anyOfResult = { ...anyOfResult, ...CatToJSON(value as Cat) };"); + TestUtils.assertFileContains(petData, "anyOfResult = { ...anyOfResult, ...DogToJSON(value as Dog) };"); + TestUtils.assertFileNotContains(petData, "return CatToJSON(value as Cat);"); + TestUtils.assertFileContains(Paths.get(output + "/models/CreatePetContent.ts"), "if (typeof json === 'number') {"); + } + } + + @DataProvider + public Object[][] anyOfAsUnionOptionValues() { + return new Object[][] {{false}, {true}}; + } + + @Test(dataProvider = "anyOfAsUnionOptionValues", description = "Verify oneOf still returns the first matching member, also when generateAnyOfAsUnion is on") + public void testOneOfKeepsFirstMatchWithAnyOfUnionOption(boolean anyOfAsUnion) throws IOException { + Map properties = new HashMap<>(); + properties.put(TypeScriptFetchClientCodegen.GENERATE_ANY_OF_AS_UNION, anyOfAsUnion); + File output = generate(properties, "src/test/resources/3_0/typescript-fetch/oneOf.yaml"); + + Path testResponse = Paths.get(output + "/models/TestResponse.ts"); + TestUtils.assertFileContains(testResponse, "return TestAFromJSONTyped(json, true);"); + TestUtils.assertFileNotContains(testResponse, "anyOfResult"); + + // the model checks only run for objects, so the declared primitive check is reachable + TestUtils.assertFileContains(testResponse, "if (typeof json === 'object') {"); + TestUtils.assertFileContains(testResponse, "if (typeof json === 'string') {"); + TestUtils.assertFileContains(testResponse, "if (typeof value === 'object') {"); + TestUtils.assertFileContains(testResponse, "if (typeof value === 'string') {"); + + // null items must not reach the instanceOf checks of array members + Path testArrayResponse = Paths.get(output + "/models/TestArrayResponse.ts"); + TestUtils.assertFileContains(testArrayResponse, "json.every(item => item !== null && typeof item === 'object')"); + TestUtils.assertFileContains(testArrayResponse, "value.every(item => item !== null && typeof item === 'object')"); + TestUtils.assertFileNotContains(testArrayResponse, "every(item => typeof item === 'object')"); + } + + @Test(dataProvider = "anyOfUnionRuntimeCheckModes", description = "Verify an anyOf declaring its own properties stays an interface with generateAnyOfAsUnion") + public void testAnyOfWithOwnPropertiesStaysInterface(boolean withoutRuntimeChecks) throws IOException { + Map properties = new HashMap<>(); + properties.put(TypeScriptFetchClientCodegen.GENERATE_ANY_OF_AS_UNION, true); + properties.put(TypeScriptFetchClientCodegen.WITHOUT_RUNTIME_CHECKS, withoutRuntimeChecks); + File output = generate(properties, ANY_OF_SPEC); + + Path model = withoutRuntimeChecks ? Paths.get(output + "/models/index.ts") : Paths.get(output + "/models/AnyOfWithProperties.ts"); + TestUtils.assertFileContains(model, "export interface AnyOfWithProperties {"); + TestUtils.assertFileContains(model, "label: string;"); + TestUtils.assertFileNotContains(model, "export type AnyOfWithProperties ="); + } + + @Test(description = "Verify a oneOf of a model and a date-time reaches the date parsing, and an enum member is checked by value") + public void testOneOfModelWithDateTimeAndEnumMembers() throws IOException { + File output = generate(new HashMap<>(), ANY_OF_SPEC); + + String dateTime = Files.readString(Paths.get(output + "/models/OneOfModelAndDateTime.ts"), StandardCharsets.UTF_8); + // the parse and serialize branches come after the object block, and no primitive is passed through before them + assertThat(dateTime.indexOf("if (typeof json === 'object') {")).isGreaterThan(-1) + .isLessThan(dateTime.indexOf("parseDateTime(json)")); + assertThat(dateTime.indexOf("if (typeof value === 'object') {")).isGreaterThan(-1) + .isLessThan(dateTime.indexOf("value instanceof Date")); + assertThat(dateTime).doesNotContain("typeof json !== 'object'").doesNotContain("typeof value !== 'object'"); + + // the instanceOf check of an enum takes the primitive value, so it must not be inside the object block + String enumUnion = Files.readString(Paths.get(output + "/models/OneOfModelAndEnum.ts"), StandardCharsets.UTF_8); + assertThat(enumUnion).contains("if (instanceOfColor(json)) {").contains("if (instanceOfColor(value)) {"); + assertThat(enumUnion.indexOf("if (instanceOfColor(json)) {")).isGreaterThan(enumUnion.indexOf("if (instanceOfCat(json)) {")); + assertThat(enumUnion).doesNotContain("typeof json !== 'object'").doesNotContain("typeof value !== 'object'"); + } + + @Test(description = "Verify an anyOf with a discriminator keeps the discriminator switch and does not merge members") + public void testGenerateAnyOfAsUnionWithDiscriminator() throws IOException { + Map properties = new HashMap<>(); + properties.put(TypeScriptFetchClientCodegen.GENERATE_ANY_OF_AS_UNION, true); + File output = generate(properties, ANY_OF_SPEC); + + Path model = Paths.get(output + "/models/DiscriminatedPet.ts"); + TestUtils.assertFileContains(model, "export type DiscriminatedPet = { kind: 'cat' } & Cat | { kind: 'dog' } & Dog;"); + TestUtils.assertFileContains(model, "switch (json['kind']) {"); + TestUtils.assertFileNotContains(model, "anyOfResult"); + } + + @Test(description = "Verify an anyOf mixing a model, an array and a primitive merges only the object member") + public void testGenerateAnyOfAsUnionWithMixedMembers() throws IOException { + Map properties = new HashMap<>(); + properties.put(TypeScriptFetchClientCodegen.GENERATE_ANY_OF_AS_UNION, true); + File output = generate(properties, ANY_OF_SPEC); + + Path model = Paths.get(output + "/models/MixedPet.ts"); + TestUtils.assertFileContains(model, "export type MixedPet = Array | Cat | string;"); + TestUtils.assertFileContains(model, "anyOfResult = { ...anyOfResult, ...CatFromJSONTyped(json, true) };"); + TestUtils.assertFileContains(model, "return json.map(value => DogFromJSONTyped(value, true));"); + TestUtils.assertFileContains(model, "if (typeof json === 'string') {"); + TestUtils.assertFileContains(model, "return value.map(value => DogToJSON(value as Dog));"); + TestUtils.assertFileContains(model, "if (typeof value === 'string') {"); + // the model checks only run for objects, so the primitive checks are reachable + TestUtils.assertFileContains(model, "if (typeof json === 'object') {"); + TestUtils.assertFileContains(model, "if (typeof value === 'object') {"); + // null items must not reach instanceOfDog + TestUtils.assertFileContains(model, "json.every(item => item !== null && typeof item === 'object')"); + TestUtils.assertFileContains(model, "value.every(item => item !== null && typeof item === 'object')"); + } + private static final String DATE_HANDLING_SPEC = "src/test/resources/3_0/typescript-fetch/date-handling.yaml"; private static File generate( diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/fetch/TypeScriptFetchClientOptionsTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/fetch/TypeScriptFetchClientOptionsTest.java index 711e09fcf993..2673f6871b7a 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/fetch/TypeScriptFetchClientOptionsTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/fetch/TypeScriptFetchClientOptionsTest.java @@ -54,6 +54,7 @@ protected void verifyOptions() { verify(clientCodegen).setSagasAndRecords(Boolean.valueOf(TypeScriptFetchClientOptionsProvider.SAGAS_AND_RECORDS)); verify(clientCodegen).setEnumUnknownDefaultCase(Boolean.parseBoolean(TypeScriptFetchClientOptionsProvider.ENUM_UNKNOWN_DEFAULT_CASE_VALUE)); verify(clientCodegen).setStringEnums(Boolean.parseBoolean(TypeScriptFetchClientOptionsProvider.STRING_ENUMS)); + verify(clientCodegen).setGenerateAnyOfAsUnion(Boolean.parseBoolean(TypeScriptFetchClientOptionsProvider.GENERATE_ANY_OF_AS_UNION)); verify(clientCodegen).setFileNaming(TypeScriptFetchClientOptionsProvider.FILE_NAMING_VALUE); verify(clientCodegen).setDateLibrary(TypeScriptFetchClientOptionsProvider.DATE_LIBRARY_VALUE); } diff --git a/modules/openapi-generator/src/test/resources/3_0/typescript-fetch/anyOf.yaml b/modules/openapi-generator/src/test/resources/3_0/typescript-fetch/anyOf.yaml new file mode 100644 index 000000000000..25c9075cc0eb --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/typescript-fetch/anyOf.yaml @@ -0,0 +1,116 @@ +openapi: 3.0.3 +info: + title: anyOf as union + version: 1.0.0 +paths: + /pets: + post: + operationId: createPet + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CreatePet' + responses: + '200': + description: ok + content: + application/json: + schema: + $ref: '#/components/schemas/PetData' +components: + schemas: + Cat: + type: object + properties: + kind: + type: string + meowCount: + type: integer + required: + - kind + - meowCount + Dog: + type: object + properties: + kind: + type: string + barkCount: + type: integer + tailLength: + type: integer + breed: + type: string + required: + - kind + - barkCount + - tailLength + PetData: + anyOf: + - $ref: '#/components/schemas/Cat' + - $ref: '#/components/schemas/Dog' + DiscriminatedPet: + anyOf: + - $ref: '#/components/schemas/Cat' + - $ref: '#/components/schemas/Dog' + discriminator: + propertyName: kind + mapping: + cat: '#/components/schemas/Cat' + dog: '#/components/schemas/Dog' + MixedPet: + anyOf: + - $ref: '#/components/schemas/Cat' + - type: array + items: + $ref: '#/components/schemas/Dog' + - type: string + AnyOfWithProperties: + anyOf: + - $ref: '#/components/schemas/Cat' + - $ref: '#/components/schemas/Dog' + properties: + label: + type: string + required: + - label + Color: + type: string + enum: + - red + - blue + OneOfModelAndEnum: + oneOf: + - $ref: '#/components/schemas/Cat' + - $ref: '#/components/schemas/Color' + OneOfModelAndDateTime: + oneOf: + - $ref: '#/components/schemas/Cat' + - type: string + format: date-time + NullableValue: + anyOf: + - type: string + nullable: true + - type: number + MultipleNullableValue: + anyOf: + - type: string + nullable: true + - type: number + nullable: true + CreatePet: + type: object + properties: + id: + type: string + data: + anyOf: + - $ref: '#/components/schemas/Cat' + - $ref: '#/components/schemas/Dog' + content: + anyOf: + - type: number + - type: string + required: + - id diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/.gitignore b/samples/client/petstore/typescript-fetch/builds/any-of-union/.gitignore new file mode 100644 index 000000000000..149b57654723 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/.gitignore @@ -0,0 +1,4 @@ +wwwroot/*.js +node_modules +typings +dist diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/.npmignore b/samples/client/petstore/typescript-fetch/builds/any-of-union/.npmignore new file mode 100644 index 000000000000..42061c01a1c7 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/.npmignore @@ -0,0 +1 @@ +README.md \ No newline at end of file diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/.openapi-generator-ignore b/samples/client/petstore/typescript-fetch/builds/any-of-union/.openapi-generator-ignore new file mode 100644 index 000000000000..7484ee590a38 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/.openapi-generator/FILES b/samples/client/petstore/typescript-fetch/builds/any-of-union/.openapi-generator/FILES new file mode 100644 index 000000000000..95988ae13db7 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/.openapi-generator/FILES @@ -0,0 +1,40 @@ +.gitignore +.npmignore +README.md +docs/AnyOfWithProperties.md +docs/Cat.md +docs/Color.md +docs/CreatePet.md +docs/CreatePetContent.md +docs/CreatePetData.md +docs/DefaultApi.md +docs/DiscriminatedPet.md +docs/Dog.md +docs/MixedPet.md +docs/MultipleNullableValue.md +docs/NullableValue.md +docs/OneOfModelAndDateTime.md +docs/OneOfModelAndEnum.md +docs/PetData.md +package.json +src/apis/DefaultApi.ts +src/apis/index.ts +src/index.ts +src/models/AnyOfWithProperties.ts +src/models/Cat.ts +src/models/Color.ts +src/models/CreatePet.ts +src/models/CreatePetContent.ts +src/models/CreatePetData.ts +src/models/DiscriminatedPet.ts +src/models/Dog.ts +src/models/MixedPet.ts +src/models/MultipleNullableValue.ts +src/models/NullableValue.ts +src/models/OneOfModelAndDateTime.ts +src/models/OneOfModelAndEnum.ts +src/models/PetData.ts +src/models/index.ts +src/runtime.ts +tsconfig.esm.json +tsconfig.json diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/.openapi-generator/VERSION b/samples/client/petstore/typescript-fetch/builds/any-of-union/.openapi-generator/VERSION new file mode 100644 index 000000000000..56fe0e8b297f --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/.openapi-generator/VERSION @@ -0,0 +1 @@ +7.27.0-SNAPSHOT diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/README.md b/samples/client/petstore/typescript-fetch/builds/any-of-union/README.md new file mode 100644 index 000000000000..4527782fcd0f --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/README.md @@ -0,0 +1,125 @@ +# @openapitools/typescript-fetch-petstore@1.0.0 + +A TypeScript SDK client for the localhost API. + +## Usage + +First, install the SDK from npm. + +```bash +npm install @openapitools/typescript-fetch-petstore --save +``` + +Next, try it out. + + +```ts +import { + Configuration, + DefaultApi, +} from '@openapitools/typescript-fetch-petstore'; +import type { CreatePetRequest } from '@openapitools/typescript-fetch-petstore'; + +async function example() { + console.log("🚀 Testing @openapitools/typescript-fetch-petstore SDK..."); + const api = new DefaultApi(); + + const body = { + // CreatePet (optional) + createPet: ..., + } satisfies CreatePetRequest; + + try { + const data = await api.createPet(body); + console.log(data); + } catch (error) { + console.error(error); + } +} + +// Run the test +example().catch(console.error); +``` + + +## Documentation + +### API Endpoints + +All URIs are relative to *http://localhost* + +| Class | Method | HTTP request | Description +| ----- | ------ | ------------ | ------------- +*DefaultApi* | [**createPet**](docs/DefaultApi.md#createpet) | **POST** /pets | + + +### Models + +- [AnyOfWithProperties](docs/AnyOfWithProperties.md) +- [Cat](docs/Cat.md) +- [Color](docs/Color.md) +- [CreatePet](docs/CreatePet.md) +- [CreatePetContent](docs/CreatePetContent.md) +- [CreatePetData](docs/CreatePetData.md) +- [DiscriminatedPet](docs/DiscriminatedPet.md) +- [Dog](docs/Dog.md) +- [MixedPet](docs/MixedPet.md) +- [MultipleNullableValue](docs/MultipleNullableValue.md) +- [NullableValue](docs/NullableValue.md) +- [OneOfModelAndDateTime](docs/OneOfModelAndDateTime.md) +- [OneOfModelAndEnum](docs/OneOfModelAndEnum.md) +- [PetData](docs/PetData.md) + +### Authorization + +Endpoints do not require authorization. + + +## About + +This TypeScript SDK client supports the [Fetch API](https://fetch.spec.whatwg.org/) +and is automatically generated by the +[OpenAPI Generator](https://openapi-generator.tech) project: + +- API version: `1.0.0` +- Package version: `1.0.0` +- Generator version: `7.27.0-SNAPSHOT` +- Build package: `org.openapitools.codegen.languages.TypeScriptFetchClientCodegen` + +The generated npm module supports the following: + +- Environments + * Node.js + * Webpack + * Browserify +- Language levels + * ES5 - you must have a Promises/A+ library installed + * ES6 +- Module systems + * CommonJS + * ES6 module system + + +## Development + +### Building + +To build the TypeScript source code, you need to have Node.js and npm installed. +After cloning the repository, navigate to the project directory and run: + +```bash +npm install +npm run build +``` + +### Publishing + +Once you've built the package, you can publish it to npm: + +```bash +npm publish +``` + +## License + +[]() diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/AnyOfWithProperties.md b/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/AnyOfWithProperties.md new file mode 100644 index 000000000000..dc61e06da87f --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/AnyOfWithProperties.md @@ -0,0 +1,44 @@ + +# AnyOfWithProperties + + +## Properties + +Name | Type +------------ | ------------- +`label` | string +`kind` | string +`meowCount` | number +`barkCount` | number +`tailLength` | number +`breed` | string + +## Example + +```typescript +import type { AnyOfWithProperties } from '@openapitools/typescript-fetch-petstore' + +// TODO: Update the object below with actual values +const example = { + "label": null, + "kind": null, + "meowCount": null, + "barkCount": null, + "tailLength": null, + "breed": null, +} satisfies AnyOfWithProperties + +console.log(example) + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example) +console.log(exampleJSON) + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as AnyOfWithProperties +console.log(exampleParsed) +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + + diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/Cat.md b/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/Cat.md new file mode 100644 index 000000000000..19b5e5d3a9e9 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/Cat.md @@ -0,0 +1,36 @@ + +# Cat + + +## Properties + +Name | Type +------------ | ------------- +`kind` | string +`meowCount` | number + +## Example + +```typescript +import type { Cat } from '@openapitools/typescript-fetch-petstore' + +// TODO: Update the object below with actual values +const example = { + "kind": null, + "meowCount": null, +} satisfies Cat + +console.log(example) + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example) +console.log(exampleJSON) + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as Cat +console.log(exampleParsed) +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + + diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/Color.md b/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/Color.md new file mode 100644 index 000000000000..71d5f7588136 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/Color.md @@ -0,0 +1,32 @@ + +# Color + + +## Properties + +Name | Type +------------ | ------------- + +## Example + +```typescript +import type { Color } from '@openapitools/typescript-fetch-petstore' + +// TODO: Update the object below with actual values +const example = { +} satisfies Color + +console.log(example) + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example) +console.log(exampleJSON) + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as Color +console.log(exampleParsed) +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + + diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/CreatePet.md b/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/CreatePet.md new file mode 100644 index 000000000000..f445bd68dac0 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/CreatePet.md @@ -0,0 +1,38 @@ + +# CreatePet + + +## Properties + +Name | Type +------------ | ------------- +`id` | string +`data` | [CreatePetData](CreatePetData.md) +`content` | [CreatePetContent](CreatePetContent.md) + +## Example + +```typescript +import type { CreatePet } from '@openapitools/typescript-fetch-petstore' + +// TODO: Update the object below with actual values +const example = { + "id": null, + "data": null, + "content": null, +} satisfies CreatePet + +console.log(example) + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example) +console.log(exampleJSON) + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as CreatePet +console.log(exampleParsed) +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + + diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/CreatePetContent.md b/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/CreatePetContent.md new file mode 100644 index 000000000000..b2c0f1a324d1 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/CreatePetContent.md @@ -0,0 +1,32 @@ + +# CreatePetContent + + +## Properties + +Name | Type +------------ | ------------- + +## Example + +```typescript +import type { CreatePetContent } from '@openapitools/typescript-fetch-petstore' + +// TODO: Update the object below with actual values +const example = { +} satisfies CreatePetContent + +console.log(example) + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example) +console.log(exampleJSON) + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as CreatePetContent +console.log(exampleParsed) +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + + diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/CreatePetData.md b/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/CreatePetData.md new file mode 100644 index 000000000000..666be577c004 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/CreatePetData.md @@ -0,0 +1,42 @@ + +# CreatePetData + + +## Properties + +Name | Type +------------ | ------------- +`kind` | string +`meowCount` | number +`barkCount` | number +`tailLength` | number +`breed` | string + +## Example + +```typescript +import type { CreatePetData } from '@openapitools/typescript-fetch-petstore' + +// TODO: Update the object below with actual values +const example = { + "kind": null, + "meowCount": null, + "barkCount": null, + "tailLength": null, + "breed": null, +} satisfies CreatePetData + +console.log(example) + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example) +console.log(exampleJSON) + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as CreatePetData +console.log(exampleParsed) +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + + diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/DefaultApi.md b/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/DefaultApi.md new file mode 100644 index 000000000000..2f2dee0e2b25 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/DefaultApi.md @@ -0,0 +1,74 @@ +# DefaultApi + +All URIs are relative to *http://localhost* + +| Method | HTTP request | Description | +|------------- | ------------- | -------------| +| [**createPet**](DefaultApi.md#createpet) | **POST** /pets | | + + + +## createPet + +> PetData createPet(createPet) + + + +### Example + +```ts +import { + Configuration, + DefaultApi, +} from '@openapitools/typescript-fetch-petstore'; +import type { CreatePetRequest } from '@openapitools/typescript-fetch-petstore'; + +async function example() { + console.log("🚀 Testing @openapitools/typescript-fetch-petstore SDK..."); + const api = new DefaultApi(); + + const body = { + // CreatePet (optional) + createPet: ..., + } satisfies CreatePetRequest; + + try { + const data = await api.createPet(body); + console.log(data); + } catch (error) { + console.error(error); + } +} + +// Run the test +example().catch(console.error); +``` + +### Parameters + + +| Name | Type | Description | Notes | +|------------- | ------------- | ------------- | -------------| +| **createPet** | [CreatePet](CreatePet.md) | | [Optional] | + +### Return type + +[**PetData**](PetData.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: `application/json` +- **Accept**: `application/json` + + +### HTTP response details +| Status code | Description | Response headers | +|-------------|-------------|------------------| +| **200** | ok | - | + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/DiscriminatedPet.md b/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/DiscriminatedPet.md new file mode 100644 index 000000000000..29600d84c633 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/DiscriminatedPet.md @@ -0,0 +1,42 @@ + +# DiscriminatedPet + + +## Properties + +Name | Type +------------ | ------------- +`kind` | string +`meowCount` | number +`barkCount` | number +`tailLength` | number +`breed` | string + +## Example + +```typescript +import type { DiscriminatedPet } from '@openapitools/typescript-fetch-petstore' + +// TODO: Update the object below with actual values +const example = { + "kind": null, + "meowCount": null, + "barkCount": null, + "tailLength": null, + "breed": null, +} satisfies DiscriminatedPet + +console.log(example) + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example) +console.log(exampleJSON) + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as DiscriminatedPet +console.log(exampleParsed) +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + + diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/Dog.md b/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/Dog.md new file mode 100644 index 000000000000..d1dcc8c5d722 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/Dog.md @@ -0,0 +1,40 @@ + +# Dog + + +## Properties + +Name | Type +------------ | ------------- +`kind` | string +`barkCount` | number +`tailLength` | number +`breed` | string + +## Example + +```typescript +import type { Dog } from '@openapitools/typescript-fetch-petstore' + +// TODO: Update the object below with actual values +const example = { + "kind": null, + "barkCount": null, + "tailLength": null, + "breed": null, +} satisfies Dog + +console.log(example) + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example) +console.log(exampleJSON) + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as Dog +console.log(exampleParsed) +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + + diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/MixedPet.md b/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/MixedPet.md new file mode 100644 index 000000000000..67668bf156f0 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/MixedPet.md @@ -0,0 +1,36 @@ + +# MixedPet + + +## Properties + +Name | Type +------------ | ------------- +`kind` | string +`meowCount` | number + +## Example + +```typescript +import type { MixedPet } from '@openapitools/typescript-fetch-petstore' + +// TODO: Update the object below with actual values +const example = { + "kind": null, + "meowCount": null, +} satisfies MixedPet + +console.log(example) + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example) +console.log(exampleJSON) + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as MixedPet +console.log(exampleParsed) +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + + diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/MultipleNullableValue.md b/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/MultipleNullableValue.md new file mode 100644 index 000000000000..b0e3f2d7606a --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/MultipleNullableValue.md @@ -0,0 +1,32 @@ + +# MultipleNullableValue + + +## Properties + +Name | Type +------------ | ------------- + +## Example + +```typescript +import type { MultipleNullableValue } from '@openapitools/typescript-fetch-petstore' + +// TODO: Update the object below with actual values +const example = { +} satisfies MultipleNullableValue + +console.log(example) + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example) +console.log(exampleJSON) + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as MultipleNullableValue +console.log(exampleParsed) +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + + diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/NullableValue.md b/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/NullableValue.md new file mode 100644 index 000000000000..ac1d89db3720 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/NullableValue.md @@ -0,0 +1,32 @@ + +# NullableValue + + +## Properties + +Name | Type +------------ | ------------- + +## Example + +```typescript +import type { NullableValue } from '@openapitools/typescript-fetch-petstore' + +// TODO: Update the object below with actual values +const example = { +} satisfies NullableValue + +console.log(example) + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example) +console.log(exampleJSON) + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as NullableValue +console.log(exampleParsed) +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + + diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/OneOfModelAndDateTime.md b/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/OneOfModelAndDateTime.md new file mode 100644 index 000000000000..c92daa21cc21 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/OneOfModelAndDateTime.md @@ -0,0 +1,36 @@ + +# OneOfModelAndDateTime + + +## Properties + +Name | Type +------------ | ------------- +`kind` | string +`meowCount` | number + +## Example + +```typescript +import type { OneOfModelAndDateTime } from '@openapitools/typescript-fetch-petstore' + +// TODO: Update the object below with actual values +const example = { + "kind": null, + "meowCount": null, +} satisfies OneOfModelAndDateTime + +console.log(example) + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example) +console.log(exampleJSON) + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as OneOfModelAndDateTime +console.log(exampleParsed) +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + + diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/OneOfModelAndEnum.md b/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/OneOfModelAndEnum.md new file mode 100644 index 000000000000..49a9ac7d91e0 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/OneOfModelAndEnum.md @@ -0,0 +1,36 @@ + +# OneOfModelAndEnum + + +## Properties + +Name | Type +------------ | ------------- +`kind` | string +`meowCount` | number + +## Example + +```typescript +import type { OneOfModelAndEnum } from '@openapitools/typescript-fetch-petstore' + +// TODO: Update the object below with actual values +const example = { + "kind": null, + "meowCount": null, +} satisfies OneOfModelAndEnum + +console.log(example) + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example) +console.log(exampleJSON) + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as OneOfModelAndEnum +console.log(exampleParsed) +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + + diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/PetData.md b/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/PetData.md new file mode 100644 index 000000000000..ddc194ad9d1a --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/docs/PetData.md @@ -0,0 +1,42 @@ + +# PetData + + +## Properties + +Name | Type +------------ | ------------- +`kind` | string +`meowCount` | number +`barkCount` | number +`tailLength` | number +`breed` | string + +## Example + +```typescript +import type { PetData } from '@openapitools/typescript-fetch-petstore' + +// TODO: Update the object below with actual values +const example = { + "kind": null, + "meowCount": null, + "barkCount": null, + "tailLength": null, + "breed": null, +} satisfies PetData + +console.log(example) + +// Convert the instance to a JSON string +const exampleJSON: string = JSON.stringify(example) +console.log(exampleJSON) + +// Parse the JSON string back to an object +const exampleParsed = JSON.parse(exampleJSON) as PetData +console.log(exampleParsed) +``` + +[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md) + + diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/package.json b/samples/client/petstore/typescript-fetch/builds/any-of-union/package.json new file mode 100644 index 000000000000..6d44ed32b0c2 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/package.json @@ -0,0 +1,24 @@ +{ + "name": "@openapitools/typescript-fetch-petstore", + "version": "1.0.0", + "description": "OpenAPI client for @openapitools/typescript-fetch-petstore", + "author": "OpenAPI-Generator", + "repository": { + "type": "git", + "url": "https://github.com/GIT_USER_ID/GIT_REPO_ID.git" + }, + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "module": "./dist/esm/index.js", + "sideEffects": false, + "scripts": { + "build": "tsc && tsc -p tsconfig.esm.json", + "prepare": "npm run build" + }, + "devDependencies": { + "typescript": "^4.0 || ^5.0" + }, + "publishConfig": { + "registry": "https://skimdb.npmjs.com/registry" + } +} diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/src/apis/DefaultApi.ts b/samples/client/petstore/typescript-fetch/builds/any-of-union/src/apis/DefaultApi.ts new file mode 100644 index 000000000000..027faee59365 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/src/apis/DefaultApi.ts @@ -0,0 +1,77 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * anyOf as union + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import * as runtime from '../runtime'; +import { + type CreatePet, + CreatePetFromJSON, + CreatePetToJSON, +} from '../models/CreatePet'; +import { + type PetData, + PetDataFromJSON, + PetDataToJSON, +} from '../models/PetData'; + +export interface CreatePetRequest { + /** + * + */ + createPet?: CreatePet; +} + +/** + * + */ +export class DefaultApi extends runtime.BaseAPI { + + /** + * Creates request options for createPet without sending the request + */ + async createPetRequestOpts(requestParameters: CreatePetRequest): Promise { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + + let urlPath = `/pets`; + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: CreatePetToJSON(requestParameters['createPet']), + }; + } + + /** + */ + async createPetRaw(requestParameters: CreatePetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.createPetRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => PetDataFromJSON(jsonValue)); + } + + /** + */ + async createPet(requestParameters: CreatePetRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.createPetRaw(requestParameters, initOverrides); + return await response.value(); + } + +} diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/src/apis/index.ts b/samples/client/petstore/typescript-fetch/builds/any-of-union/src/apis/index.ts new file mode 100644 index 000000000000..69c44c00fa0d --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/src/apis/index.ts @@ -0,0 +1,3 @@ +/* tslint:disable */ +/* eslint-disable */ +export * from './DefaultApi'; diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/src/index.ts b/samples/client/petstore/typescript-fetch/builds/any-of-union/src/index.ts new file mode 100644 index 000000000000..bebe8bbbe206 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/src/index.ts @@ -0,0 +1,5 @@ +/* tslint:disable */ +/* eslint-disable */ +export * from './runtime'; +export * from './apis/index'; +export * from './models/index'; diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/AnyOfWithProperties.ts b/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/AnyOfWithProperties.ts new file mode 100644 index 000000000000..e4c5926f7947 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/AnyOfWithProperties.ts @@ -0,0 +1,113 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * anyOf as union + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +import type { Cat } from './Cat'; +import { + CatFromJSON, + CatFromJSONTyped, + CatToJSON, + CatToJSONTyped, +} from './Cat'; +import type { Dog } from './Dog'; +import { + DogFromJSON, + DogFromJSONTyped, + DogToJSON, + DogToJSONTyped, +} from './Dog'; + +/** + * + * @export + * @interface AnyOfWithProperties + */ +export interface AnyOfWithProperties { + /** + * + */ + label: string; + /** + * + */ + kind: string; + /** + * + */ + meowCount: number; + /** + * + */ + barkCount: number; + /** + * + */ + tailLength: number; + /** + * + */ + breed?: string; +} + +/** + * Check if a given object implements the AnyOfWithProperties interface. + */ +export function instanceOfAnyOfWithProperties(value: object): value is AnyOfWithProperties { + if (!('label' in value) || value['label'] === undefined) return false; + if (!('kind' in value) || value['kind'] === undefined) return false; + if (!('meowCount' in value) || value['meowCount'] === undefined) return false; + if (!('barkCount' in value) || value['barkCount'] === undefined) return false; + if (!('tailLength' in value) || value['tailLength'] === undefined) return false; + return true; +} + +export function AnyOfWithPropertiesFromJSON(json: any): AnyOfWithProperties { + return AnyOfWithPropertiesFromJSONTyped(json, false); +} + +export function AnyOfWithPropertiesFromJSONTyped(json: any, ignoreDiscriminator: boolean): AnyOfWithProperties { + if (json == null) { + return json; + } + return { + + 'label': json['label'], + 'kind': json['kind'], + 'meowCount': json['meowCount'], + 'barkCount': json['barkCount'], + 'tailLength': json['tailLength'], + 'breed': json['breed'] == null ? undefined : json['breed'], + }; +} + +export function AnyOfWithPropertiesToJSON(json: any): AnyOfWithProperties { + return AnyOfWithPropertiesToJSONTyped(json, false); +} + +export function AnyOfWithPropertiesToJSONTyped(value?: AnyOfWithProperties | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'label': value['label'], + 'kind': value['kind'], + 'meowCount': value['meowCount'], + 'barkCount': value['barkCount'], + 'tailLength': value['tailLength'], + 'breed': value['breed'], + }; +} + diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/Cat.ts b/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/Cat.ts new file mode 100644 index 000000000000..a96ed94c8868 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/Cat.ts @@ -0,0 +1,71 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * anyOf as union + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface Cat + */ +export interface Cat { + /** + * + */ + kind: string; + /** + * + */ + meowCount: number; +} + +/** + * Check if a given object implements the Cat interface. + */ +export function instanceOfCat(value: object): value is Cat { + if (!('kind' in value) || value['kind'] === undefined) return false; + if (!('meowCount' in value) || value['meowCount'] === undefined) return false; + return true; +} + +export function CatFromJSON(json: any): Cat { + return CatFromJSONTyped(json, false); +} + +export function CatFromJSONTyped(json: any, ignoreDiscriminator: boolean): Cat { + if (json == null) { + return json; + } + return { + + 'kind': json['kind'], + 'meowCount': json['meowCount'], + }; +} + +export function CatToJSON(json: any): Cat { + return CatToJSONTyped(json, false); +} + +export function CatToJSONTyped(value?: Cat | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'kind': value['kind'], + 'meowCount': value['meowCount'], + }; +} + diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/Color.ts b/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/Color.ts new file mode 100644 index 000000000000..ca0d71d5bd87 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/Color.ts @@ -0,0 +1,53 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * anyOf as union + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** + * + * @export + */ +export const Color = { + Red: 'red', + Blue: 'blue', +} as const; +export type Color = typeof Color[keyof typeof Color]; + + +export function instanceOfColor(value: any): boolean { + for (const key in Color) { + if (Object.prototype.hasOwnProperty.call(Color, key)) { + if (Color[key as keyof typeof Color] === value) { + return true; + } + } + } + return false; +} + +export function ColorFromJSON(json: any): Color { + return ColorFromJSONTyped(json, false); +} + +export function ColorFromJSONTyped(json: any, ignoreDiscriminator: boolean): Color { + return json as Color; +} + +export function ColorToJSON(value?: Color | null): any { + return value as any; +} + +export function ColorToJSONTyped(value: any, ignoreDiscriminator: boolean): Color { + return value as Color; +} + diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/CreatePet.ts b/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/CreatePet.ts new file mode 100644 index 000000000000..87fd63f1c9bf --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/CreatePet.ts @@ -0,0 +1,91 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * anyOf as union + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +import type { CreatePetData } from './CreatePetData'; +import { + CreatePetDataFromJSON, + CreatePetDataFromJSONTyped, + CreatePetDataToJSON, + CreatePetDataToJSONTyped, +} from './CreatePetData'; +import type { CreatePetContent } from './CreatePetContent'; +import { + CreatePetContentFromJSON, + CreatePetContentFromJSONTyped, + CreatePetContentToJSON, + CreatePetContentToJSONTyped, +} from './CreatePetContent'; + +/** + * + * @export + * @interface CreatePet + */ +export interface CreatePet { + /** + * + */ + id: string; + /** + * + */ + data?: CreatePetData; + /** + * + */ + content?: CreatePetContent; +} + +/** + * Check if a given object implements the CreatePet interface. + */ +export function instanceOfCreatePet(value: object): value is CreatePet { + if (!('id' in value) || value['id'] === undefined) return false; + return true; +} + +export function CreatePetFromJSON(json: any): CreatePet { + return CreatePetFromJSONTyped(json, false); +} + +export function CreatePetFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreatePet { + if (json == null) { + return json; + } + return { + + 'id': json['id'], + 'data': json['data'] == null ? undefined : CreatePetDataFromJSON(json['data']), + 'content': json['content'] == null ? undefined : CreatePetContentFromJSON(json['content']), + }; +} + +export function CreatePetToJSON(json: any): CreatePet { + return CreatePetToJSONTyped(json, false); +} + +export function CreatePetToJSONTyped(value?: CreatePet | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'id': value['id'], + 'data': CreatePetDataToJSON(value['data']), + 'content': CreatePetContentToJSON(value['content']), + }; +} + diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/CreatePetContent.ts b/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/CreatePetContent.ts new file mode 100644 index 000000000000..1867afc78237 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/CreatePetContent.ts @@ -0,0 +1,56 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * anyOf as union + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { parseDate, parseDateTime, serializeDate, serializeDateTime } from '../runtime'; +/** + * @type CreatePetContent + * + * @export + */ +export type CreatePetContent = number | string; + +export function CreatePetContentFromJSON(json: any): CreatePetContent { + return CreatePetContentFromJSONTyped(json, false); +} + +export function CreatePetContentFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreatePetContent { + if (json == null) { + return json; + } + if (typeof json === 'number') { + return json; + } + if (typeof json === 'string') { + return json; + } + return {} as any; +} + +export function CreatePetContentToJSON(json: any): any { + return CreatePetContentToJSONTyped(json, false); +} + +export function CreatePetContentToJSONTyped(value?: CreatePetContent | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + if (typeof value === 'number') { + return value; + } + if (typeof value === 'string') { + return value; + } + return {}; +} + diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/CreatePetData.ts b/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/CreatePetData.ts new file mode 100644 index 000000000000..f30d8e035555 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/CreatePetData.ts @@ -0,0 +1,91 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * anyOf as union + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { parseDate, parseDateTime, serializeDate, serializeDateTime } from '../runtime'; +import type { Cat } from './Cat'; +import { + instanceOfCat, + CatFromJSON, + CatFromJSONTyped, + CatToJSON, +} from './Cat'; +import type { Dog } from './Dog'; +import { + instanceOfDog, + DogFromJSON, + DogFromJSONTyped, + DogToJSON, +} from './Dog'; + +/** + * @type CreatePetData + * + * @export + */ +export type CreatePetData = Cat | Dog; + +export function CreatePetDataFromJSON(json: any): CreatePetData { + return CreatePetDataFromJSONTyped(json, false); +} + +export function CreatePetDataFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreatePetData { + if (json == null) { + return json; + } + if (typeof json === 'object') { + // anyOf: a value may match several members, so combine all of them instead of keeping the first match + let anyOfResult: any = {}; + let anyOfMatched = false; + if (instanceOfCat(json)) { + anyOfResult = { ...anyOfResult, ...CatFromJSONTyped(json, true) }; + anyOfMatched = true; + } + if (instanceOfDog(json)) { + anyOfResult = { ...anyOfResult, ...DogFromJSONTyped(json, true) }; + anyOfMatched = true; + } + if (anyOfMatched) { + return anyOfResult; + } + } + return {} as any; +} + +export function CreatePetDataToJSON(json: any): any { + return CreatePetDataToJSONTyped(json, false); +} + +export function CreatePetDataToJSONTyped(value?: CreatePetData | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + if (typeof value === 'object') { + // anyOf: a value may match several members, so combine all of them instead of keeping the first match + let anyOfResult: any = {}; + let anyOfMatched = false; + if (instanceOfCat(value)) { + anyOfResult = { ...anyOfResult, ...CatToJSON(value as Cat) }; + anyOfMatched = true; + } + if (instanceOfDog(value)) { + anyOfResult = { ...anyOfResult, ...DogToJSON(value as Dog) }; + anyOfMatched = true; + } + if (anyOfMatched) { + return anyOfResult; + } + } + return {}; +} + diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/DiscriminatedPet.ts b/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/DiscriminatedPet.ts new file mode 100644 index 000000000000..5d497dff19f7 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/DiscriminatedPet.ts @@ -0,0 +1,73 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * anyOf as union + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { parseDate, parseDateTime, serializeDate, serializeDateTime } from '../runtime'; +import type { Cat } from './Cat'; +import { + instanceOfCat, + CatFromJSON, + CatFromJSONTyped, + CatToJSON, +} from './Cat'; +import type { Dog } from './Dog'; +import { + instanceOfDog, + DogFromJSON, + DogFromJSONTyped, + DogToJSON, +} from './Dog'; + +/** + * @type DiscriminatedPet + * + * @export + */ +export type DiscriminatedPet = { kind: 'cat' } & Cat | { kind: 'dog' } & Dog; + +export function DiscriminatedPetFromJSON(json: any): DiscriminatedPet { + return DiscriminatedPetFromJSONTyped(json, false); +} + +export function DiscriminatedPetFromJSONTyped(json: any, ignoreDiscriminator: boolean): DiscriminatedPet { + if (json == null) { + return json; + } + switch (json['kind']) { + case 'cat': + return Object.assign({}, CatFromJSONTyped(json, true), { kind: 'cat' } as const); + case 'dog': + return Object.assign({}, DogFromJSONTyped(json, true), { kind: 'dog' } as const); + default: + return json; + } +} + +export function DiscriminatedPetToJSON(json: any): any { + return DiscriminatedPetToJSONTyped(json, false); +} + +export function DiscriminatedPetToJSONTyped(value?: DiscriminatedPet | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + switch (value['kind']) { + case 'cat': + return Object.assign({}, CatToJSON(value), { 'kind': 'cat' } as const); + case 'dog': + return Object.assign({}, DogToJSON(value), { 'kind': 'dog' } as const); + default: + return value; + } +} + diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/Dog.ts b/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/Dog.ts new file mode 100644 index 000000000000..67abfb3cac9d --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/Dog.ts @@ -0,0 +1,84 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * anyOf as union + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface Dog + */ +export interface Dog { + /** + * + */ + kind: string; + /** + * + */ + barkCount: number; + /** + * + */ + tailLength: number; + /** + * + */ + breed?: string; +} + +/** + * Check if a given object implements the Dog interface. + */ +export function instanceOfDog(value: object): value is Dog { + if (!('kind' in value) || value['kind'] === undefined) return false; + if (!('barkCount' in value) || value['barkCount'] === undefined) return false; + if (!('tailLength' in value) || value['tailLength'] === undefined) return false; + return true; +} + +export function DogFromJSON(json: any): Dog { + return DogFromJSONTyped(json, false); +} + +export function DogFromJSONTyped(json: any, ignoreDiscriminator: boolean): Dog { + if (json == null) { + return json; + } + return { + + 'kind': json['kind'], + 'barkCount': json['barkCount'], + 'tailLength': json['tailLength'], + 'breed': json['breed'] == null ? undefined : json['breed'], + }; +} + +export function DogToJSON(json: any): Dog { + return DogToJSONTyped(json, false); +} + +export function DogToJSONTyped(value?: Dog | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'kind': value['kind'], + 'barkCount': value['barkCount'], + 'tailLength': value['tailLength'], + 'breed': value['breed'], + }; +} + diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/MixedPet.ts b/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/MixedPet.ts new file mode 100644 index 000000000000..690999551d47 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/MixedPet.ts @@ -0,0 +1,109 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * anyOf as union + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { parseDate, parseDateTime, serializeDate, serializeDateTime } from '../runtime'; +import type { Dog } from './Dog'; +import { + instanceOfDog, + DogFromJSON, + DogFromJSONTyped, + DogToJSON, +} from './Dog'; +import type { Cat } from './Cat'; +import { + instanceOfCat, + CatFromJSON, + CatFromJSONTyped, + CatToJSON, +} from './Cat'; + +/** + * @type MixedPet + * + * @export + */ +export type MixedPet = Array | Cat | string; + +export function MixedPetFromJSON(json: any): MixedPet { + return MixedPetFromJSONTyped(json, false); +} + +export function MixedPetFromJSONTyped(json: any, ignoreDiscriminator: boolean): MixedPet { + if (json == null) { + return json; + } + if (typeof json === 'object') { + // anyOf: a value may match several members, so combine all of them instead of keeping the first match + let anyOfResult: any = {}; + let anyOfMatched = false; + if (instanceOfCat(json)) { + anyOfResult = { ...anyOfResult, ...CatFromJSONTyped(json, true) }; + anyOfMatched = true; + } + if (anyOfMatched) { + return anyOfResult; + } + } + if (Array.isArray(json)) { + if (json.every(item => item !== null && typeof item === 'object')) { + if (json.every(item => instanceOfDog(item))) { + return json.map(value => DogFromJSONTyped(value, true)); + } + } + } + if (Array.isArray(json)) { + return json; + } + if (typeof json === 'string') { + return json; + } + return {} as any; +} + +export function MixedPetToJSON(json: any): any { + return MixedPetToJSONTyped(json, false); +} + +export function MixedPetToJSONTyped(value?: MixedPet | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + if (typeof value === 'object') { + // anyOf: a value may match several members, so combine all of them instead of keeping the first match + let anyOfResult: any = {}; + let anyOfMatched = false; + if (instanceOfCat(value)) { + anyOfResult = { ...anyOfResult, ...CatToJSON(value as Cat) }; + anyOfMatched = true; + } + if (anyOfMatched) { + return anyOfResult; + } + } + if (Array.isArray(value)) { + if (value.every(item => item !== null && typeof item === 'object')) { + if (value.every(item => instanceOfDog(item))) { + return value.map(value => DogToJSON(value as Dog)); + } + } + } + if (Array.isArray(value)) { + return value; + } + if (typeof value === 'string') { + return value; + } + return {}; +} + diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/MultipleNullableValue.ts b/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/MultipleNullableValue.ts new file mode 100644 index 000000000000..78ad42ff2abb --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/MultipleNullableValue.ts @@ -0,0 +1,56 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * anyOf as union + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { parseDate, parseDateTime, serializeDate, serializeDateTime } from '../runtime'; +/** + * @type MultipleNullableValue + * + * @export + */ +export type MultipleNullableValue = null | number | string; + +export function MultipleNullableValueFromJSON(json: any): MultipleNullableValue { + return MultipleNullableValueFromJSONTyped(json, false); +} + +export function MultipleNullableValueFromJSONTyped(json: any, ignoreDiscriminator: boolean): MultipleNullableValue { + if (json == null) { + return json; + } + if (typeof json === 'number') { + return json; + } + if (typeof json === 'string') { + return json; + } + return {} as any; +} + +export function MultipleNullableValueToJSON(json: any): any { + return MultipleNullableValueToJSONTyped(json, false); +} + +export function MultipleNullableValueToJSONTyped(value?: MultipleNullableValue | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + if (typeof value === 'number') { + return value; + } + if (typeof value === 'string') { + return value; + } + return {}; +} + diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/NullableValue.ts b/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/NullableValue.ts new file mode 100644 index 000000000000..bd72c9f37696 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/NullableValue.ts @@ -0,0 +1,56 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * anyOf as union + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { parseDate, parseDateTime, serializeDate, serializeDateTime } from '../runtime'; +/** + * @type NullableValue + * + * @export + */ +export type NullableValue = null | number | string; + +export function NullableValueFromJSON(json: any): NullableValue { + return NullableValueFromJSONTyped(json, false); +} + +export function NullableValueFromJSONTyped(json: any, ignoreDiscriminator: boolean): NullableValue { + if (json == null) { + return json; + } + if (typeof json === 'number') { + return json; + } + if (typeof json === 'string') { + return json; + } + return {} as any; +} + +export function NullableValueToJSON(json: any): any { + return NullableValueToJSONTyped(json, false); +} + +export function NullableValueToJSONTyped(value?: NullableValue | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + if (typeof value === 'number') { + return value; + } + if (typeof value === 'string') { + return value; + } + return {}; +} + diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/OneOfModelAndDateTime.ts b/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/OneOfModelAndDateTime.ts new file mode 100644 index 000000000000..96b23f0fdd53 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/OneOfModelAndDateTime.ts @@ -0,0 +1,68 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * anyOf as union + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { parseDate, parseDateTime, serializeDate, serializeDateTime } from '../runtime'; +import type { Cat } from './Cat'; +import { + instanceOfCat, + CatFromJSON, + CatFromJSONTyped, + CatToJSON, +} from './Cat'; + +/** + * @type OneOfModelAndDateTime + * + * @export + */ +export type OneOfModelAndDateTime = Cat | Date; + +export function OneOfModelAndDateTimeFromJSON(json: any): OneOfModelAndDateTime { + return OneOfModelAndDateTimeFromJSONTyped(json, false); +} + +export function OneOfModelAndDateTimeFromJSONTyped(json: any, ignoreDiscriminator: boolean): OneOfModelAndDateTime { + if (json == null) { + return json; + } + if (typeof json === 'object') { + if (instanceOfCat(json)) { + return CatFromJSONTyped(json, true); + } + } + if (!(isNaN(parseDateTime(json).getTime()))) { + return json == null ? undefined : (parseDateTime(json)); + } + return {} as any; +} + +export function OneOfModelAndDateTimeToJSON(json: any): any { + return OneOfModelAndDateTimeToJSONTyped(json, false); +} + +export function OneOfModelAndDateTimeToJSONTyped(value?: OneOfModelAndDateTime | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + if (typeof value === 'object') { + if (instanceOfCat(value)) { + return CatToJSON(value as Cat); + } + } + if (value instanceof Date) { + return value == null ? undefined : (serializeDateTime(value)); + } + return {}; +} + diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/OneOfModelAndEnum.ts b/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/OneOfModelAndEnum.ts new file mode 100644 index 000000000000..26f1d6f70711 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/OneOfModelAndEnum.ts @@ -0,0 +1,75 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * anyOf as union + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { parseDate, parseDateTime, serializeDate, serializeDateTime } from '../runtime'; +import type { Cat } from './Cat'; +import { + instanceOfCat, + CatFromJSON, + CatFromJSONTyped, + CatToJSON, +} from './Cat'; +import type { Color } from './Color'; +import { + instanceOfColor, + ColorFromJSON, + ColorFromJSONTyped, + ColorToJSON, +} from './Color'; + +/** + * @type OneOfModelAndEnum + * + * @export + */ +export type OneOfModelAndEnum = Cat | Color; + +export function OneOfModelAndEnumFromJSON(json: any): OneOfModelAndEnum { + return OneOfModelAndEnumFromJSONTyped(json, false); +} + +export function OneOfModelAndEnumFromJSONTyped(json: any, ignoreDiscriminator: boolean): OneOfModelAndEnum { + if (json == null) { + return json; + } + if (typeof json === 'object') { + if (instanceOfCat(json)) { + return CatFromJSONTyped(json, true); + } + } + if (instanceOfColor(json)) { + return ColorFromJSONTyped(json, true); + } + return {} as any; +} + +export function OneOfModelAndEnumToJSON(json: any): any { + return OneOfModelAndEnumToJSONTyped(json, false); +} + +export function OneOfModelAndEnumToJSONTyped(value?: OneOfModelAndEnum | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + if (typeof value === 'object') { + if (instanceOfCat(value)) { + return CatToJSON(value as Cat); + } + } + if (instanceOfColor(value)) { + return ColorToJSON(value as Color); + } + return {}; +} + diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/PetData.ts b/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/PetData.ts new file mode 100644 index 000000000000..ca1c29b93aa6 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/PetData.ts @@ -0,0 +1,91 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * anyOf as union + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { parseDate, parseDateTime, serializeDate, serializeDateTime } from '../runtime'; +import type { Cat } from './Cat'; +import { + instanceOfCat, + CatFromJSON, + CatFromJSONTyped, + CatToJSON, +} from './Cat'; +import type { Dog } from './Dog'; +import { + instanceOfDog, + DogFromJSON, + DogFromJSONTyped, + DogToJSON, +} from './Dog'; + +/** + * @type PetData + * + * @export + */ +export type PetData = Cat | Dog; + +export function PetDataFromJSON(json: any): PetData { + return PetDataFromJSONTyped(json, false); +} + +export function PetDataFromJSONTyped(json: any, ignoreDiscriminator: boolean): PetData { + if (json == null) { + return json; + } + if (typeof json === 'object') { + // anyOf: a value may match several members, so combine all of them instead of keeping the first match + let anyOfResult: any = {}; + let anyOfMatched = false; + if (instanceOfCat(json)) { + anyOfResult = { ...anyOfResult, ...CatFromJSONTyped(json, true) }; + anyOfMatched = true; + } + if (instanceOfDog(json)) { + anyOfResult = { ...anyOfResult, ...DogFromJSONTyped(json, true) }; + anyOfMatched = true; + } + if (anyOfMatched) { + return anyOfResult; + } + } + return {} as any; +} + +export function PetDataToJSON(json: any): any { + return PetDataToJSONTyped(json, false); +} + +export function PetDataToJSONTyped(value?: PetData | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + if (typeof value === 'object') { + // anyOf: a value may match several members, so combine all of them instead of keeping the first match + let anyOfResult: any = {}; + let anyOfMatched = false; + if (instanceOfCat(value)) { + anyOfResult = { ...anyOfResult, ...CatToJSON(value as Cat) }; + anyOfMatched = true; + } + if (instanceOfDog(value)) { + anyOfResult = { ...anyOfResult, ...DogToJSON(value as Dog) }; + anyOfMatched = true; + } + if (anyOfMatched) { + return anyOfResult; + } + } + return {}; +} + diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/index.ts b/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/index.ts new file mode 100644 index 000000000000..5e9b105ab02d --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/src/models/index.ts @@ -0,0 +1,16 @@ +/* tslint:disable */ +/* eslint-disable */ +export * from './AnyOfWithProperties'; +export * from './Cat'; +export * from './Color'; +export * from './CreatePet'; +export * from './CreatePetContent'; +export * from './CreatePetData'; +export * from './DiscriminatedPet'; +export * from './Dog'; +export * from './MixedPet'; +export * from './MultipleNullableValue'; +export * from './NullableValue'; +export * from './OneOfModelAndDateTime'; +export * from './OneOfModelAndEnum'; +export * from './PetData'; diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/src/runtime.ts b/samples/client/petstore/typescript-fetch/builds/any-of-union/src/runtime.ts new file mode 100644 index 000000000000..dfd140a7b89f --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/src/runtime.ts @@ -0,0 +1,572 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * anyOf as union + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +export const BASE_PATH: string = "http://localhost".replace(/\/+$/, ""); + +export interface ConfigurationParameters { + basePath?: string; // override base path + fetchApi?: FetchAPI; // override for fetch implementation + middleware?: Middleware[]; // middleware to apply before/after fetch requests + queryParamsStringify?: (params: HTTPQuery) => string; // stringify function for query strings + username?: string; // parameter for basic security + password?: string; // parameter for basic security + apiKey?: string | Promise | ((name: string) => string | Promise); // parameter for apiKey security + accessToken?: string | Promise | ((name?: string, scopes?: string[]) => string | Promise); // parameter for oauth2 security + headers?: HTTPHeaders; //header params we want to use on every request + credentials?: RequestCredentials; //value for the credentials param we want to use on each request +} + +export class Configuration { + constructor(private configuration: ConfigurationParameters = {}) {} + + set config(configuration: Configuration) { + this.configuration = configuration; + } + + get basePath(): string { + return this.configuration.basePath != null ? this.configuration.basePath : BASE_PATH; + } + + get fetchApi(): FetchAPI | undefined { + return this.configuration.fetchApi; + } + + get middleware(): Middleware[] { + return this.configuration.middleware || []; + } + + get queryParamsStringify(): (params: HTTPQuery) => string { + return this.configuration.queryParamsStringify || querystring; + } + + get username(): string | undefined { + return this.configuration.username; + } + + get password(): string | undefined { + return this.configuration.password; + } + + get apiKey(): ((name: string) => string | Promise) | undefined { + const apiKey = this.configuration.apiKey; + if (apiKey) { + return typeof apiKey === 'function' ? apiKey : () => apiKey; + } + return undefined; + } + + get accessToken(): ((name?: string, scopes?: string[]) => string | Promise) | undefined { + const accessToken = this.configuration.accessToken; + if (accessToken) { + return typeof accessToken === 'function' ? accessToken : async () => accessToken; + } + return undefined; + } + + get headers(): HTTPHeaders | undefined { + return this.configuration.headers; + } + + get credentials(): RequestCredentials | undefined { + return this.configuration.credentials; + } +} + +export const DefaultConfig: Configuration = new Configuration(); + +/** + * This is the base class for all generated API classes. + */ +export class BaseAPI { + + private static readonly jsonRegex = /^(:?application\/json|[^;/ \t]+\/[^;/ \t]+[+]json)[ \t]*(:?;.*)?$/i; + private middleware: Middleware[]; + + constructor(protected configuration: Configuration = DefaultConfig) { + this.middleware = configuration.middleware; + } + + withMiddleware(this: T, ...middlewares: Middleware[]): T { + const next = this.clone(); + next.middleware = next.middleware.concat(...middlewares); + return next; + } + + withPreMiddleware(this: T, ...preMiddlewares: Array): T { + const middlewares = preMiddlewares.map((pre) => ({ pre })); + return this.withMiddleware(...middlewares); + } + + withPostMiddleware(this: T, ...postMiddlewares: Array): T { + const middlewares = postMiddlewares.map((post) => ({ post })); + return this.withMiddleware(...middlewares); + } + + /** + * Check if the given MIME is a JSON MIME. + * JSON MIME examples: + * application/json + * application/json; charset=UTF8 + * APPLICATION/JSON + * application/vnd.company+json + * @param mime - MIME (Multipurpose Internet Mail Extensions) + * @return True if the given MIME is JSON, false otherwise. + */ + protected isJsonMime(mime: string | null | undefined): boolean { + if (!mime) { + return false; + } + return BaseAPI.jsonRegex.test(mime); + } + + protected async request(context: RequestOpts, initOverrides?: RequestInit | InitOverrideFunction): Promise { + const { url, init } = await this.createFetchParams(context, initOverrides); + const response = await this.fetchApi(url, init); + if (response && (response.status >= 200 && response.status < 300)) { + return response; + } + throw new ResponseError(response, 'Response returned an error code'); + } + + private async createFetchParams(context: RequestOpts, initOverrides?: RequestInit | InitOverrideFunction) { + let url = this.configuration.basePath + context.path; + if (context.query !== undefined && Object.keys(context.query).length !== 0) { + // only add the querystring to the URL if there are query parameters. + // this is done to avoid urls ending with a "?" character which buggy webservers + // do not handle correctly sometimes. + url += '?' + this.configuration.queryParamsStringify(context.query); + } + + const headers = Object.assign({}, this.configuration.headers, context.headers); + Object.keys(headers).forEach(key => headers[key] === undefined ? delete headers[key] : {}); + + const initOverrideFn = + typeof initOverrides === "function" + ? initOverrides + : async () => initOverrides; + + const initParams = { + method: context.method, + headers, + body: context.body, + credentials: this.configuration.credentials, + }; + + const overriddenInit: RequestInit = { + ...initParams, + ...(await initOverrideFn({ + init: initParams, + context, + })) + }; + + let body: any; + if (isFormData(overriddenInit.body) + || (overriddenInit.body instanceof URLSearchParams) + || isBlob(overriddenInit.body)) { + body = overriddenInit.body; + } else if (this.isJsonMime(headers['Content-Type'])) { + body = JSON.stringify(overriddenInit.body); + } else { + body = overriddenInit.body; + } + + const init: RequestInit = { + ...overriddenInit, + body + }; + + return { url, init }; + } + + private fetchApi = async (url: string, init: RequestInit) => { + let fetchParams = { url, init }; + for (const middleware of this.middleware) { + if (middleware.pre) { + fetchParams = await middleware.pre({ + fetch: this.fetchApi, + ...fetchParams, + }) || fetchParams; + } + } + let response: Response | undefined = undefined; + try { + response = await (this.configuration.fetchApi || fetch)(fetchParams.url, fetchParams.init); + } catch (e) { + for (const middleware of this.middleware) { + if (middleware.onError) { + response = await middleware.onError({ + fetch: this.fetchApi, + url: fetchParams.url, + init: fetchParams.init, + error: e, + response: response ? response.clone() : undefined, + }) || response; + } + } + if (response === undefined) { + if (e instanceof Error) { + throw new FetchError(e, 'The request failed and the interceptors did not return an alternative response'); + } else { + throw e; + } + } + } + for (const middleware of this.middleware) { + if (middleware.post) { + response = await middleware.post({ + fetch: this.fetchApi, + url: fetchParams.url, + init: fetchParams.init, + response: response.clone(), + }) || response; + } + } + return response; + } + + /** + * Create a shallow clone of `this` by constructing a new instance + * and then shallow cloning data members. + */ + private clone(this: T): T { + const constructor = this.constructor as any; + const next = new constructor(this.configuration); + next.middleware = this.middleware.slice(); + return next; + } +}; + +function isBlob(value: any): value is Blob { + return typeof Blob !== 'undefined' && value instanceof Blob; +} + +function isFormData(value: any): value is FormData { + return typeof FormData !== "undefined" && value instanceof FormData; +} + +export class ResponseError extends Error { + override name: "ResponseError" = "ResponseError"; + constructor(public response: Response, msg?: string) { + super(msg); + + // restore prototype chain + const actualProto = new.target.prototype; + if (Object.setPrototypeOf) { + Object.setPrototypeOf(this, actualProto); + } + } +} + +export class FetchError extends Error { + override name: "FetchError" = "FetchError"; + constructor(public cause: Error, msg?: string) { + super(msg); + + // restore prototype chain + const actualProto = new.target.prototype; + if (Object.setPrototypeOf) { + Object.setPrototypeOf(this, actualProto); + } + } +} + +export class RequiredError extends Error { + override name: "RequiredError" = "RequiredError"; + constructor(public field: string, msg?: string) { + super(msg); + + // restore prototype chain + const actualProto = new.target.prototype; + if (Object.setPrototypeOf) { + Object.setPrototypeOf(this, actualProto); + } + } +} + +export const COLLECTION_FORMATS = { + csv: ",", + ssv: " ", + tsv: "\t", + pipes: "|", +}; + +export type FetchAPI = WindowOrWorkerGlobalScope['fetch']; + +export type Json = any; +export type HTTPMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'OPTIONS' | 'HEAD'; +export type HTTPHeaders = { [key: string]: string }; +export type HTTPQuery = { [key: string]: string | number | null | boolean | Array | Set | HTTPQuery }; +export type HTTPBody = Json | FormData | URLSearchParams; +export type HTTPRequestInit = { headers?: HTTPHeaders; method: HTTPMethod; credentials?: RequestCredentials; body?: HTTPBody }; +export type ModelPropertyNaming = 'camelCase' | 'snake_case' | 'PascalCase' | 'original'; + +export type InitOverrideFunction = (requestContext: { init: HTTPRequestInit, context: RequestOpts }) => Promise + +export interface FetchParams { + url: string; + init: RequestInit; +} + +export interface RequestOpts { + path: string; + method: HTTPMethod; + headers: HTTPHeaders; + query?: HTTPQuery; + body?: HTTPBody; +} + +export function querystring(params: HTTPQuery, prefix: string = ''): string { + return Object.keys(params) + .map(key => querystringSingleKey(key, params[key], prefix)) + .filter(part => part.length > 0) + .join('&'); +} + +function querystringSingleKey(key: string, value: string | number | null | undefined | boolean | Array | Set | HTTPQuery, keyPrefix: string = ''): string { + const fullKey = keyPrefix + (keyPrefix.length ? `[${key}]` : key); + if (value instanceof Array) { + const multiValue = value.map(singleValue => encodeURIComponent(String(singleValue))) + .join(`&${encodeURIComponent(fullKey)}=`); + return `${encodeURIComponent(fullKey)}=${multiValue}`; + } + if (value instanceof Set) { + const valueAsArray = Array.from(value); + return querystringSingleKey(key, valueAsArray, keyPrefix); + } + if (value instanceof Date) { + return `${encodeURIComponent(fullKey)}=${encodeURIComponent(serializeDateTime(value))}`; + } + if (value instanceof Object) { + return querystring(value as HTTPQuery, fullKey); + } + return `${encodeURIComponent(fullKey)}=${encodeURIComponent(String(value))}`; +} + +export function exists(json: any, key: string): boolean { + const value = json[key]; + return value !== null && value !== undefined; +} + +/** + * Every generated date call site routes through these. + * + * `format: date` is a calendar date, with no time and no offset, so it is converted + * against the local calendar on both ends: they have to agree or the date shifts by + * a day. `format: date-time` is an instant and uses UTC. + */ +export function serializeDateTime(value: Date): string { + return value.toISOString(); +} + +export function serializeDate(value: Date): string { + if (isNaN(value.getTime())) { + throw new RangeError('Invalid time value'); + } + const year = ('000' + value.getFullYear()).slice(-4); + const month = ('0' + (value.getMonth() + 1)).slice(-2); + const day = ('0' + value.getDate()).slice(-2); + return `${year}-${month}-${day}`; +} + + +export function parseDate(value: Date | string): Date { + if (value instanceof Date) { + return value; + } + // `new Date("2026-08-05")` would parse as UTC midnight: a different day west of UTC. + // Local midnight is the stated day everywhere. setFullYear avoids the 1900 offset the + // multi-argument constructor applies to years 0-99. + const fullDate = /^(\d{4})-(\d{2})-(\d{2})$/.exec(String(value)); + if (fullDate) { + const year = Number(fullDate[1]); + const month = Number(fullDate[2]) - 1; + const day = Number(fullDate[3]); + const date = new Date(0); + date.setFullYear(year, month, day); + date.setHours(0, 0, 0, 0); + // Out-of-range components (or a day the local zone skipped) silently roll over, + // which would hand back a date the server never sent. + if (date.getFullYear() !== year || date.getMonth() !== month || date.getDate() !== day) { + return new Date(NaN); + } + return date; + } + return new Date(value); +} + +export function parseDateTime(value: any): Date { + return new Date(value); +} + +export function mapValues(data: any, fn: (item: any) => any): { [key: string]: any } { + const result: { [key: string]: any } = {}; + for (const key of Object.keys(data)) { + result[key] = fn(data[key]); + } + return result; +} + +// Pass-through serializer for `any`-typed properties in form data. See #1877. +export function anyToJSON(value: any): any { + return value; +} + +export function canConsumeForm(consumes: Consume[]): boolean { + for (const consume of consumes) { + if (consume.contentType?.startsWith('multipart/form-data') == true) { + return true; + } + } + return false; +} + +export interface Consume { + contentType: string; +} + +export interface RequestContext { + fetch: FetchAPI; + url: string; + init: RequestInit; +} + +export interface ResponseContext { + fetch: FetchAPI; + url: string; + init: RequestInit; + response: Response; +} + +export interface ErrorContext { + fetch: FetchAPI; + url: string; + init: RequestInit; + error: unknown; + response?: Response; +} + +export interface Middleware { + pre?(context: RequestContext): Promise; + post?(context: ResponseContext): Promise; + onError?(context: ErrorContext): Promise; +} + +export interface ApiResponse { + raw: Response; + value(): Promise; +} + +export interface ResponseTransformer { + (json: any): T; +} + +export class JSONApiResponse { + constructor(public raw: Response, private transformer: ResponseTransformer = (jsonValue: any) => jsonValue) {} + + async value(): Promise { + return this.transformer(await this.raw.json()); + } +} + +export class VoidApiResponse { + constructor(public raw: Response) {} + + async value(): Promise { + return undefined; + } +} + +/** + * A Blob carrying the file name the server advertised, empty when it did not send one. It is a File + * wherever one can be built, and the bare Blob given a name otherwise. Same name and shape as the + * `typescript` generator's browser HttpFile. + */ +export type HttpFile = Blob & { readonly name: string }; + +export class BlobApiResponse { + constructor(public raw: Response) {} + + /** + * The body named after the Content-Disposition header, so that a download keeps the name the + * server gave it. A File is built from a native Blob; the Blob itself is named where there is no + * global File (Node.js before 20), where File cannot be constructed, or where the Blob is not the + * native one, as returned by an injected fetch implementation such as node-fetch, which a File + * would stringify instead of wrapping. + */ + async value(): Promise { + const blob = await this.raw.blob(); + const name = parseContentDispositionFilename(this.raw.headers) ?? ''; + if (typeof File !== 'undefined' && blob instanceof Blob) { + try { + return new File([blob], name, { type: blob.type }); + } catch { + // File cannot be constructed: name the Blob itself + } + } + return Object.assign(blob, { name }); + }; +} + +/** + * The file name advertised by a Content-Disposition header (RFC 6266): the RFC 5987 encoded + * `filename*` parameter first, falling back to the plain `filename` when it is malformed, not UTF-8 + * or has no usable name. Any directory part is dropped; undefined when no usable name is advertised. + */ +export function parseContentDispositionFilename(headers: Headers): string | undefined { + const params = parseHeaderParameters(headers.get('Content-Disposition') ?? ''); + return basename(decodeExtValue(params.get('filename*'))) ?? basename(params.get('filename')); +} + +/** The decoded RFC 5987 ext-value, or undefined when it is not UTF-8 or its percent-encoding is malformed. */ +function decodeExtValue(value: string | undefined): string | undefined { + const match = value === undefined ? null : /^utf-8'[^']*'(.*)$/i.exec(value); + try { + return match ? decodeURIComponent(match[1]) : undefined; + } catch { + return undefined; + } +} + +/** + * The `name=value` parameters of a header value, consumed one at a time so that a quoted-string is + * taken whole, `;` included. Names are lower-cased, quoted-string values are unquoted with their + * backslash escapes resolved, and the first occurrence of a name wins. + */ +function parseHeaderParameters(value: string): Map { + const params = new Map(); + const parameter = /(?:^|;)\s*([^=;]+?)\s*=\s*(?:"((?:[^"\\]|\\.)*)"?|([^;]*))/g; + let match: RegExpExecArray | null; + while ((match = parameter.exec(value)) !== null) { + const name = match[1].toLowerCase(); + if (!params.has(name)) { + params.set(name, match[2] !== undefined ? match[2].replace(/\\(.)/g, '$1') : match[3].trim()); + } + } + return params; +} + +/** The last `/` or `\` separated segment of a file name, or undefined when it is not a file name. */ +function basename(name: string | undefined): string | undefined { + const base = name?.split(/[\\/]/).pop(); + return !base || base === '.' || base === '..' ? undefined : base; +} + +export class TextApiResponse { + constructor(public raw: Response) {} + + async value(): Promise { + return await this.raw.text(); + }; +} diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/tsconfig.esm.json b/samples/client/petstore/typescript-fetch/builds/any-of-union/tsconfig.esm.json new file mode 100644 index 000000000000..2c0331cce040 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/tsconfig.esm.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "module": "esnext", + "outDir": "dist/esm" + } +} diff --git a/samples/client/petstore/typescript-fetch/builds/any-of-union/tsconfig.json b/samples/client/petstore/typescript-fetch/builds/any-of-union/tsconfig.json new file mode 100644 index 000000000000..f1d5adffdbf7 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/any-of-union/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "declaration": true, + "target": "es6", + "module": "commonjs", + "outDir": "dist", + "rootDir": "src", + "typeRoots": [ + "node_modules/@types" + ] + }, + "exclude": [ + "dist", + "node_modules" + ] +} diff --git a/samples/client/petstore/typescript-fetch/builds/oneOf-not-enum/src/models/TaggedUnion.ts b/samples/client/petstore/typescript-fetch/builds/oneOf-not-enum/src/models/TaggedUnion.ts index 79bf6d115811..c040122c9a3f 100644 --- a/samples/client/petstore/typescript-fetch/builds/oneOf-not-enum/src/models/TaggedUnion.ts +++ b/samples/client/petstore/typescript-fetch/builds/oneOf-not-enum/src/models/TaggedUnion.ts @@ -43,14 +43,13 @@ export function TaggedUnionFromJSONTyped(json: any, ignoreDiscriminator: boolean if (json == null) { return json; } - if (typeof json !== 'object') { - return json; - } - if (instanceOfKnown(json)) { - return KnownFromJSONTyped(json, true); - } - if (instanceOfOther(json)) { - return OtherFromJSONTyped(json, true); + if (typeof json === 'object') { + if (instanceOfKnown(json)) { + return KnownFromJSONTyped(json, true); + } + if (instanceOfOther(json)) { + return OtherFromJSONTyped(json, true); + } } return {} as any; } @@ -63,14 +62,13 @@ export function TaggedUnionToJSONTyped(value?: TaggedUnion | null, ignoreDiscrim if (value == null) { return value; } - if (typeof value !== 'object') { - return value; - } - if (instanceOfKnown(value)) { - return KnownToJSON(value as Known); - } - if (instanceOfOther(value)) { - return OtherToJSON(value as Other); + if (typeof value === 'object') { + if (instanceOfKnown(value)) { + return KnownToJSON(value as Known); + } + if (instanceOfOther(value)) { + return OtherToJSON(value as Other); + } } return {}; } diff --git a/samples/client/petstore/typescript-fetch/builds/oneOf/models/TestArrayResponse.ts b/samples/client/petstore/typescript-fetch/builds/oneOf/models/TestArrayResponse.ts index af3bbd2a6269..378b1b6771ad 100644 --- a/samples/client/petstore/typescript-fetch/builds/oneOf/models/TestArrayResponse.ts +++ b/samples/client/petstore/typescript-fetch/builds/oneOf/models/TestArrayResponse.ts @@ -44,7 +44,7 @@ export function TestArrayResponseFromJSONTyped(json: any, ignoreDiscriminator: b return json; } if (Array.isArray(json)) { - if (json.every(item => typeof item === 'object')) { + if (json.every(item => item !== null && typeof item === 'object')) { if (json.every(item => instanceOfTestA(item))) { return json.map(value => TestAFromJSONTyped(value, true)); } @@ -73,7 +73,7 @@ export function TestArrayResponseToJSONTyped(value?: TestArrayResponse | null, i return value; } if (Array.isArray(value)) { - if (value.every(item => typeof item === 'object')) { + if (value.every(item => item !== null && typeof item === 'object')) { if (value.every(item => instanceOfTestA(item))) { return value.map(value => TestAToJSON(value as TestA)); } diff --git a/samples/client/petstore/typescript-fetch/builds/oneOf/models/TestResponse.ts b/samples/client/petstore/typescript-fetch/builds/oneOf/models/TestResponse.ts index ca45996d992e..bbcfec3b4397 100644 --- a/samples/client/petstore/typescript-fetch/builds/oneOf/models/TestResponse.ts +++ b/samples/client/petstore/typescript-fetch/builds/oneOf/models/TestResponse.ts @@ -43,14 +43,13 @@ export function TestResponseFromJSONTyped(json: any, ignoreDiscriminator: boolea if (json == null) { return json; } - if (typeof json !== 'object') { - return json; - } - if (instanceOfTestA(json)) { - return TestAFromJSONTyped(json, true); - } - if (instanceOfTestB(json)) { - return TestBFromJSONTyped(json, true); + if (typeof json === 'object') { + if (instanceOfTestA(json)) { + return TestAFromJSONTyped(json, true); + } + if (instanceOfTestB(json)) { + return TestBFromJSONTyped(json, true); + } } if (typeof json === 'string') { return json; @@ -66,14 +65,13 @@ export function TestResponseToJSONTyped(value?: TestResponse | null, ignoreDiscr if (value == null) { return value; } - if (typeof value !== 'object') { - return value; - } - if (instanceOfTestA(value)) { - return TestAToJSON(value as TestA); - } - if (instanceOfTestB(value)) { - return TestBToJSON(value as TestB); + if (typeof value === 'object') { + if (instanceOfTestA(value)) { + return TestAToJSON(value as TestA); + } + if (instanceOfTestB(value)) { + return TestBToJSON(value as TestB); + } } if (typeof value === 'string') { return value;