mirror of
https://github.com/OpenAPITools/openapi-generator.git
synced 2026-01-07 04:47:07 +00:00
Compare commits
25 Commits
jdk21-test
...
autofix-sc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e6f94c5d8b | ||
|
|
816befc466 | ||
|
|
3d00fd2adc | ||
|
|
00d16496c8 | ||
|
|
57752d190c | ||
|
|
6572d5d9a6 | ||
|
|
c15ba67fc9 | ||
|
|
63ddce0c1b | ||
|
|
01139e6963 | ||
|
|
e7dae1a81e | ||
|
|
4e7bba659b | ||
|
|
88bba259e9 | ||
|
|
8c85e3cedc | ||
|
|
d840c495c4 | ||
|
|
7c000687e4 | ||
|
|
23a2aafe91 | ||
|
|
2afe7d29cd | ||
|
|
6ede03d546 | ||
|
|
ee85775afd | ||
|
|
94e8997cc7 | ||
|
|
552ab4c6d5 | ||
|
|
2b00bab60a | ||
|
|
ccd43a5ce4 | ||
|
|
592c262277 | ||
|
|
40b9d69d5a |
1
.github/workflows/gradle-plugin-tests.yaml
vendored
1
.github/workflows/gradle-plugin-tests.yaml
vendored
@@ -19,6 +19,7 @@ jobs:
|
||||
with:
|
||||
java-version: 11
|
||||
distribution: 'temurin'
|
||||
cache: gradle
|
||||
- name: Cache maven dependencies
|
||||
uses: actions/cache@v4
|
||||
env:
|
||||
|
||||
1
.github/workflows/gradle-test.yaml
vendored
1
.github/workflows/gradle-test.yaml
vendored
@@ -37,6 +37,7 @@ jobs:
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 11
|
||||
cache: gradle
|
||||
# Cache Gradle Dependencies
|
||||
- name: Setup Gradle Dependencies Cache
|
||||
uses: actions/cache@v4
|
||||
|
||||
2
.github/workflows/linux.yaml
vendored
2
.github/workflows/linux.yaml
vendored
@@ -27,6 +27,7 @@ jobs:
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: ${{ matrix.java }}
|
||||
cache: gradle
|
||||
|
||||
- uses: actions/cache@v4
|
||||
with:
|
||||
@@ -95,6 +96,7 @@ jobs:
|
||||
with:
|
||||
java-version: 11
|
||||
maven-version: 3.8.8
|
||||
cache: gradle
|
||||
- name: Download build artifact
|
||||
uses: actions/download-artifact@v5
|
||||
with:
|
||||
|
||||
2
.github/workflows/openapi-generator.yaml
vendored
2
.github/workflows/openapi-generator.yaml
vendored
@@ -21,6 +21,7 @@ jobs:
|
||||
with:
|
||||
java-version: 11
|
||||
distribution: 'temurin'
|
||||
cache: gradle
|
||||
- name: Cache maven dependencies
|
||||
uses: actions/cache@v4
|
||||
env:
|
||||
@@ -59,6 +60,7 @@ jobs:
|
||||
with:
|
||||
java-version: 11
|
||||
distribution: 'temurin'
|
||||
cache: gradle
|
||||
- name: Cache maven dependencies
|
||||
uses: actions/cache@v4
|
||||
env:
|
||||
|
||||
1
.github/workflows/samples-groovy.yaml
vendored
1
.github/workflows/samples-groovy.yaml
vendored
@@ -26,6 +26,7 @@ jobs:
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 8
|
||||
cache: gradle
|
||||
- name: Cache maven dependencies
|
||||
uses: actions/cache@v4
|
||||
env:
|
||||
|
||||
@@ -118,6 +118,7 @@ jobs:
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 11
|
||||
cache: gradle
|
||||
- name: Cache maven dependencies
|
||||
uses: actions/cache@v4
|
||||
env:
|
||||
|
||||
@@ -42,6 +42,7 @@ jobs:
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 17
|
||||
cache: gradle
|
||||
- name: Cache maven dependencies
|
||||
uses: actions/cache@v4
|
||||
env:
|
||||
|
||||
1
.github/workflows/samples-kotlin-client.yaml
vendored
1
.github/workflows/samples-kotlin-client.yaml
vendored
@@ -77,6 +77,7 @@ jobs:
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 11
|
||||
cache: gradle
|
||||
- name: Cache maven dependencies
|
||||
uses: actions/cache@v4
|
||||
env:
|
||||
|
||||
@@ -26,6 +26,7 @@ jobs:
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 17
|
||||
cache: gradle
|
||||
- name: Cache maven dependencies
|
||||
uses: actions/cache@v4
|
||||
env:
|
||||
|
||||
@@ -52,6 +52,7 @@ jobs:
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 17
|
||||
cache: gradle
|
||||
- name: Cache maven dependencies
|
||||
uses: actions/cache@v4
|
||||
env:
|
||||
|
||||
@@ -32,6 +32,7 @@ jobs:
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 21
|
||||
cache: gradle
|
||||
- name: Cache maven dependencies
|
||||
uses: actions/cache@v4
|
||||
env:
|
||||
|
||||
3
.github/workflows/samples-kotlin-server.yaml
vendored
3
.github/workflows/samples-kotlin-server.yaml
vendored
@@ -59,7 +59,8 @@ jobs:
|
||||
- uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 8
|
||||
java-version: 11
|
||||
cache: gradle
|
||||
- name: Cache maven dependencies
|
||||
uses: actions/cache@v4
|
||||
env:
|
||||
|
||||
1
.github/workflows/windows.yaml
vendored
1
.github/workflows/windows.yaml
vendored
@@ -24,6 +24,7 @@ jobs:
|
||||
with:
|
||||
java-version: ${{ matrix.java }}
|
||||
distribution: 'temurin'
|
||||
cache: gradle
|
||||
- name: Cache maven dependencies
|
||||
uses: actions/cache@v4
|
||||
env:
|
||||
|
||||
@@ -538,6 +538,7 @@ OpenAPI Normalizer transforms the input OpenAPI doc/spec (which may not perfectl
|
||||
|
||||
- SIMPLIFY_ONEOF_ANYOF
|
||||
- SIMPLIFY_BOOLEAN_ENUM
|
||||
- REFACTOR_ALLOF_WITH_PROPERTIES_ONLY
|
||||
|
||||
(One can use `DISABLE_ALL=true` to disable all the rules)
|
||||
|
||||
@@ -645,7 +646,7 @@ java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generat
|
||||
|
||||
- `FILTER`
|
||||
|
||||
The `FILTER` parameter allows selective inclusion of API operations based on specific criteria. It applies the `x-internal: true` property to operations that do **not** match the specified values, preventing them from being generated.
|
||||
The `FILTER` parameter allows selective inclusion of API operations based on specific criteria. It applies the `x-internal: true` property to operations that do **not** match the specified values, preventing them from being generated. Multiple filters can be separated by a semicolon.
|
||||
|
||||
### Available Filters
|
||||
|
||||
@@ -658,6 +659,9 @@ The `FILTER` parameter allows selective inclusion of API operations based on spe
|
||||
- **`tag`**
|
||||
When set to `tag:person|basic`, operations **not** tagged with `person` or `basic` will be marked as internal (`x-internal: true`), and will not be generated.
|
||||
|
||||
- **`path`**
|
||||
When set to `path:/v1|/v2`, operations on paths **not** starting with `/v1` or with `/v2` will be marked as internal (`x-internal: true`), and will not be generated.
|
||||
|
||||
### Example Usage
|
||||
|
||||
```sh
|
||||
@@ -665,7 +669,7 @@ java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generat
|
||||
-g java \
|
||||
-i modules/openapi-generator/src/test/resources/3_0/petstore.yaml \
|
||||
-o /tmp/java-okhttp/ \
|
||||
--openapi-normalizer FILTER="operationId:addPet|getPetById"
|
||||
--openapi-normalizer FILTER="operationId:addPet|getPetById ; tag:store"
|
||||
```
|
||||
|
||||
- `SET_CONTAINER_TO_NULLABLE`: When set to `array|set|map` (or just `array`) for example, it will set `nullable` in array, set and map to true.
|
||||
|
||||
@@ -3,6 +3,7 @@ id: generators
|
||||
title: Generators List
|
||||
---
|
||||
|
||||
[main] INFO o.o.c.l.PythonFastAPIServerCodegen - Skipping sorting of path operations, order matters, let the developer decide via their specification file.
|
||||
The following generators are available:
|
||||
|
||||
## CLIENT generators
|
||||
|
||||
@@ -133,6 +133,9 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|
||||
|x-spring-paginated|Add `org.springframework.data.domain.Pageable` to controller method. Can be used to handle `page`, `size` and `sort` query parameters. If these query parameters are also specified in the operation spec, they will be removed from the controller method as their values can be obtained from the `Pageable` object.|OPERATION|false
|
||||
|x-version-param|Marker property that tells that this parameter would be used for endpoint versioning. Applicable for headers & query params. true/false|OPERATION_PARAMETER|null
|
||||
|x-pattern-message|Add this property whenever you need to customize the invalidation error message for the regex pattern of a variable|FIELD, OPERATION_PARAMETER|null
|
||||
|x-size-message|Add this property whenever you need to customize the invalidation error message for the size or length of a variable|FIELD, OPERATION_PARAMETER|null
|
||||
|x-minimum-message|Add this property whenever you need to customize the invalidation error message for the minimum value of a variable|FIELD, OPERATION_PARAMETER|null
|
||||
|x-maximum-message|Add this property whenever you need to customize the invalidation error message for the maximum value of a variable|FIELD, OPERATION_PARAMETER|null
|
||||
|x-spring-api-version|Value for 'version' attribute in @RequestMapping (for Spring 7 and above).|OPERATION|null
|
||||
|
||||
|
||||
|
||||
@@ -67,6 +67,9 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|
||||
|x-discriminator-value|Used with model inheritance to specify value for discriminator that identifies current model|MODEL|
|
||||
|x-field-extra-annotation|List of custom annotations to be added to property|FIELD, OPERATION_PARAMETER|null
|
||||
|x-pattern-message|Add this property whenever you need to customize the invalidation error message for the regex pattern of a variable|FIELD, OPERATION_PARAMETER|null
|
||||
|x-size-message|Add this property whenever you need to customize the invalidation error message for the size or length of a variable|FIELD, OPERATION_PARAMETER|null
|
||||
|x-minimum-message|Add this property whenever you need to customize the invalidation error message for the minimum value of a variable|FIELD, OPERATION_PARAMETER|null
|
||||
|x-maximum-message|Add this property whenever you need to customize the invalidation error message for the maximum value of a variable|FIELD, OPERATION_PARAMETER|null
|
||||
|x-kotlin-implements|Ability to specify interfaces that model must implement|MODEL|empty array
|
||||
|x-kotlin-implements-fields|Specify attributes that are implemented by the interface(s) added via `x-kotlin-implements`|MODEL|empty array
|
||||
|
||||
|
||||
@@ -126,6 +126,9 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|
||||
|x-spring-paginated|Add `org.springframework.data.domain.Pageable` to controller method. Can be used to handle `page`, `size` and `sort` query parameters. If these query parameters are also specified in the operation spec, they will be removed from the controller method as their values can be obtained from the `Pageable` object.|OPERATION|false
|
||||
|x-version-param|Marker property that tells that this parameter would be used for endpoint versioning. Applicable for headers & query params. true/false|OPERATION_PARAMETER|null
|
||||
|x-pattern-message|Add this property whenever you need to customize the invalidation error message for the regex pattern of a variable|FIELD, OPERATION_PARAMETER|null
|
||||
|x-size-message|Add this property whenever you need to customize the invalidation error message for the size or length of a variable|FIELD, OPERATION_PARAMETER|null
|
||||
|x-minimum-message|Add this property whenever you need to customize the invalidation error message for the minimum value of a variable|FIELD, OPERATION_PARAMETER|null
|
||||
|x-maximum-message|Add this property whenever you need to customize the invalidation error message for the maximum value of a variable|FIELD, OPERATION_PARAMETER|null
|
||||
|x-spring-api-version|Value for 'version' attribute in @RequestMapping (for Spring 7 and above).|OPERATION|null
|
||||
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|
||||
|supportsES6|Generate code that conforms to ES6.| |false|
|
||||
|useSingleRequestParameter|Setting this property to true will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter.| |false|
|
||||
|useSquareBracketsInArrayNames|Setting this property to true will add brackets to array attribute names, e.g. my_values[].| |false|
|
||||
|withAWSV4Signature|whether to include AWS v4 signature support| |false|
|
||||
|withInterfaces|Setting this property to true will generate interfaces next to the default class implementations.| |false|
|
||||
|withNodeImports|Setting this property to true adds imports for NodeJS| |false|
|
||||
|withSeparateModelsAndApi|Put the model and api in separate folders and in separate classes. This requires in addition a value for 'apiPackage' and 'modelPackage'| |false|
|
||||
@@ -291,7 +292,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|
||||
|OAuth2_ClientCredentials|✗|OAS2,OAS3
|
||||
|OAuth2_AuthorizationCode|✗|OAS2,OAS3
|
||||
|SignatureAuth|✗|OAS3
|
||||
|AWSV4Signature|✗|ToolingExtension
|
||||
|AWSV4Signature|✓|ToolingExtension
|
||||
|
||||
### Wire Format Feature
|
||||
| Name | Supported | Defined By |
|
||||
|
||||
@@ -29,6 +29,7 @@ import io.airlift.airline.Arguments;
|
||||
import io.airlift.airline.Command;
|
||||
import io.airlift.airline.Option;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.lang3.Strings;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openapitools.codegen.ClientOptInput;
|
||||
import org.openapitools.codegen.CodegenConfig;
|
||||
@@ -248,7 +249,7 @@ public class GenerateBatch extends OpenApiGeneratorCommand {
|
||||
Path filesMeta = Paths.get(outDir.toAbsolutePath().toString(), ".openapi-generator", "FILES");
|
||||
if (filesMeta.toFile().exists()) {
|
||||
FileUtils.readLines(filesMeta.toFile(), StandardCharsets.UTF_8).forEach(relativePath -> {
|
||||
if (!StringUtils.startsWith(relativePath, ".")) {
|
||||
if (!Strings.CS.startsWith(relativePath, ".")) {
|
||||
Path file = outDir.resolve(relativePath).toAbsolutePath();
|
||||
// hack: disallow directory traversal outside of output directory. we don't want to delete wrong files.
|
||||
if (file.toString().startsWith(outDir.toAbsolutePath().toString())) {
|
||||
|
||||
@@ -5734,7 +5734,7 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
cs.name = key;
|
||||
cs.description = securityScheme.getDescription();
|
||||
cs.type = securityScheme.getType().toString();
|
||||
cs.isCode = cs.isPassword = cs.isApplication = cs.isImplicit = cs.isOpenId = false;
|
||||
cs.isCode = cs.isPassword = cs.isApplication = cs.isImplicit = cs.isOpenId = cs.isOAuth = false;
|
||||
cs.isHttpSignature = false;
|
||||
cs.isBasicBasic = cs.isBasicBearer = false;
|
||||
cs.scheme = securityScheme.getScheme();
|
||||
|
||||
@@ -353,18 +353,22 @@ public class InlineModelResolver {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (schema.getProperties() != null) {
|
||||
// If non-object type is specified but also properties
|
||||
LOGGER.error("Illegal schema found with non-object type combined with properties," +
|
||||
" no properties should be defined:\n " + schema.toString());
|
||||
return;
|
||||
} else if (schema.getAdditionalProperties() != null) {
|
||||
// If non-object type is specified but also additionalProperties
|
||||
LOGGER.error("Illegal schema found with non-object type combined with" +
|
||||
" additionalProperties, no additionalProperties should be defined:\n " +
|
||||
schema.toString());
|
||||
return;
|
||||
} else {
|
||||
if (schema.getProperties() != null) {
|
||||
// If non-object type is specified but also properties
|
||||
LOGGER.warn("Illegal schema found with non-object type ({}) combined with properties. Properties automatically removed.", schema.getType());
|
||||
schema.setProperties(null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (schema.getAdditionalProperties() != null) {
|
||||
// If non-object type is specified but also additionalProperties
|
||||
LOGGER.error("Illegal schema found with non-object type ({}) combined with additionalProperties. AdditionalProperties automatically removed.", schema.getType());
|
||||
schema.setAdditionalProperties(null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check array items
|
||||
if (ModelUtils.isArraySchema(schema)) {
|
||||
Schema items = ModelUtils.getSchemaItems(schema);
|
||||
|
||||
@@ -49,7 +49,7 @@ public class OpenAPINormalizer {
|
||||
|
||||
private TreeSet<String> anyTypeTreeSet = new TreeSet<>();
|
||||
|
||||
protected final Logger LOGGER = LoggerFactory.getLogger(OpenAPINormalizer.class);
|
||||
protected static final Logger LOGGER = LoggerFactory.getLogger(OpenAPINormalizer.class);
|
||||
|
||||
Set<String> ruleNames = new TreeSet<>();
|
||||
Set<String> rulesDefaultToTrue = new TreeSet<>();
|
||||
@@ -133,10 +133,6 @@ public class OpenAPINormalizer {
|
||||
|
||||
// when set (e.g. operationId:getPetById|addPet), filter out (or remove) everything else
|
||||
final String FILTER = "FILTER";
|
||||
HashSet<String> operationIdFilters = new HashSet<>();
|
||||
HashSet<String> methodFilters = new HashSet<>();
|
||||
|
||||
HashSet<String> tagFilters = new HashSet<>();
|
||||
|
||||
// when set (e.g. operationId:getPetById|addPet), filter out (or remove) everything else
|
||||
final String SET_CONTAINER_TO_NULLABLE = "SET_CONTAINER_TO_NULLABLE";
|
||||
@@ -215,6 +211,7 @@ public class OpenAPINormalizer {
|
||||
rules.put(SIMPLIFY_ONEOF_ANYOF, true);
|
||||
rules.put(SIMPLIFY_BOOLEAN_ENUM, true);
|
||||
rules.put(SIMPLIFY_ONEOF_ANYOF_ENUM, true);
|
||||
rules.put(REFACTOR_ALLOF_WITH_PROPERTIES_ONLY, true);
|
||||
|
||||
processRules(inputRules);
|
||||
|
||||
@@ -275,30 +272,7 @@ public class OpenAPINormalizer {
|
||||
|
||||
if (inputRules.get(FILTER) != null) {
|
||||
rules.put(FILTER, true);
|
||||
|
||||
String[] filterStrs = inputRules.get(FILTER).split(":");
|
||||
if (filterStrs.length != 2) { // only support operationId with : at the moment
|
||||
LOGGER.error("FILTER rule must be in the form of `operationId:name1|name2|name3` or `method:get|post|put` or `tag:tag1|tag2|tag3`: {}", inputRules.get(FILTER));
|
||||
} else {
|
||||
if ("operationId".equals(filterStrs[0])) {
|
||||
operationIdFilters = Arrays.stream(filterStrs[1].split("[|]"))
|
||||
.filter(Objects::nonNull)
|
||||
.map(String::trim)
|
||||
.collect(Collectors.toCollection(HashSet::new));
|
||||
} else if ("method".equals(filterStrs[0])) {
|
||||
methodFilters = Arrays.stream(filterStrs[1].split("[|]"))
|
||||
.filter(Objects::nonNull)
|
||||
.map(String::trim)
|
||||
.collect(Collectors.toCollection(HashSet::new));
|
||||
} else if ("tag".equals(filterStrs[0])) {
|
||||
tagFilters = Arrays.stream(filterStrs[1].split("[|]"))
|
||||
.filter(Objects::nonNull)
|
||||
.map(String::trim)
|
||||
.collect(Collectors.toCollection(HashSet::new));
|
||||
} else {
|
||||
LOGGER.error("FILTER rule must be in the form of `operationId:name1|name2|name3` or `method:get|post|put` or `tag:tag1|tag2|tag3`: {}", inputRules.get(FILTER));
|
||||
}
|
||||
}
|
||||
// actual parsing is delayed to allow customization of the Filter processing
|
||||
}
|
||||
|
||||
if (inputRules.get(SET_CONTAINER_TO_NULLABLE) != null) {
|
||||
@@ -344,6 +318,19 @@ public class OpenAPINormalizer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the filter to process the FILTER normalizer.
|
||||
* Override this to create a custom filter normalizer.
|
||||
*
|
||||
* @param openApi Contract used in the filtering (could be used for customization).
|
||||
* @param filters full FILTER value
|
||||
*
|
||||
* @return a Filter containing the parsed filters.
|
||||
*/
|
||||
protected Filter createFilter(OpenAPI openApi, String filters) {
|
||||
return new Filter(filters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes the OpenAPI input, which may not perfectly conform to
|
||||
* the specification.
|
||||
@@ -405,15 +392,15 @@ public class OpenAPINormalizer {
|
||||
"trace", PathItem::getTrace
|
||||
);
|
||||
|
||||
// Iterates over each HTTP method in methodMap, retrieves the corresponding Operation from the PathItem,
|
||||
// and marks it as internal (`x-internal`) if the method is not in methodFilters.
|
||||
methodMap.forEach((method, getter) -> {
|
||||
Operation operation = getter.apply(path);
|
||||
if (operation != null && !methodFilters.isEmpty()) {
|
||||
LOGGER.info("operation `{}` marked internal only (x-internal: `{}`) by the method FILTER", operation.getOperationId(), !methodFilters.contains(method));
|
||||
operation.addExtension("x-internal", !methodFilters.contains(method));
|
||||
if (Boolean.TRUE.equals(getRule(FILTER))) {
|
||||
String filters = inputRules.get(FILTER);
|
||||
Filter filter = createFilter(this.openAPI, filters);
|
||||
if (filter.parse()) {
|
||||
// Iterates over each HTTP method in methodMap, retrieves the corresponding Operations from the PathItem,
|
||||
// and marks it as internal (`x-internal=true`) if the method/operationId/tag/path is not in the filters.
|
||||
filter.apply(pathsEntry.getKey(), path, methodMap);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Include callback operation as well
|
||||
for (Operation operation : path.readOperations()) {
|
||||
@@ -430,22 +417,6 @@ public class OpenAPINormalizer {
|
||||
normalizeParameters(path.getParameters());
|
||||
|
||||
for (Operation operation : operations) {
|
||||
if (operationIdFilters.size() > 0) {
|
||||
if (operationIdFilters.contains(operation.getOperationId())) {
|
||||
operation.addExtension(X_INTERNAL, false);
|
||||
} else {
|
||||
LOGGER.info("operation `{}` marked as internal only (x-internal: true) by the operationId FILTER", operation.getOperationId());
|
||||
operation.addExtension(X_INTERNAL, true);
|
||||
}
|
||||
} else if (!tagFilters.isEmpty()) {
|
||||
if (operation.getTags().stream().anyMatch(tagFilters::contains)) {
|
||||
operation.addExtension(X_INTERNAL, false);
|
||||
} else {
|
||||
LOGGER.info("operation `{}` marked as internal only (x-internal: true) by the tag FILTER", operation.getOperationId());
|
||||
operation.addExtension(X_INTERNAL, true);
|
||||
}
|
||||
}
|
||||
|
||||
normalizeOperation(operation);
|
||||
normalizeRequestBody(operation);
|
||||
normalizeParameters(operation.getParameters());
|
||||
@@ -1363,7 +1334,7 @@ public class OpenAPINormalizer {
|
||||
*
|
||||
* @param schema Schema to modify
|
||||
* @param subSchemas List of sub-schemas to check
|
||||
* @param schemaType Type of composed schema ("oneOf" or "anyOf")
|
||||
* @param composedType Type of composed schema ("oneOf" or "anyOf")
|
||||
* @return Simplified schema
|
||||
*/
|
||||
protected Schema simplifyComposedSchemaWithEnums(Schema schema, List<Object> subSchemas, String composedType) {
|
||||
@@ -1832,4 +1803,164 @@ public class OpenAPINormalizer {
|
||||
}
|
||||
|
||||
// ===================== end of rules =====================
|
||||
|
||||
protected static class Filter {
|
||||
public static final String OPERATION_ID = "operationId";
|
||||
public static final String METHOD = "method";
|
||||
public static final String TAG = "tag";
|
||||
public static final String PATH = "path";
|
||||
private final String filters;
|
||||
protected Set<String> operationIdFilters = Collections.emptySet();
|
||||
protected Set<String> methodFilters = Collections.emptySet();
|
||||
protected Set<String> tagFilters = Collections.emptySet();
|
||||
protected Set<String> pathStartingWithFilters = Collections.emptySet();
|
||||
private boolean hasFilter;
|
||||
|
||||
protected Filter(String filters) {
|
||||
this.filters = filters.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform the parsing of the filter string.
|
||||
*
|
||||
* @return true if filters need to be processed
|
||||
*/
|
||||
public boolean parse() {
|
||||
if (StringUtils.isEmpty(filters)) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
doParse();
|
||||
return hasFilter();
|
||||
} catch (RuntimeException e) {
|
||||
String message = String.format(Locale.ROOT, "FILTER rule [%s] must be in the form of `%s:name1|name2|name3` or `%s:get|post|put` or `%s:tag1|tag2|tag3` or `%s:/v1|/v2`. Error: %s",
|
||||
filters, Filter.OPERATION_ID, Filter.METHOD, Filter.TAG, Filter.PATH, e.getMessage());
|
||||
// throw an exception. This is a breaking change compared to pre 7.16.0
|
||||
// Workaround: fix the syntax!
|
||||
throw new IllegalArgumentException(message);
|
||||
}
|
||||
}
|
||||
|
||||
private void doParse() {
|
||||
for (String filter : filters.split(";")) {
|
||||
filter = filter.trim();
|
||||
String[] filterStrs = filter.split(":");
|
||||
if (filterStrs.length != 2) { // only support filter with : at the moment
|
||||
throw new IllegalArgumentException("filter with no value not supported :[" + filter + "]");
|
||||
} else {
|
||||
String filterKey = filterStrs[0].trim();
|
||||
String filterValue = filterStrs[1];
|
||||
Set<String> parsedFilters = splitByPipe(filterValue);
|
||||
hasFilter = true;
|
||||
if (OPERATION_ID.equals(filterKey)) {
|
||||
operationIdFilters = parsedFilters;
|
||||
} else if (METHOD.equals(filterKey)) {
|
||||
methodFilters = parsedFilters;
|
||||
} else if (TAG.equals(filterKey)) {
|
||||
tagFilters = parsedFilters;
|
||||
} else if (PATH.equals(filterKey)) {
|
||||
pathStartingWithFilters = parsedFilters;
|
||||
} else {
|
||||
parse(filterKey, filterValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Split the filterValue by pipe.
|
||||
*
|
||||
* @return the split values.
|
||||
*/
|
||||
protected Set<String> splitByPipe(String filterValue) {
|
||||
return Arrays.stream(filterValue.split("[|]"))
|
||||
.filter(Objects::nonNull)
|
||||
.map(String::trim)
|
||||
.collect(Collectors.toCollection(HashSet::new));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse non default filters.
|
||||
*
|
||||
* Override this method to add custom parsing logic.
|
||||
*
|
||||
* By default throws IllegalArgumentException.
|
||||
*
|
||||
* @param filterName name of the filter
|
||||
* @param filterValue value of the filter
|
||||
*/
|
||||
protected void parse(String filterName, String filterValue) {
|
||||
parseFails(filterName, filterValue);
|
||||
}
|
||||
|
||||
protected void parseFails(String filterName, String filterValue) {
|
||||
throw new IllegalArgumentException("filter not supported :[" + filterName + ":" + filterValue + "]");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the OpenAPI contract match an extra filter.
|
||||
*
|
||||
* Override this method to add custom logic.
|
||||
*
|
||||
* @param operation Openapi Operation
|
||||
* @param path Path of the operation
|
||||
*
|
||||
* @return true if the operation of path match the filter
|
||||
*/
|
||||
protected boolean hasCustomFilterMatch(String path, Operation operation) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean hasFilter() {
|
||||
return hasFilter;
|
||||
}
|
||||
|
||||
public void apply(String path, PathItem pathItem, Map<String, Function<PathItem, Operation>> methodMap) {
|
||||
methodMap.forEach((method, getter) -> {
|
||||
Operation operation = getter.apply(pathItem);
|
||||
if (operation != null) {
|
||||
boolean found = false;
|
||||
found |= logIfMatch(PATH, operation, hasPathStarting(path));
|
||||
found |= logIfMatch(TAG, operation, hasTag(operation));
|
||||
found |= logIfMatch(OPERATION_ID, operation, hasOperationId(operation));
|
||||
found |= logIfMatch(METHOD, operation, hasMethod(method));
|
||||
found |= hasCustomFilterMatch(path, operation);
|
||||
|
||||
operation.addExtension(X_INTERNAL, !found);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected boolean logIfMatch(String filterName, Operation operation, boolean filterMatched) {
|
||||
if (filterMatched) {
|
||||
logMatch(filterName, operation);
|
||||
}
|
||||
return filterMatched;
|
||||
}
|
||||
|
||||
protected void logMatch(String filterName, Operation operation) {
|
||||
getLogger().info("operation `{}` marked as internal only (x-internal: true) by the {} FILTER", operation.getOperationId(), filterName);
|
||||
}
|
||||
|
||||
protected Logger getLogger() {
|
||||
return OpenAPINormalizer.LOGGER;
|
||||
}
|
||||
|
||||
private boolean hasPathStarting(String path) {
|
||||
return pathStartingWithFilters.stream().anyMatch(filter -> path.startsWith(filter));
|
||||
}
|
||||
|
||||
private boolean hasTag( Operation operation) {
|
||||
return operation.getTags() != null && operation.getTags().stream().anyMatch(tagFilters::contains);
|
||||
}
|
||||
|
||||
private boolean hasOperationId(Operation operation) {
|
||||
return operationIdFilters.contains(operation.getOperationId());
|
||||
}
|
||||
|
||||
private boolean hasMethod(String method) {
|
||||
return methodFilters.contains(method);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,9 @@ public enum VendorExtension {
|
||||
X_OPERATION_EXTRA_ANNOTATION("x-operation-extra-annotation", ExtensionLevel.OPERATION, "List of custom annotations to be added to operation", null),
|
||||
X_VERSION_PARAM("x-version-param", ExtensionLevel.OPERATION_PARAMETER, "Marker property that tells that this parameter would be used for endpoint versioning. Applicable for headers & query params. true/false", null),
|
||||
X_PATTERN_MESSAGE("x-pattern-message", Arrays.asList(ExtensionLevel.FIELD, ExtensionLevel.OPERATION_PARAMETER), "Add this property whenever you need to customize the invalidation error message for the regex pattern of a variable", null),
|
||||
X_SIZE_MESSAGE("x-size-message", Arrays.asList(ExtensionLevel.FIELD, ExtensionLevel.OPERATION_PARAMETER), "Add this property whenever you need to customize the invalidation error message for the size or length of a variable", null),
|
||||
X_MINIMUM_MESSAGE("x-minimum-message", Arrays.asList(ExtensionLevel.FIELD, ExtensionLevel.OPERATION_PARAMETER), "Add this property whenever you need to customize the invalidation error message for the minimum value of a variable", null),
|
||||
X_MAXIMUM_MESSAGE("x-maximum-message", Arrays.asList(ExtensionLevel.FIELD, ExtensionLevel.OPERATION_PARAMETER), "Add this property whenever you need to customize the invalidation error message for the maximum value of a variable", null),
|
||||
X_ZERO_BASED_ENUM("x-zero-based-enum", ExtensionLevel.MODEL, "When used on an enum, the index will not be generated and the default numbering will be used, zero-based", "false");
|
||||
|
||||
private final String name;
|
||||
|
||||
@@ -1628,7 +1628,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
|
||||
Schema<?> target = ModelUtils.isGenerateAliasAsModel() ? p : schema;
|
||||
if (ModelUtils.isArraySchema(target)) {
|
||||
Schema<?> items = getSchemaItems(schema);
|
||||
return getSchemaType(target) + "<" + getTypeDeclarationForArray(items) + ">";
|
||||
return typeMapping.get("array") + "<" + getTypeDeclarationForArray(items) + ">";
|
||||
} else if (ModelUtils.isMapSchema(p)) {
|
||||
// Should we also support maps of maps?
|
||||
Schema<?> inner = ModelUtils.getAdditionalProperties(p);
|
||||
|
||||
@@ -34,6 +34,7 @@ import io.swagger.v3.oas.models.media.Schema;
|
||||
import io.swagger.v3.oas.models.parameters.Parameter;
|
||||
import io.swagger.v3.oas.models.parameters.RequestBody;
|
||||
import io.swagger.v3.oas.models.security.SecurityScheme;
|
||||
import org.apache.commons.lang3.Strings;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openapitools.codegen.*;
|
||||
import org.openapitools.codegen.meta.features.DocumentationFeature;
|
||||
@@ -601,7 +602,7 @@ public abstract class AbstractPythonConnexionServerCodegen extends AbstractPytho
|
||||
@Override
|
||||
public String toModelImport(String name) {
|
||||
String modelImport;
|
||||
if (StringUtils.startsWithAny(name, "import", "from")) {
|
||||
if (Strings.CS.startsWithAny(name, "import", "from")) {
|
||||
modelImport = name;
|
||||
} else {
|
||||
modelImport = "from ";
|
||||
|
||||
@@ -1012,6 +1012,9 @@ public class KotlinSpringServerCodegen extends AbstractKotlinCodegen
|
||||
extensions.add(VendorExtension.X_DISCRIMINATOR_VALUE);
|
||||
extensions.add(VendorExtension.X_FIELD_EXTRA_ANNOTATION);
|
||||
extensions.add(VendorExtension.X_PATTERN_MESSAGE);
|
||||
extensions.add(VendorExtension.X_SIZE_MESSAGE);
|
||||
extensions.add(VendorExtension.X_MINIMUM_MESSAGE);
|
||||
extensions.add(VendorExtension.X_MAXIMUM_MESSAGE);
|
||||
extensions.add(VendorExtension.X_KOTLIN_IMPLEMENTS);
|
||||
extensions.add(VendorExtension.X_KOTLIN_IMPLEMENTS_FIELDS);
|
||||
return extensions;
|
||||
|
||||
@@ -20,7 +20,7 @@ package org.openapitools.codegen.languages;
|
||||
import io.swagger.v3.oas.models.media.Schema;
|
||||
import io.swagger.v3.oas.models.security.SecurityScheme;
|
||||
import lombok.Setter;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.Strings;
|
||||
import org.openapitools.codegen.*;
|
||||
import org.openapitools.codegen.meta.GeneratorMetadata;
|
||||
import org.openapitools.codegen.meta.Stability;
|
||||
@@ -355,7 +355,7 @@ public class PythonClientCodegen extends AbstractPythonCodegen implements Codege
|
||||
@Override
|
||||
public String toModelImport(String name) {
|
||||
String modelImport;
|
||||
if (StringUtils.startsWithAny(name, "import", "from")) {
|
||||
if (Strings.CS.startsWithAny(name, "import", "from")) {
|
||||
modelImport = name;
|
||||
} else {
|
||||
modelImport = "from ";
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import io.swagger.v3.oas.models.media.Schema;
|
||||
import org.apache.commons.lang3.Strings;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openapitools.codegen.*;
|
||||
import org.openapitools.codegen.meta.GeneratorMetadata;
|
||||
@@ -89,6 +90,11 @@ public class PythonFastAPIServerCodegen extends AbstractPythonCodegen {
|
||||
public PythonFastAPIServerCodegen() {
|
||||
super();
|
||||
|
||||
// Skip sorting of operations to preserve the order found in the OpenAPI spec file. See
|
||||
// https://fastapi.tiangolo.com/tutorial/path-params/?h=path#order-matters for details on why order matters.
|
||||
LOGGER.info("Skipping sorting of path operations, order matters, let the developer decide via their specification file.");
|
||||
setSkipSortingOperations(true);
|
||||
|
||||
modifyFeatureSet(features -> features.includeSecurityFeatures(
|
||||
SecurityFeature.OAuth2_AuthorizationCode,
|
||||
SecurityFeature.OAuth2_Password
|
||||
@@ -198,7 +204,7 @@ public class PythonFastAPIServerCodegen extends AbstractPythonCodegen {
|
||||
@Override
|
||||
public String toModelImport(String name) {
|
||||
String modelImport;
|
||||
if (StringUtils.startsWithAny(name, "import", "from")) {
|
||||
if (Strings.CS.startsWithAny(name, "import", "from")) {
|
||||
modelImport = name;
|
||||
} else {
|
||||
modelImport = "from ";
|
||||
|
||||
@@ -20,6 +20,7 @@ package org.openapitools.codegen.languages;
|
||||
import io.swagger.v3.oas.models.media.Schema;
|
||||
import io.swagger.v3.oas.models.security.SecurityScheme;
|
||||
import lombok.Setter;
|
||||
import org.apache.commons.lang3.Strings;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openapitools.codegen.*;
|
||||
import org.openapitools.codegen.meta.GeneratorMetadata;
|
||||
@@ -353,7 +354,7 @@ public class PythonPydanticV1ClientCodegen extends AbstractPythonPydanticV1Codeg
|
||||
@Override
|
||||
public String toModelImport(String name) {
|
||||
String modelImport;
|
||||
if (StringUtils.startsWithAny(name, "import", "from")) {
|
||||
if (Strings.CS.startsWithAny(name, "import", "from")) {
|
||||
modelImport = name;
|
||||
} else {
|
||||
modelImport = "from ";
|
||||
|
||||
@@ -1408,6 +1408,7 @@ public class RustServerCodegen extends AbstractRustCodegen implements CodegenCon
|
||||
*
|
||||
* @deprecated Avoid using this - use a different mechanism instead.
|
||||
*/
|
||||
@Deprecated
|
||||
private static String stripNullable(String type) {
|
||||
if (type.startsWith("swagger::Nullable<") && type.endsWith(">")) {
|
||||
return type.substring("swagger::Nullable<".length(), type.length() - 1);
|
||||
|
||||
@@ -1408,6 +1408,7 @@ public class RustServerCodegenDeprecated extends AbstractRustCodegen implements
|
||||
*
|
||||
* @deprecated Avoid using this - use a different mechanism instead.
|
||||
*/
|
||||
@Deprecated
|
||||
private static String stripNullable(String type) {
|
||||
if (type.startsWith("swagger::Nullable<") && type.endsWith(">")) {
|
||||
return type.substring("swagger::Nullable<".length(), type.length() - 1);
|
||||
|
||||
@@ -568,12 +568,8 @@ public class SpringCodegen extends AbstractJavaCodegen
|
||||
(sourceFolder + File.separator + apiPackage).replace(".", java.io.File.separator), "ApiUtil.java"));
|
||||
}
|
||||
|
||||
if (!delegatePattern || delegateMethod) {
|
||||
additionalProperties.put("jdk8-no-delegate", true);
|
||||
}
|
||||
|
||||
if (delegatePattern && !delegateMethod) {
|
||||
additionalProperties.put("isDelegate", "true");
|
||||
additionalProperties.put("isDelegate", true);
|
||||
apiTemplateFiles.put("apiDelegate.mustache", "Delegate.java");
|
||||
}
|
||||
|
||||
@@ -1217,6 +1213,9 @@ public class SpringCodegen extends AbstractJavaCodegen
|
||||
extensions.add(VendorExtension.X_SPRING_PAGINATED);
|
||||
extensions.add(VendorExtension.X_VERSION_PARAM);
|
||||
extensions.add(VendorExtension.X_PATTERN_MESSAGE);
|
||||
extensions.add(VendorExtension.X_SIZE_MESSAGE);
|
||||
extensions.add(VendorExtension.X_MINIMUM_MESSAGE);
|
||||
extensions.add(VendorExtension.X_MAXIMUM_MESSAGE);
|
||||
extensions.add(VendorExtension.X_SPRING_API_VERSION);
|
||||
return extensions;
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ public class TypeScriptAxiosClientCodegen extends AbstractTypeScriptClientCodege
|
||||
public static final String USE_SQUARE_BRACKETS_IN_ARRAY_NAMES = "useSquareBracketsInArrayNames";
|
||||
public static final String AXIOS_VERSION = "axiosVersion";
|
||||
public static final String DEFAULT_AXIOS_VERSION = "^1.6.1";
|
||||
public static final String WITH_AWSV4_SIGNATURE = "withAWSV4Signature";
|
||||
|
||||
@Getter @Setter
|
||||
protected String npmRepository = null;
|
||||
@@ -60,6 +61,7 @@ public class TypeScriptAxiosClientCodegen extends AbstractTypeScriptClientCodege
|
||||
|
||||
@Getter @Setter
|
||||
protected String axiosVersion = DEFAULT_AXIOS_VERSION;
|
||||
protected boolean withAWSV4Signature = false;
|
||||
|
||||
private String tsModelPackage = "";
|
||||
|
||||
@@ -71,7 +73,7 @@ public class TypeScriptAxiosClientCodegen extends AbstractTypeScriptClientCodege
|
||||
|
||||
modifyFeatureSet(features -> features
|
||||
.includeDocumentationFeatures(DocumentationFeature.Readme)
|
||||
.includeSecurityFeatures(SecurityFeature.BearerToken));
|
||||
.includeSecurityFeatures(SecurityFeature.BearerToken, SecurityFeature.AWSV4Signature));
|
||||
|
||||
// clear import mapping (from default generator) as TS does not use it
|
||||
// at the moment
|
||||
@@ -94,6 +96,7 @@ public class TypeScriptAxiosClientCodegen extends AbstractTypeScriptClientCodege
|
||||
this.cliOptions.add(new CliOption(IMPORT_FILE_EXTENSION_SWITCH, IMPORT_FILE_EXTENSION_SWITCH_DESC, SchemaTypeUtil.STRING_TYPE).defaultValue(this.importFileExtension));
|
||||
this.cliOptions.add(new CliOption(USE_SQUARE_BRACKETS_IN_ARRAY_NAMES, "Setting this property to true will add brackets to array attribute names, e.g. my_values[].", SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.FALSE.toString()));
|
||||
this.cliOptions.add(new CliOption(AXIOS_VERSION, "Use this property to override the axios version in package.json").defaultValue(DEFAULT_AXIOS_VERSION));
|
||||
this.cliOptions.add(new CliOption(WITH_AWSV4_SIGNATURE, "whether to include AWS v4 signature support", SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.FALSE.toString()));
|
||||
// Templates have no mapping between formatted property names and original base names so use only "original" and remove this option
|
||||
removeOption(CodegenConstants.MODEL_PROPERTY_NAMING);
|
||||
}
|
||||
@@ -182,6 +185,10 @@ public class TypeScriptAxiosClientCodegen extends AbstractTypeScriptClientCodege
|
||||
setAxiosVersion(additionalProperties.get(AXIOS_VERSION).toString());
|
||||
}
|
||||
additionalProperties.put("axiosVersion", getAxiosVersion());
|
||||
if (additionalProperties.containsKey(CodegenConstants.WITH_AWSV4_SIGNATURE_COMMENT)) {
|
||||
this.setWithAWSV4Signature(Boolean.parseBoolean(additionalProperties.get(CodegenConstants.WITH_AWSV4_SIGNATURE_COMMENT).toString()));
|
||||
}
|
||||
additionalProperties.put(CodegenConstants.WITH_AWSV4_SIGNATURE_COMMENT, withAWSV4Signature);
|
||||
|
||||
}
|
||||
|
||||
@@ -307,6 +314,10 @@ public class TypeScriptAxiosClientCodegen extends AbstractTypeScriptClientCodege
|
||||
return (outputFolder + "/" + modelDocPath).replace('/', File.separatorChar);
|
||||
}
|
||||
|
||||
public void setWithAWSV4Signature(boolean withAWSV4Signature) {
|
||||
this.withAWSV4Signature = withAWSV4Signature;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overriding toRegularExpression() to avoid escapeText() being called,
|
||||
* as it would return a broken regular expression if any escaped character / metacharacter were present.
|
||||
|
||||
@@ -24,14 +24,16 @@ import io.swagger.v3.oas.annotations.media.ExampleObject;
|
||||
{{#swagger1AnnotationLibrary}}
|
||||
import io.swagger.annotations.*;
|
||||
{{/swagger1AnnotationLibrary}}
|
||||
{{#jdk8-no-delegate}}
|
||||
{{^isDelegate}}
|
||||
{{#jdk8-default-interface}}
|
||||
{{#virtualService}}
|
||||
import io.virtualan.annotation.ApiVirtual;
|
||||
import io.virtualan.annotation.VirtualService;
|
||||
{{/virtualService}}
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
{{/jdk8-no-delegate}}
|
||||
{{/jdk8-default-interface}}
|
||||
{{/isDelegate}}
|
||||
{{^useResponseEntity}}
|
||||
import org.springframework.http.HttpStatus;
|
||||
{{/useResponseEntity}}
|
||||
@@ -48,11 +50,13 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
{{/useResponseEntity}}
|
||||
{{/useSpringController}}
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
{{#jdk8-no-delegate}}
|
||||
{{^reactive}}
|
||||
{{#jdk8-default-interface}}
|
||||
{{^isDelegate}}
|
||||
{{^reactive}}
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
{{/reactive}}
|
||||
{{/jdk8-no-delegate}}
|
||||
{{/reactive}}
|
||||
{{/isDelegate}}
|
||||
{{/jdk8-default-interface}}
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
{{#reactive}}
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
@@ -67,14 +71,14 @@ import {{javaxPackage}}.validation.constraints.*;
|
||||
{{/useBeanValidation}}
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
{{#jdk8-no-delegate}}
|
||||
{{^isDelegate}}
|
||||
import java.util.Optional;
|
||||
{{/jdk8-no-delegate}}
|
||||
{{^jdk8-no-delegate}}
|
||||
{{/isDelegate}}
|
||||
{{#isDelegate}}
|
||||
{{#useOptional}}
|
||||
import java.util.Optional;
|
||||
{{/useOptional}}
|
||||
{{/jdk8-no-delegate}}
|
||||
{{/isDelegate}}
|
||||
{{#async}}
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
{{/async}}
|
||||
@@ -128,7 +132,7 @@ public interface {{classname}} {
|
||||
{{/jdk8-default-interface}}
|
||||
{{#operation}}
|
||||
|
||||
public static final String PATH_{{#lambda.uppercase}}{{#lambda.snakecase}}{{{operationId}}}{{/lambda.snakecase}}{{/lambda.uppercase}} = "{{{path}}}";
|
||||
String PATH_{{#lambda.uppercase}}{{#lambda.snakecase}}{{{operationId}}}{{/lambda.snakecase}}{{/lambda.uppercase}} = "{{{path}}}";
|
||||
/**
|
||||
* {{httpMethod}} {{{path}}}{{#summary}} : {{.}}{{/summary}}
|
||||
{{#notes}}
|
||||
@@ -261,7 +265,9 @@ public interface {{classname}} {
|
||||
{{#vendorExtensions.x-operation-extra-annotation}}
|
||||
{{{.}}}
|
||||
{{/vendorExtensions.x-operation-extra-annotation}}
|
||||
{{#vendorExtensions.x-sse}}@ResponseBody{{/vendorExtensions.x-sse}}
|
||||
{{#vendorExtensions.x-sse}}
|
||||
@ResponseBody
|
||||
{{/vendorExtensions.x-sse}}
|
||||
{{#jdk8-default-interface}}default {{/jdk8-default-interface}}{{>responseType}} {{#delegate-method}}_{{/delegate-method}}{{operationId}}(
|
||||
{{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{>cookieParams}}{{^-last}},
|
||||
{{/-last}}{{/allParams}}{{#reactive}}{{#hasParams}},
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
{{^isUuid}}{{#pattern}}{{^isByteArray}}@Pattern(regexp = "{{{pattern}}}"{{#vendorExtensions.x-pattern-message}}, message="{{vendorExtensions.x-pattern-message}}"{{/vendorExtensions.x-pattern-message}}) {{/isByteArray}}{{/pattern}}{{!
|
||||
{{^isUuid}}{{#pattern}}{{^isByteArray}}@Pattern(regexp = "{{{pattern}}}"{{#vendorExtensions.x-pattern-message}}, message = "{{vendorExtensions.x-pattern-message}}"{{/vendorExtensions.x-pattern-message}}) {{/isByteArray}}{{/pattern}}{{!
|
||||
minLength && maxLength set
|
||||
}}{{#minLength}}{{#maxLength}}@Size(min = {{minLength}}, max = {{maxLength}}) {{/maxLength}}{{/minLength}}{{!
|
||||
}}{{#minLength}}{{#maxLength}}@Size(min = {{minLength}}, max = {{maxLength}}{{#vendorExtensions.x-size-message}}, message = "{{vendorExtensions.x-size-message}}"{{/vendorExtensions.x-size-message}}) {{/maxLength}}{{/minLength}}{{!
|
||||
minLength set, maxLength not
|
||||
}}{{#minLength}}{{^maxLength}}@Size(min = {{minLength}}) {{/maxLength}}{{/minLength}}{{!
|
||||
}}{{#minLength}}{{^maxLength}}@Size(min = {{minLength}}{{#vendorExtensions.x-size-message}}, message = "{{vendorExtensions.x-size-message}}"{{/vendorExtensions.x-size-message}}) {{/maxLength}}{{/minLength}}{{!
|
||||
minLength not set, maxLength set
|
||||
}}{{^minLength}}{{#maxLength}}@Size(max = {{.}}) {{/maxLength}}{{/minLength}}{{!
|
||||
}}{{^minLength}}{{#maxLength}}@Size(max = {{.}}{{#vendorExtensions.x-size-message}}, message = "{{vendorExtensions.x-size-message}}"{{/vendorExtensions.x-size-message}}) {{/maxLength}}{{/minLength}}{{!
|
||||
@Size: minItems && maxItems set
|
||||
}}{{#minItems}}{{#maxItems}}@Size(min = {{minItems}}, max = {{maxItems}}) {{/maxItems}}{{/minItems}}{{!
|
||||
}}{{#minItems}}{{#maxItems}}@Size(min = {{minItems}}, max = {{maxItems}}{{#vendorExtensions.x-size-message}}, message = "{{vendorExtensions.x-size-message}}"{{/vendorExtensions.x-size-message}}) {{/maxItems}}{{/minItems}}{{!
|
||||
@Size: minItems set, maxItems not
|
||||
}}{{#minItems}}{{^maxItems}}@Size(min = {{minItems}}) {{/maxItems}}{{/minItems}}{{!
|
||||
}}{{#minItems}}{{^maxItems}}@Size(min = {{minItems}}{{#vendorExtensions.x-size-message}}, message = "{{vendorExtensions.x-size-message}}"{{/vendorExtensions.x-size-message}}) {{/maxItems}}{{/minItems}}{{!
|
||||
@Size: minItems not set && maxItems set
|
||||
}}{{^minItems}}{{#maxItems}}@Size(max = {{.}}) {{/maxItems}}{{/minItems}}{{!
|
||||
}}{{^minItems}}{{#maxItems}}@Size(max = {{.}}{{#vendorExtensions.x-size-message}}, message = "{{vendorExtensions.x-size-message}}"{{/vendorExtensions.x-size-message}}) {{/maxItems}}{{/minItems}}{{!
|
||||
@Email: useBeanValidation
|
||||
}}{{#isEmail}}{{#useBeanValidation}}@{{javaxPackage}}.validation.constraints.Email {{/useBeanValidation}}{{!
|
||||
@Email: performBeanValidation exclusive
|
||||
}}{{^useBeanValidation}}{{#performBeanValidation}}@org.hibernate.validator.constraints.Email {{/performBeanValidation}}{{/useBeanValidation}}{{/isEmail}}{{!
|
||||
check for integer or long / all others=decimal type with @Decimal*
|
||||
isInteger set
|
||||
}}{{#isInteger}}{{#minimum}}@Min({{.}}) {{/minimum}}{{#maximum}}@Max({{.}}) {{/maximum}}{{/isInteger}}{{!
|
||||
}}{{#isInteger}}{{#minimum}}@Min(value = {{.}}{{#vendorExtensions.x-minimum-message}}, message = "{{vendorExtensions.x-minimum-message}}"{{/vendorExtensions.x-minimum-message}}) {{/minimum}}{{#maximum}}@Max(value = {{.}}{{#vendorExtensions.x-maximum-message}}, message = "{{vendorExtensions.x-maximum-message}}"{{/vendorExtensions.x-maximum-message}}) {{/maximum}}{{/isInteger}}{{!
|
||||
isLong set
|
||||
}}{{#isLong}}{{#minimum}}@Min({{.}}L) {{/minimum}}{{#maximum}}@Max({{.}}L) {{/maximum}}{{/isLong}}{{!
|
||||
}}{{#isLong}}{{#minimum}}@Min(value = {{.}}L{{#vendorExtensions.x-minimum-message}}, message = "{{vendorExtensions.x-minimum-message}}"{{/vendorExtensions.x-minimum-message}}) {{/minimum}}{{#maximum}}@Max(value = {{.}}L{{#vendorExtensions.x-maximum-message}}, message = "{{vendorExtensions.x-maximum-message}}"{{/vendorExtensions.x-maximum-message}}) {{/maximum}}{{/isLong}}{{!
|
||||
Not Integer, not Long => we have a decimal value!
|
||||
}}{{^isInteger}}{{^isLong}}{{#minimum}}@DecimalMin({{#exclusiveMinimum}}value = {{/exclusiveMinimum}}"{{minimum}}"{{#exclusiveMinimum}}, inclusive = false{{/exclusiveMinimum}}) {{/minimum}}{{#maximum}}@DecimalMax({{#exclusiveMaximum}}value = {{/exclusiveMaximum}}"{{maximum}}"{{#exclusiveMaximum}}, inclusive = false{{/exclusiveMaximum}}) {{/maximum}}{{/isLong}}{{/isInteger}}{{/isUuid}}
|
||||
}}{{^isInteger}}{{^isLong}}{{#minimum}}@DecimalMin(value = "{{minimum}}"{{#exclusiveMinimum}}, inclusive = false{{/exclusiveMinimum}}{{#vendorExtensions.x-minimum-message}}, message = "{{vendorExtensions.x-minimum-message}}"{{/vendorExtensions.x-minimum-message}}) {{/minimum}}{{#maximum}}@DecimalMax(value = "{{maximum}}"{{#exclusiveMaximum}}, inclusive = false{{/exclusiveMaximum}}{{#vendorExtensions.x-maximum-message}}, message = "{{vendorExtensions.x-maximum-message}}"{{/vendorExtensions.x-maximum-message}}) {{/maximum}}{{/isLong}}{{/isInteger}}{{/isUuid}}
|
||||
@@ -167,6 +167,9 @@ namespace {{packageName}}.Client
|
||||
/// </remarks>
|
||||
{{>visibility}} partial class ApiClient : IDisposable, ISynchronousClient{{#supportsAsync}}, IAsynchronousClient{{/supportsAsync}}
|
||||
{
|
||||
{{#net60OrLater}}
|
||||
private static readonly HttpRequestOptionsKey<List<Cookie>> _httpOptionsCookieContainerKey = new("CookieContainer");
|
||||
{{/net60OrLater}}
|
||||
private readonly string _baseUrl;
|
||||
|
||||
private readonly HttpClientHandler _httpClientHandler;
|
||||
@@ -382,12 +385,15 @@ namespace {{packageName}}.Client
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// TODO provide an alternative that allows cookies per request instead of per API client
|
||||
if (options.Cookies != null && options.Cookies.Count > 0)
|
||||
{
|
||||
{{#net60OrLater}}
|
||||
request.Options.Set(_httpOptionsCookieContainerKey, options.Cookies);
|
||||
{{/net60OrLater}}
|
||||
{{^net60OrLater}}
|
||||
request.Properties["CookieContainer"] = options.Cookies;
|
||||
{{/net60OrLater}}
|
||||
}
|
||||
|
||||
return request;
|
||||
@@ -474,9 +480,16 @@ namespace {{packageName}}.Client
|
||||
_httpClientHandler.ClientCertificates.AddRange(configuration.ClientCertificates);
|
||||
}
|
||||
|
||||
{{^net60OrLater}}
|
||||
var cookieContainer = req.Properties.ContainsKey("CookieContainer") ? req.Properties["CookieContainer"] as List<Cookie> : null;
|
||||
{{/net60OrLater}}
|
||||
|
||||
{{#net60OrLater}}
|
||||
if (req.Options.TryGetValue(_httpOptionsCookieContainerKey, out var cookieContainer))
|
||||
{{/net60OrLater}}
|
||||
{{^net60OrLater}}
|
||||
if (cookieContainer != null)
|
||||
{{/net60OrLater}}
|
||||
{
|
||||
if(_httpClientHandler == null) throw new InvalidOperationException("Request property `CookieContainer` not supported when the client is explicitly created without an HttpClientHandler, use the proper constructor.");
|
||||
foreach (var cookie in cookieContainer)
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace {{packageName}}.{{clientPackage}}
|
||||
string value = reader.GetString(){{nrt!}};
|
||||
|
||||
foreach(string format in Formats)
|
||||
if (DateOnly.TryParseExact(value, format, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal, out DateOnly result))
|
||||
if (DateOnly.TryParseExact(value, format, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateOnly result))
|
||||
return result;
|
||||
|
||||
throw new NotSupportedException();
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace {{packageName}}.{{clientPackage}}
|
||||
string value = reader.GetString(){{nrt!}};
|
||||
|
||||
foreach(string format in Formats)
|
||||
if (DateOnly.TryParseExact(value, format, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal, out DateOnly result))
|
||||
if (DateOnly.TryParseExact(value, format, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateOnly result))
|
||||
return result;
|
||||
|
||||
throw new NotSupportedException();
|
||||
|
||||
@@ -79,7 +79,7 @@ namespace {{packageName}}.Client
|
||||
|
||||
public async Task<T> Deserialize<T>(HttpResponseMessage response)
|
||||
{
|
||||
var result = (T) await Deserialize(response, typeof(T)).ConfigureAwait(false);
|
||||
var result = (T)await Deserialize(response, typeof(T)).ConfigureAwait(false);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -95,13 +95,13 @@ namespace {{packageName}}.Client
|
||||
// process response headers, e.g. Access-Control-Allow-Methods
|
||||
foreach (var responseHeader in response.Headers)
|
||||
{
|
||||
headers.Add(responseHeader.Key + "=" + ClientUtils.ParameterToString(responseHeader.Value));
|
||||
headers.Add(responseHeader.Key + "=" + ClientUtils.ParameterToString(responseHeader.Value));
|
||||
}
|
||||
|
||||
// process response content headers, e.g. Content-Type
|
||||
foreach (var responseHeader in response.Content.Headers)
|
||||
{
|
||||
headers.Add(responseHeader.Key + "=" + ClientUtils.ParameterToString(responseHeader.Value));
|
||||
headers.Add(responseHeader.Key + "=" + ClientUtils.ParameterToString(responseHeader.Value));
|
||||
}
|
||||
|
||||
// RFC 2183 & RFC 2616
|
||||
@@ -112,7 +112,8 @@ namespace {{packageName}}.Client
|
||||
}
|
||||
else if (type == typeof(FileParameter))
|
||||
{
|
||||
if (headers != null) {
|
||||
if (headers != null)
|
||||
{
|
||||
foreach (var header in headers)
|
||||
{
|
||||
var match = fileNameRegex.Match(header.ToString());
|
||||
@@ -191,6 +192,9 @@ namespace {{packageName}}.Client
|
||||
/// </remarks>
|
||||
{{>visibility}} partial class ApiClient : IDisposable, ISynchronousClient{{#supportsAsync}}, IAsynchronousClient{{/supportsAsync}}
|
||||
{
|
||||
{{#net60OrLater}}
|
||||
private static readonly HttpRequestOptionsKey<List<Cookie>> _httpOptionsCookieContainerKey = new("CookieContainer");
|
||||
{{/net60OrLater}}
|
||||
private readonly string _baseUrl;
|
||||
|
||||
private readonly HttpClientHandler _httpClientHandler;
|
||||
@@ -283,7 +287,8 @@ namespace {{packageName}}.Client
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
if(_disposeClient) {
|
||||
if(_disposeClient)
|
||||
{
|
||||
_httpClient.Dispose();
|
||||
}
|
||||
}
|
||||
@@ -413,7 +418,12 @@ namespace {{packageName}}.Client
|
||||
// TODO provide an alternative that allows cookies per request instead of per API client
|
||||
if (options.Cookies != null && options.Cookies.Count > 0)
|
||||
{
|
||||
{{#net60OrLater}}
|
||||
request.Options.Set(_httpOptionsCookieContainerKey, options.Cookies);
|
||||
{{/net60OrLater}}
|
||||
{{^net60OrLater}}
|
||||
request.Properties["CookieContainer"] = options.Cookies;
|
||||
{{/net60OrLater}}
|
||||
}
|
||||
|
||||
return request;
|
||||
@@ -424,7 +434,7 @@ namespace {{packageName}}.Client
|
||||
|
||||
private async Task<ApiResponse<T>> ToApiResponse<T>(HttpResponseMessage response, object responseData, Uri uri)
|
||||
{
|
||||
T result = (T) responseData;
|
||||
T result = (T)responseData;
|
||||
string rawContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
|
||||
var transformed = new ApiResponse<T>(response.StatusCode, new Multimap<string, string>({{#caseInsensitiveResponseHeaders}}StringComparer.OrdinalIgnoreCase{{/caseInsensitiveResponseHeaders}}), result, rawContent)
|
||||
@@ -459,7 +469,7 @@ namespace {{packageName}}.Client
|
||||
transformed.Cookies.Add(cookie);
|
||||
}
|
||||
}
|
||||
catch (PlatformNotSupportedException) {}
|
||||
catch (PlatformNotSupportedException) { }
|
||||
}
|
||||
|
||||
return transformed;
|
||||
@@ -496,15 +506,22 @@ namespace {{packageName}}.Client
|
||||
|
||||
if (configuration.ClientCertificates != null)
|
||||
{
|
||||
if(_httpClientHandler == null) throw new InvalidOperationException("Configuration `ClientCertificates` not supported when the client is explicitly created without an HttpClientHandler, use the proper constructor.");
|
||||
if (_httpClientHandler == null) throw new InvalidOperationException("Configuration `ClientCertificates` not supported when the client is explicitly created without an HttpClientHandler, use the proper constructor.");
|
||||
_httpClientHandler.ClientCertificates.AddRange(configuration.ClientCertificates);
|
||||
}
|
||||
|
||||
{{^net60OrLater}}
|
||||
var cookieContainer = req.Properties.ContainsKey("CookieContainer") ? req.Properties["CookieContainer"] as List<Cookie> : null;
|
||||
{{/net60OrLater}}
|
||||
|
||||
{{#net60OrLater}}
|
||||
if (req.Options.TryGetValue(_httpOptionsCookieContainerKey, out var cookieContainer))
|
||||
{{/net60OrLater}}
|
||||
{{^net60OrLater}}
|
||||
if (cookieContainer != null)
|
||||
{{/net60OrLater}}
|
||||
{
|
||||
if(_httpClientHandler == null) throw new InvalidOperationException("Request property `CookieContainer` not supported when the client is explicitly created without an HttpClientHandler, use the proper constructor.");
|
||||
if (_httpClientHandler == null) throw new InvalidOperationException("Request property `CookieContainer` not supported when the client is explicitly created without an HttpClientHandler, use the proper constructor.");
|
||||
foreach (var cookie in cookieContainer)
|
||||
{
|
||||
_httpClientHandler.CookieContainer.Add(cookie);
|
||||
@@ -546,11 +563,11 @@ namespace {{packageName}}.Client
|
||||
// if the response type is oneOf/anyOf, call FromJSON to deserialize the data
|
||||
if (typeof({{{packageName}}}.{{modelPackage}}.AbstractOpenAPISchema).IsAssignableFrom(typeof(T)))
|
||||
{
|
||||
responseData = (T) typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content });
|
||||
responseData = (T)typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content });
|
||||
}
|
||||
else if (typeof(T).Name == "Stream") // for binary response
|
||||
{
|
||||
responseData = (T) (object) await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
|
||||
responseData = (T)(object) await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
InterceptResponse(req, response);
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
@BuiltValueHook(initializeBuilder: true)
|
||||
static void _defaults({{{classname}}}Builder b) => b{{#vendorExtensions.x-parent-discriminator}}..{{propertyName}}=b.discriminatorValue{{/vendorExtensions.x-parent-discriminator}}{{#vendorExtensions.x-self-and-ancestor-only-props}}{{#defaultValue}}
|
||||
..{{{name}}} = {{#isEnum}}{{^isContainer}}{{{defaultValue}}}{{/isContainer}}{{/isEnum}}{{^isEnum}}{{{defaultValue}}}{{/isEnum}}{{/defaultValue}}{{/vendorExtensions.x-self-and-ancestor-only-props}};
|
||||
..{{{name}}} = {{#isEnum}}{{^isContainer}}{{#enumName}}{{enumName}}.valueOf({{{defaultValue}}}){{/enumName}}{{^enumName}}{{{defaultValue}}}{{/enumName}}{{/isContainer}}{{/isEnum}}{{^isEnum}}{{{defaultValue}}}{{/isEnum}}{{/defaultValue}}{{/vendorExtensions.x-self-and-ancestor-only-props}};
|
||||
|
||||
{{/vendorExtensions.x-is-parent}} @BuiltValueSerializer(custom: true)
|
||||
static Serializer<{{classname}}> get serializer => _${{classname}}Serializer();
|
||||
@@ -1,6 +1,6 @@
|
||||
package {{package}};
|
||||
|
||||
{{^jdk8-no-delegate}}
|
||||
{{^isDelegate}}
|
||||
{{#imports}}import {{import}};
|
||||
{{/imports}}
|
||||
|
||||
@@ -8,9 +8,9 @@ import io.swagger.annotations.*;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
{{/jdk8-no-delegate}}
|
||||
{{/isDelegate}}
|
||||
import org.springframework.stereotype.Controller;
|
||||
{{^jdk8-no-delegate}}
|
||||
{{^isDelegate}}
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
@@ -26,7 +26,7 @@ import java.util.Optional;
|
||||
{{#async}}
|
||||
import java.util.concurrent.Callable;
|
||||
{{/async}}
|
||||
{{/jdk8-no-delegate}}
|
||||
{{/isDelegate}}
|
||||
{{^useSpringCloudClient}}
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import java.io.IOException;
|
||||
@@ -60,7 +60,7 @@ public class {{classname}}Controller implements {{classname}} {
|
||||
}
|
||||
|
||||
{{/isDelegate}}
|
||||
{{^jdk8-no-delegate}}
|
||||
{{^isDelegate}}
|
||||
{{#operation}}
|
||||
public {{#async}}Callable<{{/async}}ResponseEntity<{{>returnTypes}}>{{#async}}>{{/async}} {{operationId}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}},
|
||||
{{/allParams}}@RequestHeader(value = "Accept", required = false) String accept) throws Exception {
|
||||
@@ -111,6 +111,6 @@ public class {{classname}}Controller implements {{classname}} {
|
||||
}
|
||||
|
||||
{{/operation}}
|
||||
{{/jdk8-no-delegate}}
|
||||
{{/isDelegate}}
|
||||
}
|
||||
{{/operations}}
|
||||
|
||||
@@ -18,9 +18,9 @@ public class {{classname}}MockServer {
|
||||
@Deprecated
|
||||
{{/isDeprecated}}
|
||||
public static MappingBuilder stub{{#lambda.pascalcase}}{{operationId}}{{/lambda.pascalcase}}{{{code}}}({{#allParams}}{{#required}}{{#isNullable}}@{{javaxPackage}}.annotation.Nullable {{/isNullable}}{{^isNullable}}@{{javaxPackage}}.annotation.Nonnull {{/isNullable}}{{/required}}{{^required}}@{{javaxPackage}}.annotation.Nullable {{/required}}{{^isBodyParam}}String {{paramName}}{{/isBodyParam}}{{#isBodyParam}}String body{{/isBodyParam}}{{^-last}}, {{/-last}}{{#-last}}{{#headers.0}}, {{/headers.0}}{{^headers.0}}{{#returnType}}, {{/returnType}}{{/headers.0}}{{/-last}}{{/allParams}}{{#headers}}String response{{#lambda.pascalcase}}{{baseName}}{{/lambda.pascalcase}}{{^-last}}, {{/-last}}{{#-last}}{{#returnType}}, {{/returnType}}{{/-last}}{{/headers}}{{#returnType}}String response{{/returnType}}) {
|
||||
MappingBuilder stub = {{#lambda.lowercase}}{{httpMethod}}{{/lambda.lowercase}}({{^pathParams.0}}urlPathEqualTo{{/pathParams.0}}{{#pathParams.0}}urlPathTemplate{{/pathParams.0}}("{{{path}}}")){{#hasProduces}}
|
||||
.withHeader("Accept", havingExactly({{#produces}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/produces}})){{/hasProduces}}{{#hasAuthMethods}}{{#hasConsumes}}
|
||||
.withHeader("Content-Type", havingExactly("{{#consumes.0}}{{{mediaType}}}{{/consumes.0}}")){{/hasConsumes}}
|
||||
MappingBuilder stub = {{#lambda.lowercase}}{{httpMethod}}{{/lambda.lowercase}}({{^pathParams.0}}urlPathEqualTo{{/pathParams.0}}{{#pathParams.0}}urlPathTemplate{{/pathParams.0}}("{{{path}}}")){{#hasProduces}}{{#produces}}
|
||||
.withHeader("Accept", containing("{{{mediaType}}}")){{/produces}}{{/hasProduces}}{{#hasAuthMethods}}{{#hasConsumes}}
|
||||
.withHeader("Content-Type", havingExactly(equalToIgnoreCase("{{#consumes.0}}{{{mediaType}}}{{/consumes.0}}"))){{/hasConsumes}}
|
||||
.withHeader("Authorization", matching(".*")){{/hasAuthMethods}}{{#cookieParams}}
|
||||
.withCookie("{{baseName}}", havingExactly({{paramName}})){{/cookieParams}}{{#hasBodyParam}}
|
||||
.withRequestBody(equalToJson(body)){{/hasBodyParam}}
|
||||
@@ -105,9 +105,9 @@ public class {{classname}}MockServer {
|
||||
{{/responses}}
|
||||
|
||||
public static MappingBuilder stub{{#lambda.pascalcase}}{{operationId}}{{/lambda.pascalcase}}Fault({{#allParams}}{{#required}}{{#isNullable}}@{{javaxPackage}}.annotation.Nullable {{/isNullable}}{{^isNullable}}@{{javaxPackage}}.annotation.Nonnull {{/isNullable}}{{/required}}{{^required}}@{{javaxPackage}}.annotation.Nullable {{/required}}{{^isBodyParam}}String {{paramName}}{{/isBodyParam}}{{#isBodyParam}}String body{{/isBodyParam}}, {{/allParams}}Fault fault) {
|
||||
MappingBuilder stub = {{#lambda.lowercase}}{{httpMethod}}{{/lambda.lowercase}}({{^pathParams.0}}urlPathEqualTo{{/pathParams.0}}{{#pathParams.0}}urlPathTemplate{{/pathParams.0}}("{{{path}}}")){{#hasProduces}}
|
||||
.withHeader("Accept", havingExactly({{#produces}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/produces}})){{/hasProduces}}{{#hasAuthMethods}}{{#hasConsumes}}
|
||||
.withHeader("Content-Type", havingExactly("{{#consumes.0}}{{{mediaType}}}{{/consumes.0}}")){{/hasConsumes}}
|
||||
MappingBuilder stub = {{#lambda.lowercase}}{{httpMethod}}{{/lambda.lowercase}}({{^pathParams.0}}urlPathEqualTo{{/pathParams.0}}{{#pathParams.0}}urlPathTemplate{{/pathParams.0}}("{{{path}}}")){{#hasProduces}}{{#produces}}
|
||||
.withHeader("Accept", containing("{{{mediaType}}}")){{/produces}}{{/hasProduces}}{{#hasAuthMethods}}{{#hasConsumes}}
|
||||
.withHeader("Content-Type", havingExactly(equalToIgnoreCase("{{#consumes.0}}{{{mediaType}}}{{/consumes.0}}"))){{/hasConsumes}}
|
||||
.withHeader("Authorization", matching(".*")){{/hasAuthMethods}}{{#cookieParams}}
|
||||
.withCookie("{{baseName}}", havingExactly({{paramName}})){{/cookieParams}}{{#bodyParam}}
|
||||
.withRequestBody(equalToJson(body)){{/bodyParam}}
|
||||
|
||||
@@ -37,14 +37,14 @@ apply plugin: "java"
|
||||
apply plugin: "kotlin"
|
||||
apply plugin: "application"
|
||||
|
||||
sourceCompatibility = 1.8
|
||||
sourceCompatibility = 11
|
||||
|
||||
compileKotlin {
|
||||
kotlinOptions.jvmTarget = "1.8"
|
||||
kotlinOptions.jvmTarget = "11"
|
||||
}
|
||||
|
||||
compileTestKotlin {
|
||||
kotlinOptions.jvmTarget = "1.8"
|
||||
kotlinOptions.jvmTarget = "11"
|
||||
}
|
||||
|
||||
repositories {
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
{{#isEmail}}@Email {{/isEmail}}{{!
|
||||
pattern set
|
||||
}}{{#pattern}}@Pattern(regexp="{{{.}}}") {{/pattern}}{{!
|
||||
}}{{#pattern}}@Pattern(regexp="{{{.}}}"{{#vendorExtensions.x-pattern-message}}, message="{{vendorExtensions.x-pattern-message}}"{{/vendorExtensions.x-pattern-message}}) {{/pattern}}{{!
|
||||
minLength && maxLength set
|
||||
}}{{#minLength}}{{#maxLength}}@Size(min={{minLength}},max={{maxLength}}) {{/maxLength}}{{/minLength}}{{!
|
||||
}}{{#minLength}}{{#maxLength}}@Size(min={{minLength}},max={{maxLength}}{{#vendorExtensions.x-size-message}}, message="{{vendorExtensions.x-size-message}}"{{/vendorExtensions.x-size-message}}) {{/maxLength}}{{/minLength}}{{!
|
||||
minLength set, maxLength not
|
||||
}}{{#minLength}}{{^maxLength}}@Size(min={{minLength}}) {{/maxLength}}{{/minLength}}{{!
|
||||
}}{{#minLength}}{{^maxLength}}@Size(min={{minLength}}{{#vendorExtensions.x-size-message}}, message="{{vendorExtensions.x-size-message}}"{{/vendorExtensions.x-size-message}}) {{/maxLength}}{{/minLength}}{{!
|
||||
minLength not set, maxLength set
|
||||
}}{{^minLength}}{{#maxLength}}@Size(max={{.}}) {{/maxLength}}{{/minLength}}{{!
|
||||
}}{{^minLength}}{{#maxLength}}@Size(max={{.}}{{#vendorExtensions.x-size-message}}, message="{{vendorExtensions.x-size-message}}"{{/vendorExtensions.x-size-message}}) {{/maxLength}}{{/minLength}}{{!
|
||||
@Size: minItems && maxItems set
|
||||
}}{{#minItems}}{{#maxItems}}@Size(min={{minItems}},max={{maxItems}}) {{/maxItems}}{{/minItems}}{{!
|
||||
}}{{#minItems}}{{#maxItems}}@Size(min={{minItems}},max={{maxItems}}{{#vendorExtensions.x-size-message}}, message="{{vendorExtensions.x-size-message}}"{{/vendorExtensions.x-size-message}}) {{/maxItems}}{{/minItems}}{{!
|
||||
@Size: minItems set, maxItems not
|
||||
}}{{#minItems}}{{^maxItems}}@Size(min={{minItems}}) {{/maxItems}}{{/minItems}}{{!
|
||||
}}{{#minItems}}{{^maxItems}}@Size(min={{minItems}}{{#vendorExtensions.x-size-message}}, message="{{vendorExtensions.x-size-message}}"{{/vendorExtensions.x-size-message}}) {{/maxItems}}{{/minItems}}{{!
|
||||
@Size: minItems not set && maxItems set
|
||||
}}{{^minItems}}{{#maxItems}}@Size(max={{.}}) {{/maxItems}}{{/minItems}}{{!
|
||||
}}{{^minItems}}{{#maxItems}}@Size(max={{.}}{{#vendorExtensions.x-size-message}}, message="{{vendorExtensions.x-size-message}}"{{/vendorExtensions.x-size-message}}) {{/maxItems}}{{/minItems}}{{!
|
||||
check for integer or long / all others=decimal type with @Decimal*
|
||||
isInteger set
|
||||
}}{{#isInteger}}{{#minimum}}@Min({{.}}){{/minimum}}{{#maximum}} @Max({{.}}) {{/maximum}}{{/isInteger}}{{!
|
||||
}}{{#isInteger}}{{#minimum}}@Min(value={{.}}{{#vendorExtensions.x-minimum-message}}, message="{{vendorExtensions.x-minimum-message}}"{{/vendorExtensions.x-minimum-message}}){{/minimum}}{{#maximum}} @Max(value={{.}}{{#vendorExtensions.x-maximum-message}}, message="{{vendorExtensions.x-maximum-message}}"{{/vendorExtensions.x-maximum-message}}) {{/maximum}}{{/isInteger}}{{!
|
||||
isLong set
|
||||
}}{{#isLong}}{{#minimum}}@Min({{.}}L){{/minimum}}{{#maximum}} @Max({{.}}L) {{/maximum}}{{/isLong}}{{!
|
||||
}}{{#isLong}}{{#minimum}}@Min(value={{.}}L{{#vendorExtensions.x-minimum-message}}, message="{{vendorExtensions.x-minimum-message}}"{{/vendorExtensions.x-minimum-message}}){{/minimum}}{{#maximum}} @Max(value={{.}}L{{#vendorExtensions.x-maximum-message}}, message="{{vendorExtensions.x-maximum-message}}"{{/vendorExtensions.x-maximum-message}}) {{/maximum}}{{/isLong}}{{!
|
||||
Not Integer, not Long => we have a decimal value!
|
||||
}}{{^isInteger}}{{^isLong}}{{#minimum}}@DecimalMin("{{.}}"){{/minimum}}{{#maximum}} @DecimalMax("{{.}}") {{/maximum}}{{/isLong}}{{/isInteger}}
|
||||
}}{{^isInteger}}{{^isLong}}{{#minimum}}@DecimalMin(value="{{.}}"{{#vendorExtensions.x-minimum-message}}, message="{{vendorExtensions.x-minimum-message}}"{{/vendorExtensions.x-minimum-message}}){{/minimum}}{{#maximum}} @DecimalMax(value="{{.}}"{{#vendorExtensions.x-maximum-message}}, message="{{vendorExtensions.x-maximum-message}}"{{/vendorExtensions.x-maximum-message}}) {{/maximum}}{{/isLong}}{{/isInteger}}
|
||||
@@ -7,32 +7,32 @@ pattern set
|
||||
@get:Pattern(regexp="{{{pattern}}}"{{#vendorExtensions.x-pattern-message}}, message="{{vendorExtensions.x-pattern-message}}"{{/vendorExtensions.x-pattern-message}}){{/pattern}}{{!
|
||||
minLength && maxLength set
|
||||
}}{{#minLength}}{{#maxLength}}
|
||||
@get:Size(min={{minLength}},max={{maxLength}}){{/maxLength}}{{/minLength}}{{!
|
||||
@get:Size(min={{minLength}},max={{maxLength}}{{#vendorExtensions.x-size-message}}, message="{{vendorExtensions.x-size-message}}"{{/vendorExtensions.x-size-message}}){{/maxLength}}{{/minLength}}{{!
|
||||
minLength set, maxLength not
|
||||
}}{{#minLength}}{{^maxLength}}
|
||||
@get:Size(min={{minLength}}){{/maxLength}}{{/minLength}}{{!
|
||||
@get:Size(min={{minLength}}{{#vendorExtensions.x-size-message}}, message="{{vendorExtensions.x-size-message}}"{{/vendorExtensions.x-size-message}}){{/maxLength}}{{/minLength}}{{!
|
||||
minLength not set, maxLength set
|
||||
}}{{^minLength}}{{#maxLength}}
|
||||
@get:Size(max={{.}}){{/maxLength}}{{/minLength}}{{!
|
||||
@get:Size(max={{.}}{{#vendorExtensions.x-size-message}}, message="{{vendorExtensions.x-size-message}}"{{/vendorExtensions.x-size-message}}){{/maxLength}}{{/minLength}}{{!
|
||||
@Size: minItems && maxItems set
|
||||
}}{{#minItems}}{{#maxItems}}
|
||||
@get:Size(min={{minItems}},max={{maxItems}}) {{/maxItems}}{{/minItems}}{{!
|
||||
@get:Size(min={{minItems}},max={{maxItems}}{{#vendorExtensions.x-size-message}}, message="{{vendorExtensions.x-size-message}}"{{/vendorExtensions.x-size-message}}) {{/maxItems}}{{/minItems}}{{!
|
||||
@Size: minItems set, maxItems not
|
||||
}}{{#minItems}}{{^maxItems}}
|
||||
@get:Size(min={{minItems}}){{/maxItems}}{{/minItems}}{{!
|
||||
@get:Size(min={{minItems}}{{#vendorExtensions.x-size-message}}, message="{{vendorExtensions.x-size-message}}"{{/vendorExtensions.x-size-message}}){{/maxItems}}{{/minItems}}{{!
|
||||
@Size: minItems not set && maxItems set
|
||||
}}{{^minItems}}{{#maxItems}}
|
||||
@get:Size(max={{.}}){{/maxItems}}{{/minItems}}{{!
|
||||
@get:Size(max={{.}}{{#vendorExtensions.x-size-message}}, message="{{vendorExtensions.x-size-message}}"{{/vendorExtensions.x-size-message}}){{/maxItems}}{{/minItems}}{{!
|
||||
check for integer or long / all others=decimal type with @Decimal*
|
||||
isInteger set
|
||||
}}{{#isInteger}}{{#minimum}}
|
||||
@get:Min({{.}}){{/minimum}}{{#maximum}}
|
||||
@get:Max({{.}}){{/maximum}}{{/isInteger}}{{!
|
||||
@get:Min(value={{.}}{{#vendorExtensions.x-minimum-message}}, message="{{vendorExtensions.x-minimum-message}}"{{/vendorExtensions.x-minimum-message}}){{/minimum}}{{#maximum}}
|
||||
@get:Max(value={{.}}{{#vendorExtensions.x-maximum-message}}, message="{{vendorExtensions.x-maximum-message}}"{{/vendorExtensions.x-maximum-message}}){{/maximum}}{{/isInteger}}{{!
|
||||
isLong set
|
||||
}}{{#isLong}}{{#minimum}}
|
||||
@get:Min({{.}}L){{/minimum}}{{#maximum}}
|
||||
@get:Max({{.}}L){{/maximum}}{{/isLong}}{{!
|
||||
@get:Min(value={{.}}L{{#vendorExtensions.x-minimum-message}}, message="{{vendorExtensions.x-minimum-message}}"{{/vendorExtensions.x-minimum-message}}){{/minimum}}{{#maximum}}
|
||||
@get:Max(value={{.}}L{{#vendorExtensions.x-maximum-message}}, message="{{vendorExtensions.x-maximum-message}}"{{/vendorExtensions.x-maximum-message}}){{/maximum}}{{/isLong}}{{!
|
||||
Not Integer, not Long => we have a decimal value!
|
||||
}}{{^isInteger}}{{^isLong}}{{#minimum}}
|
||||
@get:DecimalMin("{{.}}"){{/minimum}}{{#maximum}}
|
||||
@get:DecimalMax("{{.}}"){{/maximum}}{{/isLong}}{{/isInteger}}
|
||||
@get:DecimalMin(value="{{.}}"{{#vendorExtensions.x-minimum-message}}, message="{{vendorExtensions.x-minimum-message}}"{{/vendorExtensions.x-minimum-message}}){{/minimum}}{{#maximum}}
|
||||
@get:DecimalMax(value="{{.}}"{{#vendorExtensions.x-maximum-message}}, message="{{vendorExtensions.x-maximum-message}}"{{/vendorExtensions.x-maximum-message}}){{/maximum}}{{/isLong}}{{/isInteger}}
|
||||
@@ -17,7 +17,7 @@ repositories {
|
||||
}
|
||||
|
||||
tasks.withType<KotlinCompile> {
|
||||
kotlinOptions.jvmTarget = "1.8"
|
||||
kotlinOptions.jvmTarget = "11"
|
||||
}
|
||||
|
||||
{{#interfaceOnly}}
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
<compilerPlugins>
|
||||
<plugin>spring</plugin>
|
||||
</compilerPlugins>
|
||||
<jvmTarget>1.8</jvmTarget>
|
||||
<jvmTarget>11</jvmTarget>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
<compilerPlugins>
|
||||
<plugin>spring</plugin>
|
||||
</compilerPlugins>
|
||||
<jvmTarget>1.8</jvmTarget>
|
||||
<jvmTarget>11</jvmTarget>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
|
||||
@@ -1 +1 @@
|
||||
{{^isFile}}{{{dataType}}}{{^required}}{{^defaultValue}}?{{/defaultValue}}{{/required}}{{/isFile}}{{#isFile}}{{#isArray}}Array<{{/isArray}}org.springframework.web.multipart.MultipartFile{{#isArray}}>{{/isArray}}{{^isArray}}{{^required}}?{{/required}}{{/isArray}}{{/isFile}}
|
||||
{{^isFile}}{{{dataType}}}{{^required}}{{^defaultValue}}?{{/defaultValue}}{{/required}}{{/isFile}}{{#isFile}}{{#isArray}}Array<{{/isArray}}org.springframework.web.multipart.MultipartFile{{#isArray}}>{{/isArray}}{{#isNullable}}?{{/isNullable}}{{/isFile}}
|
||||
@@ -630,7 +630,7 @@ impl std::convert::From<{{{dataType}}}> for {{{classname}}} {
|
||||
|
||||
impl std::fmt::Display for {{{classname}}} {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{:?}", self.0)
|
||||
write!(f, "{}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -99,6 +99,9 @@ pub enum {{{operationIdCamelCase}}}Error {
|
||||
{{#notes}}
|
||||
/// {{{.}}}
|
||||
{{/notes}}
|
||||
{{#isDeprecated}}
|
||||
#[deprecated]
|
||||
{{/isDeprecated}}
|
||||
{{#vendorExtensions.x-group-parameters}}
|
||||
pub {{#supportAsync}}async {{/supportAsync}}fn {{{operationId}}}(configuration: &configuration::Configuration{{#allParams}}{{#-first}}, {{!
|
||||
### Params
|
||||
|
||||
@@ -74,6 +74,7 @@ export class {{classname}} extends BaseService {
|
||||
{{#notes}}
|
||||
* {{.}}
|
||||
{{/notes}}
|
||||
* @endpoint {{httpMethod}} {{{path}}}
|
||||
{{^useSingleRequestParameter}}
|
||||
{{#allParams}}
|
||||
* @param {{paramName}} {{description}}
|
||||
|
||||
@@ -38,6 +38,7 @@ export interface {{classname}}Interface {
|
||||
/**
|
||||
* {{summary}}
|
||||
* {{notes}}
|
||||
* @endpoint {{httpMethod}} {{{path}}}
|
||||
{{^useSingleRequestParameter}}
|
||||
{{#allParams}}* @param {{paramName}} {{description}}
|
||||
{{/allParams}}{{/useSingleRequestParameter}}{{#useSingleRequestParameter}}{{#allParams.0}}* @param requestParameters
|
||||
|
||||
@@ -17,7 +17,7 @@ import FormData from 'form-data'
|
||||
{{/withNodeImports}}
|
||||
// Some imports not used depending on template conditions
|
||||
// @ts-ignore
|
||||
import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from './common{{importFileExtension}}';
|
||||
import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction{{#withAWSV4Signature}}, setAWS4SignatureInterceptor{{/withAWSV4Signature}} } from './common{{importFileExtension}}';
|
||||
import type { RequestArgs } from './base{{importFileExtension}}';
|
||||
// @ts-ignore
|
||||
import { BASE_PATH, COLLECTION_FORMATS, BaseAPI, RequiredError, operationServerMap } from './base{{importFileExtension}}';
|
||||
|
||||
@@ -17,7 +17,7 @@ import FormData from 'form-data'
|
||||
{{/withNodeImports}}
|
||||
// Some imports not used depending on template conditions
|
||||
// @ts-ignore
|
||||
import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '{{apiRelativeToRoot}}common{{importFileExtension}}';
|
||||
import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction{{#withAWSV4Signature}}, setAWS4SignatureInterceptor{{/withAWSV4Signature}} } from '{{apiRelativeToRoot}}common{{importFileExtension}}';
|
||||
// @ts-ignore
|
||||
import { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '{{apiRelativeToRoot}}base{{importFileExtension}}';
|
||||
{{#imports}}
|
||||
@@ -71,6 +71,10 @@ export const {{classname}}AxiosParamCreator = function (configuration?: Configur
|
||||
{{#authMethods}}
|
||||
// authentication {{name}} required
|
||||
{{#isApiKey}}
|
||||
{{#withAWSV4Signature}}
|
||||
// aws v4 signature authentication required
|
||||
await setAWS4SignatureInterceptor(globalAxios, configuration)
|
||||
{{/withAWSV4Signature}}
|
||||
{{#isKeyInHeader}}
|
||||
await setApiKeyToObject(localVarHeaderParameter, "{{keyParamName}}", configuration)
|
||||
{{/isKeyInHeader}}
|
||||
|
||||
@@ -2,10 +2,12 @@
|
||||
/* eslint-disable */
|
||||
{{>licenseInfo}}
|
||||
|
||||
|
||||
import type { Configuration } from "./configuration{{importFileExtension}}";
|
||||
import type { RequestArgs } from "./base{{importFileExtension}}";
|
||||
import type { AxiosInstance, AxiosResponse } from 'axios';
|
||||
{{#withAWSV4Signature}}
|
||||
import { aws4Interceptor } from "aws4-axios";
|
||||
{{/withAWSV4Signature}}
|
||||
import { RequiredError } from "./base{{importFileExtension}}";
|
||||
{{#withNodeImports}}
|
||||
import { URL, URLSearchParams } from 'url';
|
||||
@@ -56,6 +58,25 @@ export const setOAuthToObject = async function (object: any, name: string, scope
|
||||
}
|
||||
}
|
||||
|
||||
{{#withAWSV4Signature}}
|
||||
export const setAWS4SignatureInterceptor = async function (globalAxios: AxiosInstance, configuration?: Configuration) {
|
||||
if (configuration && configuration.awsv4) {
|
||||
const interceptor = aws4Interceptor({
|
||||
options: {
|
||||
region: configuration.awsv4?.options?.region ?? process.env.AWS_REGION ?? 'us-east-1',
|
||||
service: configuration.awsv4?.options?.service ?? 'execute-api',
|
||||
},
|
||||
credentials: {
|
||||
accessKeyId: configuration.awsv4?.credentials?.accessKeyId ?? process.env.AWS_ACCESS_KEY_ID,
|
||||
secretAccessKey: configuration.awsv4?.credentials?.secretAccessKey ?? process.env.AWS_SECRET_ACCESS_KEY,
|
||||
sessionToken: configuration.awsv4?.credentials?.sessionToken ?? process.env.AWS_SESSION_TOKEN
|
||||
},
|
||||
});
|
||||
globalAxios.interceptors.request.use(interceptor);
|
||||
}
|
||||
}
|
||||
{{/withAWSV4Signature}}
|
||||
|
||||
function setFlattenedQueryParams(urlSearchParams: URLSearchParams, parameter: any, key: string = ""): void {
|
||||
if (parameter == null) return;
|
||||
if (typeof parameter === "object") {
|
||||
|
||||
@@ -1,13 +1,24 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
{{>licenseInfo}}
|
||||
|
||||
interface AWSv4Configuration {
|
||||
options?: {
|
||||
region?: string
|
||||
service?: string
|
||||
}
|
||||
credentials?: {
|
||||
accessKeyId?: string
|
||||
secretAccessKey?: string,
|
||||
sessionToken?: string
|
||||
}
|
||||
}
|
||||
|
||||
export interface ConfigurationParameters {
|
||||
apiKey?: string | Promise<string> | ((name: string) => string) | ((name: string) => Promise<string>);
|
||||
username?: string;
|
||||
password?: string;
|
||||
accessToken?: string | Promise<string> | ((name?: string, scopes?: string[]) => string) | ((name?: string, scopes?: string[]) => Promise<string>);
|
||||
awsv4?: AWSv4Configuration;
|
||||
basePath?: string;
|
||||
serverIndex?: number;
|
||||
baseOptions?: any;
|
||||
@@ -34,6 +45,17 @@ export class Configuration {
|
||||
* @param scopes oauth2 scope
|
||||
*/
|
||||
accessToken?: string | Promise<string> | ((name?: string, scopes?: string[]) => string) | ((name?: string, scopes?: string[]) => Promise<string>);
|
||||
/**
|
||||
* parameter for aws4 signature security
|
||||
* @param {Object} AWS4Signature - AWS4 Signature security
|
||||
* @param {string} options.region - aws region
|
||||
* @param {string} options.service - name of the service.
|
||||
* @param {string} credentials.accessKeyId - aws access key id
|
||||
* @param {string} credentials.secretAccessKey - aws access key
|
||||
* @param {string} credentials.sessionToken - aws session token
|
||||
* @memberof Configuration
|
||||
*/
|
||||
awsv4?: AWSv4Configuration;
|
||||
/**
|
||||
* override base path
|
||||
*/
|
||||
@@ -60,6 +82,7 @@ export class Configuration {
|
||||
this.username = param.username;
|
||||
this.password = param.password;
|
||||
this.accessToken = param.accessToken;
|
||||
this.awsv4 = param.awsv4;
|
||||
this.basePath = param.basePath;
|
||||
this.serverIndex = param.serverIndex;
|
||||
this.baseOptions = {
|
||||
|
||||
@@ -27,6 +27,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "{{axiosVersion}}"
|
||||
{{#withAWSV4Signature}}
|
||||
"aws4-axios": "^3.3.4"
|
||||
{{/withAWSV4Signature}}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "12.11.5 - 12.20.42",
|
||||
|
||||
@@ -5036,6 +5036,19 @@ public class DefaultCodegenTest {
|
||||
assertTrue(codegenOperation.queryParams.stream().allMatch(p -> p.queryIsJsonMimeType));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultOauthIsNotNull() {
|
||||
final DefaultCodegen codegen = new DefaultCodegen();
|
||||
final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_1/issue_20662.yaml");
|
||||
codegen.setOpenAPI(openAPI);
|
||||
List<CodegenSecurity> securitySchemes = codegen.fromSecurity(openAPI.getComponents().getSecuritySchemes());
|
||||
assertThat(securitySchemes.size()).isEqualTo(1);
|
||||
CodegenSecurity openIdScheme = securitySchemes.get(0);
|
||||
assertNotNull(openIdScheme.isOAuth);
|
||||
assertFalse(openIdScheme.isOAuth);
|
||||
assertTrue(openIdScheme.isOpenId);
|
||||
}
|
||||
|
||||
private List<String> getRequiredVars(CodegenModel model) {
|
||||
return getNames(model.getRequiredVars());
|
||||
}
|
||||
|
||||
@@ -1205,4 +1205,13 @@ public class InlineModelResolverTest {
|
||||
assertNotNull(allOfRefWithDescriptionAndReadonly.getAllOf());
|
||||
assertEquals(numberRangeRef, ((Schema) allOfRefWithDescriptionAndReadonly.getAllOf().get(0)).get$ref());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonNullTypeWithProperties() {
|
||||
OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_0/issue_21680_array_with_properties.yaml");
|
||||
new InlineModelResolver().flatten(openAPI);
|
||||
Schema<?> schema = (Schema<?>) openAPI.getComponents().getSchemas().get("errors");
|
||||
assertNotNull(schema);
|
||||
assertNull(schema.getProperties());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.openapitools.codegen;
|
||||
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
import io.swagger.v3.oas.models.Operation;
|
||||
import io.swagger.v3.oas.models.PathItem;
|
||||
import io.swagger.v3.oas.models.media.*;
|
||||
import io.swagger.v3.oas.models.parameters.Parameter;
|
||||
@@ -606,8 +607,7 @@ public class OpenAPINormalizerTest {
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getDelete().getExtensions().get(X_INTERNAL), true);
|
||||
assertEquals(s.getExtensions().get(X_INTERNAL), true);
|
||||
|
||||
Map<String, String> options = new HashMap<>();
|
||||
options.put("REMOVE_X_INTERNAL", "true");
|
||||
Map<String, String> options = Map.of("REMOVE_X_INTERNAL", "true");
|
||||
OpenAPINormalizer openAPINormalizer = new OpenAPINormalizer(openAPI, options);
|
||||
openAPINormalizer.normalize();
|
||||
|
||||
@@ -623,34 +623,14 @@ public class OpenAPINormalizerTest {
|
||||
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getGet().getExtensions(), null);
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getDelete().getExtensions().get(X_INTERNAL), true);
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getPut().getExtensions(), null);
|
||||
|
||||
Map<String, String> options = new HashMap<>();
|
||||
options.put("FILTER", "operationId:delete|list");
|
||||
Map<String, String> options = Map.of("FILTER", "operationId:delete|list");
|
||||
OpenAPINormalizer openAPINormalizer = new OpenAPINormalizer(openAPI, options);
|
||||
openAPINormalizer.normalize();
|
||||
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getGet().getExtensions().get(X_INTERNAL), false);
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getDelete().getExtensions().get(X_INTERNAL), false);
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getPut().getExtensions().get(X_INTERNAL), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOperationIdFilterWithTrim() {
|
||||
OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_0/enableKeepOnlyFirstTagInOperation_test.yaml");
|
||||
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getGet().getExtensions(), null);
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getDelete().getExtensions().get(X_INTERNAL), true);
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getPut().getExtensions(), null);
|
||||
|
||||
Map<String, String> options = new HashMap<>();
|
||||
options.put("FILTER", "operationId:\n\t\t\t\tdelete|\n\t\tlist");
|
||||
OpenAPINormalizer openAPINormalizer = new OpenAPINormalizer(openAPI, options);
|
||||
openAPINormalizer.normalize();
|
||||
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getGet().getExtensions().get(X_INTERNAL), false);
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getDelete().getExtensions().get(X_INTERNAL), false);
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getPut().getExtensions().get(X_INTERNAL), true);
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getGet().getExtensions().get("x-internal"), false);
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getDelete().getExtensions().get("x-internal"), false);
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getPut().getExtensions().get("x-internal"), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -659,10 +639,8 @@ public class OpenAPINormalizerTest {
|
||||
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getGet().getExtensions(), null);
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getDelete().getExtensions().get(X_INTERNAL), true);
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getPut().getExtensions(), null);
|
||||
|
||||
Map<String, String> options = new HashMap<>();
|
||||
options.put("FILTER", "method:get");
|
||||
Map<String, String> options = Map.of("FILTER", "method:get");
|
||||
OpenAPINormalizer openAPINormalizer = new OpenAPINormalizer(openAPI, options);
|
||||
openAPINormalizer.normalize();
|
||||
|
||||
@@ -670,22 +648,58 @@ public class OpenAPINormalizerTest {
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getDelete().getExtensions().get(X_INTERNAL), true);
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getPut().getExtensions().get(X_INTERNAL), true);
|
||||
}
|
||||
|
||||
static OpenAPINormalizer.Filter parseFilter(String filters) {
|
||||
OpenAPINormalizer.Filter filter = new OpenAPINormalizer.Filter(filters);
|
||||
filter.parse();
|
||||
return filter;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFilterWithMethodWithTrim() {
|
||||
OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_0/enableKeepOnlyFirstTagInOperation_test.yaml");
|
||||
public void testFilterParsing() {
|
||||
OpenAPINormalizer.Filter filter;
|
||||
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getGet().getExtensions(), null);
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getDelete().getExtensions().get(X_INTERNAL), true);
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getPut().getExtensions(), null);
|
||||
// no filter
|
||||
filter = parseFilter(" ");
|
||||
assertFalse(filter.hasFilter());
|
||||
|
||||
Map<String, String> options = new HashMap<>();
|
||||
options.put("FILTER", "method:\n\t\t\t\tget");
|
||||
OpenAPINormalizer openAPINormalizer = new OpenAPINormalizer(openAPI, options);
|
||||
openAPINormalizer.normalize();
|
||||
// invalid filter
|
||||
assertThrows(IllegalArgumentException.class, () ->
|
||||
parseFilter("operationId:"));
|
||||
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getGet().getExtensions().get(X_INTERNAL), false);
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getDelete().getExtensions().get(X_INTERNAL), true);
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getPut().getExtensions().get(X_INTERNAL), true);
|
||||
assertThrows(IllegalArgumentException.class, () ->
|
||||
parseFilter("invalid:invalid:"));
|
||||
|
||||
// extra spaces are trimmed
|
||||
filter = parseFilter("method:\n\t\t\t\tget");
|
||||
assertTrue(filter.hasFilter());
|
||||
assertEquals(filter.methodFilters, Set.of("get"));
|
||||
assertTrue(filter.operationIdFilters.isEmpty());
|
||||
assertTrue(filter.tagFilters.isEmpty());
|
||||
assertTrue(filter.pathStartingWithFilters.isEmpty());
|
||||
|
||||
// multiple values separated by pipe
|
||||
filter = parseFilter("operationId:\n\t\t\t\tdelete|\n\t\tlist\t");
|
||||
assertTrue(filter.hasFilter());
|
||||
assertTrue(filter.methodFilters.isEmpty());
|
||||
assertEquals(filter.operationIdFilters, Set.of("delete", "list"));
|
||||
assertTrue(filter.tagFilters.isEmpty());
|
||||
assertTrue(filter.pathStartingWithFilters.isEmpty());
|
||||
|
||||
// multiple filters
|
||||
filter = parseFilter("operationId:delete|list;path:/v1");
|
||||
assertTrue(filter.hasFilter());
|
||||
assertTrue(filter.methodFilters.isEmpty());
|
||||
assertEquals(filter.operationIdFilters, Set.of("delete", "list"));
|
||||
assertTrue(filter.tagFilters.isEmpty());
|
||||
assertEquals(filter.pathStartingWithFilters, Set.of("/v1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiFilterParsing() {
|
||||
OpenAPINormalizer.Filter filter = parseFilter("operationId: delete| list ; tag : testA |testB ");
|
||||
assertEquals(filter.operationIdFilters, Set.of("delete", "list"));
|
||||
assertEquals(filter.tagFilters, Set.of("testA", "testB"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -694,10 +708,8 @@ public class OpenAPINormalizerTest {
|
||||
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getGet().getExtensions(), null);
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getDelete().getExtensions().get(X_INTERNAL), true);
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getPut().getExtensions(), null);
|
||||
|
||||
Map<String, String> options = new HashMap<>();
|
||||
options.put("FILTER", "tag:basic");
|
||||
Map<String, String> options = Map.of("FILTER", "tag:basic");
|
||||
OpenAPINormalizer openAPINormalizer = new OpenAPINormalizer(openAPI, options);
|
||||
openAPINormalizer.normalize();
|
||||
|
||||
@@ -705,24 +717,74 @@ public class OpenAPINormalizerTest {
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getDelete().getExtensions().get(X_INTERNAL), true);
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getPut().getExtensions().get(X_INTERNAL), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFilterWithTagWithTrim() {
|
||||
public void testCustomRoleFilter() {
|
||||
OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_0/enableKeepOnlyFirstTagInOperation_test.yaml");
|
||||
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getGet().getExtensions(), null);
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getDelete().getExtensions().get(X_INTERNAL), true);
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getPut().getExtensions(), null);
|
||||
|
||||
Map<String, String> options = new HashMap<>();
|
||||
options.put("FILTER", "tag:basic");
|
||||
OpenAPINormalizer openAPINormalizer = new OpenAPINormalizer(openAPI, options);
|
||||
Map<String, String> options = Map.of("FILTER", "role:admin");
|
||||
OpenAPINormalizer openAPINormalizer = new OpenAPINormalizer(openAPI, options) {
|
||||
@Override
|
||||
protected Filter createFilter(OpenAPI openApi, String filters) {
|
||||
return new CustomRoleFilter(filters);
|
||||
}
|
||||
};
|
||||
openAPINormalizer.normalize();
|
||||
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getGet().getExtensions().get(X_INTERNAL), false);
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getGet().getExtensions().get(X_INTERNAL), true);
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getDelete().getExtensions().get(X_INTERNAL), true);
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getPut().getExtensions().get(X_INTERNAL), true);
|
||||
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getPut().getExtensions().get(X_INTERNAL), false);
|
||||
}
|
||||
|
||||
private class CustomRoleFilter extends OpenAPINormalizer.Filter {
|
||||
private Set<String> filteredRoles;
|
||||
|
||||
public CustomRoleFilter(String filters) {
|
||||
super(filters);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void parse(String filterName, String filterValue) {
|
||||
if ("role".equals(filterName)) {
|
||||
this.filteredRoles = splitByPipe(filterValue);
|
||||
} else {
|
||||
parseFails(filterName, filterValue);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasCustomFilterMatch(String path, Operation operation) {
|
||||
return operation.getExtensions() != null && filteredRoles.contains(operation.getExtensions().get("x-role"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFilterInvalidSyntaxDoesThrow() {
|
||||
OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_0/enableKeepOnlyFirstTagInOperation_test.yaml");
|
||||
|
||||
Map<String, String> options = Map.of("FILTER", "tag ; invalid");
|
||||
try {
|
||||
new OpenAPINormalizer(openAPI, options).normalize();
|
||||
fail("Expected IllegalArgumentException");
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals(e.getMessage(), "FILTER rule [tag ; invalid] must be in the form of `operationId:name1|name2|name3` or `method:get|post|put` or `tag:tag1|tag2|tag3` or `path:/v1|/v2`. Error: filter with no value not supported :[tag]");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFilterInvalidFilterDoesThrow() {
|
||||
OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_0/enableKeepOnlyFirstTagInOperation_test.yaml");
|
||||
|
||||
Map<String, String> options = Map.of("FILTER", "method:get ; unknown:test");
|
||||
try {
|
||||
new OpenAPINormalizer(openAPI, options).normalize();
|
||||
fail("Expected IllegalArgumentException");
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals(e.getMessage(), "FILTER rule [method:get ; unknown:test] must be in the form of `operationId:name1|name2|name3` or `method:get|post|put` or `tag:tag1|tag2|tag3` or `path:/v1|/v2`. Error: filter not supported :[unknown:test]");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testComposedSchemaDoesNotThrow() {
|
||||
OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_1/composed-schema.yaml");
|
||||
@@ -1204,4 +1266,5 @@ public class OpenAPINormalizerTest {
|
||||
return super.normalizeSchema(schema, visitedSchemas);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -368,11 +368,27 @@ public class CSharpModelTest {
|
||||
public void nullablePropertyWithNullableReferenceTypesTest() {
|
||||
final Schema model = new Schema()
|
||||
.description("a sample model")
|
||||
.addProperties("id", new IntegerSchema().format(SchemaTypeUtil.INTEGER64_FORMAT).nullable(true))
|
||||
.addProperties("id", new IntegerSchema().format(SchemaTypeUtil.INTEGER64_FORMAT)
|
||||
.nullable(true))
|
||||
.addProperties("urls", new ArraySchema()
|
||||
.items(new StringSchema()).nullable(true))
|
||||
.items(new StringSchema())
|
||||
.nullable(true))
|
||||
.addProperties("name", new StringSchema().nullable(true))
|
||||
.addProperties("subObject", new Schema().addProperties("name", new StringSchema()).nullable(true))
|
||||
.addProperties("subObject", new Schema().addProperties("name", new StringSchema())
|
||||
.nullable(true))
|
||||
.addProperties("deepNullableAliasArray", new ArraySchema()
|
||||
.items(new ArraySchema()
|
||||
.items(new StringSchema()
|
||||
.nullable(true))
|
||||
.nullable(true))
|
||||
.nullable(true))
|
||||
.addProperties("deepAliasArray", new ArraySchema()
|
||||
.items(new ArraySchema()
|
||||
.items(new StringSchema())))
|
||||
.addProperties("deepIntermediateNullableAliasArray", new ArraySchema()
|
||||
.items(new ArraySchema()
|
||||
.items(new StringSchema())
|
||||
.nullable(true)))
|
||||
.addRequiredItem("id");
|
||||
final DefaultCodegen codegen = new AspNetServerCodegen();
|
||||
codegen.processOpts();
|
||||
@@ -385,7 +401,7 @@ public class CSharpModelTest {
|
||||
Assert.assertEquals(cm.name, "sample");
|
||||
Assert.assertEquals(cm.classname, "Sample");
|
||||
Assert.assertEquals(cm.description, "a sample model");
|
||||
Assert.assertEquals(cm.vars.size(), 4);
|
||||
Assert.assertEquals(cm.vars.size(), 7);
|
||||
|
||||
final CodegenProperty property1 = cm.vars.get(0);
|
||||
Assert.assertEquals(property1.baseName, "id");
|
||||
@@ -398,7 +414,7 @@ public class CSharpModelTest {
|
||||
|
||||
final CodegenProperty property2 = cm.vars.get(1);
|
||||
Assert.assertEquals(property2.baseName, "urls");
|
||||
Assert.assertEquals(property2.dataType, "List?<string>");
|
||||
Assert.assertEquals(property2.dataType, "List<string>");
|
||||
Assert.assertEquals(property2.name, "Urls");
|
||||
Assert.assertNull(property2.defaultValue);
|
||||
Assert.assertEquals(property2.baseType, "List?");
|
||||
@@ -424,6 +440,33 @@ public class CSharpModelTest {
|
||||
Assert.assertEquals(property4.baseType, "Object?");
|
||||
Assert.assertFalse(property4.required);
|
||||
Assert.assertFalse(property4.isPrimitiveType);
|
||||
|
||||
final CodegenProperty property5 = cm.vars.get(4);
|
||||
Assert.assertEquals(property5.baseName, "deepNullableAliasArray");
|
||||
Assert.assertEquals(property5.dataType, "List<List<string?>>");
|
||||
Assert.assertEquals(property5.name, "DeepNullableAliasArray");
|
||||
Assert.assertNull(property5.defaultValue);
|
||||
Assert.assertEquals(property5.baseType, "List?");
|
||||
Assert.assertEquals(property5.containerType, "array");
|
||||
Assert.assertFalse(property5.required);
|
||||
Assert.assertFalse(property5.isPrimitiveType);
|
||||
Assert.assertTrue(property5.isContainer);
|
||||
|
||||
final CodegenProperty property6 = cm.vars.get(5);
|
||||
Assert.assertEquals(property6.baseName, "deepAliasArray");
|
||||
Assert.assertEquals(property6.dataType, "List<List<string>>");
|
||||
Assert.assertEquals(property6.name, "DeepAliasArray");
|
||||
Assert.assertEquals(property6.baseType, "List");
|
||||
Assert.assertEquals(property6.containerType, "array");
|
||||
Assert.assertTrue(property6.isContainer);
|
||||
|
||||
final CodegenProperty property7 = cm.vars.get(6);
|
||||
Assert.assertEquals(property7.baseName, "deepIntermediateNullableAliasArray");
|
||||
Assert.assertEquals(property7.dataType, "List<List<string>>");
|
||||
Assert.assertEquals(property7.name, "DeepIntermediateNullableAliasArray");
|
||||
Assert.assertEquals(property7.baseType, "List");
|
||||
Assert.assertEquals(property7.containerType, "array");
|
||||
Assert.assertTrue(property7.isContainer);
|
||||
}
|
||||
|
||||
@Test(description = "convert a model with list property")
|
||||
|
||||
@@ -50,7 +50,7 @@ public abstract class AbstractAnnotationsAssert<ACTUAL extends AbstractAnnotatio
|
||||
return myself();
|
||||
}
|
||||
|
||||
public ACTUAL containsWithNameAndDoesContainAttributes(final String name, final List<String> attributes) {
|
||||
public ACTUAL containsWithNameAndDoesNotContainAttributes(final String name, final List<String> attributes) {
|
||||
super
|
||||
.withFailMessage("Should have annotation with name: " + name + " and no attributes: " + attributes + ", but was: " + actual)
|
||||
.anyMatch(annotation -> annotation.getNameAsString().equals(name) && hasNotAttributes(annotation, attributes));
|
||||
|
||||
@@ -1171,7 +1171,7 @@ public class SpringCodegenTest {
|
||||
// Check that the @RequestMapping annotation is generated in the Api file
|
||||
JavaFileAssert.assertThat(files.get("PetApi.java"))
|
||||
.fileContains("@RequestMapping(\"${openapi.openAPIPetstore.base-path:/v2}\")",
|
||||
"public static final String PATH_ADD_PET = \"/pet\";",
|
||||
"String PATH_ADD_PET = \"/pet\";",
|
||||
"value = PetApi.PATH_ADD_PET");
|
||||
|
||||
// Check that the @RequestMapping annotation is not generated in the Controller file
|
||||
@@ -2272,8 +2272,12 @@ public class SpringCodegenTest {
|
||||
additionalProperties.put(RETURN_SUCCESS_CODE, "true");
|
||||
Map<String, File> files = generateFromContract("src/test/resources/bugs/issue_12524.json", SPRING_BOOT, additionalProperties);
|
||||
|
||||
JavaFileAssert.assertThat(files.get("API01ListOfStuff.java"))
|
||||
.hasImports("com.fasterxml.jackson.annotation.JsonTypeName");
|
||||
// class extending array is no longer generated as it's automatically fixed by inline resolver
|
||||
// by removing the properties for array type
|
||||
//JavaFileAssert.assertThat(files.get("API01ListOfStuff.java"))
|
||||
// .hasImports("com.fasterxml.jackson.annotation.JsonTypeName");
|
||||
File notExisting = files.get("API01ListOfStuff.java");
|
||||
assertThat(notExisting).isNull();
|
||||
} finally {
|
||||
GlobalSettings.reset();
|
||||
}
|
||||
@@ -3759,22 +3763,22 @@ public class SpringCodegenTest {
|
||||
.withType("JsonNullable<@Size(max = 1) String>")
|
||||
.toType()
|
||||
.assertProperty("intMinMaxNullable")
|
||||
.withType("JsonNullable<@Min(1) @Max(10) Integer>")
|
||||
.withType("JsonNullable<@Min(value = 1) @Max(value = 10) Integer>")
|
||||
.toType()
|
||||
.assertProperty("intMinNullable")
|
||||
.withType("JsonNullable<@Min(1) Integer>")
|
||||
.withType("JsonNullable<@Min(value = 1) Integer>")
|
||||
.toType()
|
||||
.assertProperty("intMaxNullable")
|
||||
.withType("JsonNullable<@Max(10) Integer>")
|
||||
.withType("JsonNullable<@Max(value = 10) Integer>")
|
||||
.toType()
|
||||
.assertProperty("numberMinMaxNullable")
|
||||
.withType("JsonNullable<@DecimalMin(\"1\") @DecimalMax(\"10\") BigDecimal>")
|
||||
.withType("JsonNullable<@DecimalMin(value = \"1\") @DecimalMax(value = \"10\") BigDecimal>")
|
||||
.toType()
|
||||
.assertProperty("numberMinNullable")
|
||||
.withType("JsonNullable<@DecimalMin(\"1\") BigDecimal>")
|
||||
.withType("JsonNullable<@DecimalMin(value = \"1\") BigDecimal>")
|
||||
.toType()
|
||||
.assertProperty("numberMaxNullable")
|
||||
.withType("JsonNullable<@DecimalMax(\"10\") BigDecimal>")
|
||||
.withType("JsonNullable<@DecimalMax(value = \"10\") BigDecimal>")
|
||||
.toType()
|
||||
.assertProperty("stringDefaultNullable")
|
||||
.withType("JsonNullable<@Size(max = 1) String>")
|
||||
@@ -3863,12 +3867,12 @@ public class SpringCodegenTest {
|
||||
assertJsonNullableMethod(javaFileAssert, String.class, "stringMinLengthNullable", "JsonNullable<@Size(min = 1) String>");
|
||||
assertJsonNullableMethod(javaFileAssert, String.class, "stringMaxLengthNullable", "JsonNullable<@Size(max = 1) String>");
|
||||
assertJsonNullableMethod(javaFileAssert, String.class, "stringEmailNullable", "JsonNullable<@jakarta.validation.constraints.Email String>");
|
||||
assertJsonNullableMethod(javaFileAssert, Integer.class, "intMinMaxNullable", "JsonNullable<@Min(1) @Max(10) Integer>");
|
||||
assertJsonNullableMethod(javaFileAssert, Integer.class, "intMinNullable", "JsonNullable<@Min(1) Integer>");
|
||||
assertJsonNullableMethod(javaFileAssert, Integer.class, "intMaxNullable", "JsonNullable<@Max(10) Integer>");
|
||||
assertJsonNullableMethod(javaFileAssert, BigDecimal.class, "numberMinMaxNullable", "JsonNullable<@DecimalMin(\"1\") @DecimalMax(\"10\") BigDecimal>");
|
||||
assertJsonNullableMethod(javaFileAssert, BigDecimal.class, "numberMinNullable", "JsonNullable<@DecimalMin(\"1\") BigDecimal>");
|
||||
assertJsonNullableMethod(javaFileAssert, BigDecimal.class, "numberMaxNullable", "JsonNullable<@DecimalMax(\"10\") BigDecimal>");
|
||||
assertJsonNullableMethod(javaFileAssert, Integer.class, "intMinMaxNullable", "JsonNullable<@Min(value = 1) @Max(value = 10) Integer>");
|
||||
assertJsonNullableMethod(javaFileAssert, Integer.class, "intMinNullable", "JsonNullable<@Min(value = 1) Integer>");
|
||||
assertJsonNullableMethod(javaFileAssert, Integer.class, "intMaxNullable", "JsonNullable<@Max(value = 10) Integer>");
|
||||
assertJsonNullableMethod(javaFileAssert, BigDecimal.class, "numberMinMaxNullable", "JsonNullable<@DecimalMin(value = \"1\") @DecimalMax(value = \"10\") BigDecimal>");
|
||||
assertJsonNullableMethod(javaFileAssert, BigDecimal.class, "numberMinNullable", "JsonNullable<@DecimalMin(value = \"1\") BigDecimal>");
|
||||
assertJsonNullableMethod(javaFileAssert, BigDecimal.class, "numberMaxNullable", "JsonNullable<@DecimalMax(value = \"10\") BigDecimal>");
|
||||
|
||||
}
|
||||
|
||||
@@ -3937,22 +3941,22 @@ public class SpringCodegenTest {
|
||||
.withType("Optional<@jakarta.validation.constraints.Email String>")
|
||||
.toType()
|
||||
.assertProperty("intMinMax")
|
||||
.withType("Optional<@Min(1) @Max(10) Integer>")
|
||||
.withType("Optional<@Min(value = 1) @Max(value = 10) Integer>")
|
||||
.toType()
|
||||
.assertProperty("intMin")
|
||||
.withType("Optional<@Min(1) Integer>")
|
||||
.withType("Optional<@Min(value = 1) Integer>")
|
||||
.toType()
|
||||
.assertProperty("intMax")
|
||||
.withType("Optional<@Max(10) Integer>")
|
||||
.withType("Optional<@Max(value = 10) Integer>")
|
||||
.toType()
|
||||
.assertProperty("numberMinMax")
|
||||
.withType("Optional<@DecimalMin(\"1\") @DecimalMax(\"10\") BigDecimal>")
|
||||
.withType("Optional<@DecimalMin(value = \"1\") @DecimalMax(value = \"10\") BigDecimal>")
|
||||
.toType()
|
||||
.assertProperty("numberMin")
|
||||
.withType("Optional<@DecimalMin(\"1\") BigDecimal>")
|
||||
.withType("Optional<@DecimalMin(value = \"1\") BigDecimal>")
|
||||
.toType()
|
||||
.assertProperty("numberMax")
|
||||
.withType("Optional<@DecimalMax(\"10\") BigDecimal>")
|
||||
.withType("Optional<@DecimalMax(value = \"10\") BigDecimal>")
|
||||
.toType()
|
||||
.assertProperty("stringDefault")
|
||||
.withType("Optional<@Size(max = 1) String>")
|
||||
@@ -3975,22 +3979,22 @@ public class SpringCodegenTest {
|
||||
.withType("JsonNullable<@Size(max = 1) String>")
|
||||
.toType()
|
||||
.assertProperty("intMinMaxNullable")
|
||||
.withType("JsonNullable<@Min(1) @Max(10) Integer>")
|
||||
.withType("JsonNullable<@Min(value = 1) @Max(value = 10) Integer>")
|
||||
.toType()
|
||||
.assertProperty("intMinNullable")
|
||||
.withType("JsonNullable<@Min(1) Integer>")
|
||||
.withType("JsonNullable<@Min(value = 1) Integer>")
|
||||
.toType()
|
||||
.assertProperty("intMaxNullable")
|
||||
.withType("JsonNullable<@Max(10) Integer>")
|
||||
.withType("JsonNullable<@Max(value = 10) Integer>")
|
||||
.toType()
|
||||
.assertProperty("numberMinMaxNullable")
|
||||
.withType("JsonNullable<@DecimalMin(\"1\") @DecimalMax(\"10\") BigDecimal>")
|
||||
.withType("JsonNullable<@DecimalMin(value = \"1\") @DecimalMax(value = \"10\") BigDecimal>")
|
||||
.toType()
|
||||
.assertProperty("numberMinNullable")
|
||||
.withType("JsonNullable<@DecimalMin(\"1\") BigDecimal>")
|
||||
.withType("JsonNullable<@DecimalMin(value = \"1\") BigDecimal>")
|
||||
.toType()
|
||||
.assertProperty("numberMaxNullable")
|
||||
.withType("JsonNullable<@DecimalMax(\"10\") BigDecimal>")
|
||||
.withType("JsonNullable<@DecimalMax(value = \"10\") BigDecimal>")
|
||||
.toType()
|
||||
.assertProperty("stringDefaultNullable")
|
||||
.withType("JsonNullable<@Size(max = 1) String>")
|
||||
@@ -4066,12 +4070,12 @@ public class SpringCodegenTest {
|
||||
assertOptionalMethod(javaFileAssert, String.class, "stringMinLength", "Optional<@Size(min = 1) String>");
|
||||
assertOptionalMethod(javaFileAssert, String.class, "stringMaxLength", "Optional<@Size(max = 1) String>");
|
||||
assertOptionalMethod(javaFileAssert, String.class, "stringEmail", "Optional<@jakarta.validation.constraints.Email String>");
|
||||
assertOptionalMethod(javaFileAssert, Integer.class, "intMinMax", "Optional<@Min(1) @Max(10) Integer>");
|
||||
assertOptionalMethod(javaFileAssert, Integer.class, "intMin", "Optional<@Min(1) Integer>");
|
||||
assertOptionalMethod(javaFileAssert, Integer.class, "intMax", "Optional<@Max(10) Integer>");
|
||||
assertOptionalMethod(javaFileAssert, BigDecimal.class, "numberMinMax", "Optional<@DecimalMin(\"1\") @DecimalMax(\"10\") BigDecimal>");
|
||||
assertOptionalMethod(javaFileAssert, BigDecimal.class, "numberMin", "Optional<@DecimalMin(\"1\") BigDecimal>");
|
||||
assertOptionalMethod(javaFileAssert, BigDecimal.class, "numberMax", "Optional<@DecimalMax(\"10\") BigDecimal>");
|
||||
assertOptionalMethod(javaFileAssert, Integer.class, "intMinMax", "Optional<@Min(value = 1) @Max(value = 10) Integer>");
|
||||
assertOptionalMethod(javaFileAssert, Integer.class, "intMin", "Optional<@Min(value = 1) Integer>");
|
||||
assertOptionalMethod(javaFileAssert, Integer.class, "intMax", "Optional<@Max(value = 10) Integer>");
|
||||
assertOptionalMethod(javaFileAssert, BigDecimal.class, "numberMinMax", "Optional<@DecimalMin(value = \"1\") @DecimalMax(value = \"10\") BigDecimal>");
|
||||
assertOptionalMethod(javaFileAssert, BigDecimal.class, "numberMin", "Optional<@DecimalMin(value = \"1\") BigDecimal>");
|
||||
assertOptionalMethod(javaFileAssert, BigDecimal.class, "numberMax", "Optional<@DecimalMax(value = \"10\") BigDecimal>");
|
||||
assertOptionalMethod(javaFileAssert, "Zebra", "zebra", "Optional<Zebra>");
|
||||
|
||||
assertJsonNullableMethod(javaFileAssert, String.class, "stringPatternNullable", "JsonNullable<@Pattern(regexp = \"[a-z]\") String>");
|
||||
@@ -4079,12 +4083,12 @@ public class SpringCodegenTest {
|
||||
assertJsonNullableMethod(javaFileAssert, String.class, "stringMinLengthNullable", "JsonNullable<@Size(min = 1) String>");
|
||||
assertJsonNullableMethod(javaFileAssert, String.class, "stringMaxLengthNullable", "JsonNullable<@Size(max = 1) String>");
|
||||
assertJsonNullableMethod(javaFileAssert, String.class, "stringEmailNullable", "JsonNullable<@jakarta.validation.constraints.Email String>");
|
||||
assertJsonNullableMethod(javaFileAssert, Integer.class, "intMinMaxNullable", "JsonNullable<@Min(1) @Max(10) Integer>");
|
||||
assertJsonNullableMethod(javaFileAssert, Integer.class, "intMinNullable", "JsonNullable<@Min(1) Integer>");
|
||||
assertJsonNullableMethod(javaFileAssert, Integer.class, "intMaxNullable", "JsonNullable<@Max(10) Integer>");
|
||||
assertJsonNullableMethod(javaFileAssert, BigDecimal.class, "numberMinMaxNullable", "JsonNullable<@DecimalMin(\"1\") @DecimalMax(\"10\") BigDecimal>");
|
||||
assertJsonNullableMethod(javaFileAssert, BigDecimal.class, "numberMinNullable", "JsonNullable<@DecimalMin(\"1\") BigDecimal>");
|
||||
assertJsonNullableMethod(javaFileAssert, BigDecimal.class, "numberMaxNullable", "JsonNullable<@DecimalMax(\"10\") BigDecimal>");
|
||||
assertJsonNullableMethod(javaFileAssert, Integer.class, "intMinMaxNullable", "JsonNullable<@Min(value = 1) @Max(value = 10) Integer>");
|
||||
assertJsonNullableMethod(javaFileAssert, Integer.class, "intMinNullable", "JsonNullable<@Min(value = 1) Integer>");
|
||||
assertJsonNullableMethod(javaFileAssert, Integer.class, "intMaxNullable", "JsonNullable<@Max(value = 10) Integer>");
|
||||
assertJsonNullableMethod(javaFileAssert, BigDecimal.class, "numberMinMaxNullable", "JsonNullable<@DecimalMin(value = \"1\") @DecimalMax(value = \"10\") BigDecimal>");
|
||||
assertJsonNullableMethod(javaFileAssert, BigDecimal.class, "numberMinNullable", "JsonNullable<@DecimalMin(value = \"1\") BigDecimal>");
|
||||
assertJsonNullableMethod(javaFileAssert, BigDecimal.class, "numberMaxNullable", "JsonNullable<@DecimalMax(value = \"10\") BigDecimal>");
|
||||
|
||||
}
|
||||
|
||||
@@ -4812,7 +4816,7 @@ public class SpringCodegenTest {
|
||||
// super(responseType, requestId, success, pageInfo);
|
||||
// }
|
||||
JavaFileAssert.assertThat(output.get("Object4.java"))
|
||||
.assertConstructor("Type1", "String", "String", "Boolean")
|
||||
.assertConstructor("String", "String", "Boolean", "Type1")
|
||||
.hasParameter("responseType").toConstructor()
|
||||
.hasParameter("requestId").toConstructor()
|
||||
.hasParameter("success").toConstructor()
|
||||
@@ -5758,7 +5762,319 @@ public class SpringCodegenTest {
|
||||
|
||||
.assertMethod("getNones")
|
||||
.assertMethodAnnotations()
|
||||
.containsWithNameAndDoesContainAttributes("RequestMapping", List.of("version"));
|
||||
.containsWithNameAndDoesNotContainAttributes("RequestMapping", List.of("version"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testXSizeMessage_length() throws IOException {
|
||||
final Map<String, File> files = generateFromContract("src/test/resources/3_0/error-message-for-size-max-min.yaml", SPRING_BOOT);
|
||||
JavaFileAssert.assertThat(files.get("TestApi.java"))
|
||||
.assertMethod("lengthTest")
|
||||
.assertParameter("word")
|
||||
.assertParameterAnnotations()
|
||||
.containsWithNameAndAttributes("Size", ImmutableMap.of(
|
||||
"max", "10",
|
||||
"message", "\"Must be max 10 characters\""
|
||||
))
|
||||
.toParameter()
|
||||
.toMethod()
|
||||
.assertParameter("token")
|
||||
.assertParameterAnnotations()
|
||||
.containsWithNameAndAttributes("Size", ImmutableMap.of(
|
||||
"min", "1",
|
||||
"message", "\"Must not be empty\""
|
||||
))
|
||||
.toParameter()
|
||||
.toMethod()
|
||||
.assertParameter("clientId")
|
||||
.assertParameterAnnotations()
|
||||
.containsWithNameAndAttributes("Size", ImmutableMap.of(
|
||||
"min", "3",
|
||||
"max", "5",
|
||||
"message", "\"Must be between 3 and 5 characters\""
|
||||
));
|
||||
JavaFileAssert.assertThat(files.get("LengthTest.java"))
|
||||
.assertMethod("getField1")
|
||||
.assertMethodAnnotations()
|
||||
.containsWithNameAndAttributes("Size", ImmutableMap.of(
|
||||
"max", "10",
|
||||
"message", "\"Must be max 10 characters\""
|
||||
))
|
||||
.toMethod()
|
||||
.toFileAssert()
|
||||
.assertMethod("getField2")
|
||||
.assertMethodAnnotations()
|
||||
.containsWithNameAndAttributes("Size", ImmutableMap.of(
|
||||
"min", "1",
|
||||
"message", "\"Must not be empty\""
|
||||
))
|
||||
.toMethod()
|
||||
.toFileAssert()
|
||||
.assertMethod("getField3")
|
||||
.assertMethodAnnotations()
|
||||
.containsWithNameAndAttributes("Size", ImmutableMap.of(
|
||||
"min", "3",
|
||||
"max", "5",
|
||||
"message", "\"Must be between 3 and 5 characters\""
|
||||
))
|
||||
.toMethod()
|
||||
.toFileAssert()
|
||||
.assertMethod("getField4")
|
||||
.assertMethodAnnotations()
|
||||
.containsWithNameAndDoesNotContainAttributes("Size", List.of("message"))
|
||||
.toMethod()
|
||||
.toFileAssert()
|
||||
.assertMethod("getField5")
|
||||
.assertMethodAnnotations()
|
||||
.containsWithNameAndDoesNotContainAttributes("Size", List.of("message"))
|
||||
.toMethod()
|
||||
.toFileAssert()
|
||||
.assertMethod("getField6")
|
||||
.assertMethodAnnotations()
|
||||
.containsWithNameAndDoesNotContainAttributes("Size", List.of("message"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testXSizeMessage_size() throws IOException {
|
||||
final Map<String, File> files = generateFromContract("src/test/resources/3_0/error-message-for-size-max-min.yaml", SPRING_BOOT);
|
||||
JavaFileAssert.assertThat(files.get("TestApi.java"))
|
||||
.assertMethod("sizeTest")
|
||||
.assertParameter("values")
|
||||
.assertParameterAnnotations()
|
||||
.containsWithNameAndAttributes("Size", ImmutableMap.of(
|
||||
"max", "10",
|
||||
"message", "\"Must be max 10 elements\""
|
||||
))
|
||||
.toParameter()
|
||||
.toMethod()
|
||||
.assertParameter("tokens")
|
||||
.assertParameterAnnotations()
|
||||
.containsWithNameAndAttributes("Size", ImmutableMap.of(
|
||||
"min", "1",
|
||||
"message", "\"Must not be empty\""
|
||||
))
|
||||
.toParameter()
|
||||
.toMethod()
|
||||
.assertParameter("clientIds")
|
||||
.assertParameterAnnotations()
|
||||
.containsWithNameAndAttributes("Size", ImmutableMap.of(
|
||||
"min", "3",
|
||||
"max", "5",
|
||||
"message", "\"Must be between 3 and 5 elements\""
|
||||
));
|
||||
JavaFileAssert.assertThat(files.get("SizeTest.java"))
|
||||
.assertMethod("getField1")
|
||||
.assertMethodAnnotations()
|
||||
.containsWithNameAndAttributes("Size", ImmutableMap.of(
|
||||
"max", "10",
|
||||
"message", "\"Must be max 10 elements\""
|
||||
))
|
||||
.toMethod()
|
||||
.toFileAssert()
|
||||
.assertMethod("getField2")
|
||||
.assertMethodAnnotations()
|
||||
.containsWithNameAndAttributes("Size", ImmutableMap.of(
|
||||
"min", "1",
|
||||
"message", "\"Must not be empty\""
|
||||
))
|
||||
.toMethod()
|
||||
.toFileAssert()
|
||||
.assertMethod("getField3")
|
||||
.assertMethodAnnotations()
|
||||
.containsWithNameAndAttributes("Size", ImmutableMap.of(
|
||||
"min", "3",
|
||||
"max", "5",
|
||||
"message", "\"Must be between 3 and 5 elements\""
|
||||
))
|
||||
.toMethod()
|
||||
.toFileAssert()
|
||||
.assertMethod("getField4")
|
||||
.assertMethodAnnotations()
|
||||
.containsWithNameAndDoesNotContainAttributes("Size", List.of("message"))
|
||||
.toMethod()
|
||||
.toFileAssert()
|
||||
.assertMethod("getField5")
|
||||
.assertMethodAnnotations()
|
||||
.containsWithNameAndDoesNotContainAttributes("Size", List.of("message"))
|
||||
.toMethod()
|
||||
.toFileAssert()
|
||||
.assertMethod("getField6")
|
||||
.assertMethodAnnotations()
|
||||
.containsWithNameAndDoesNotContainAttributes("Size", List.of("message"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testXMinimumMessageAndXMaximumMessage_decimal() throws IOException {
|
||||
final Map<String, File> files = generateFromContract("src/test/resources/3_0/error-message-for-size-max-min.yaml", SPRING_BOOT);
|
||||
JavaFileAssert.assertThat(files.get("TestApi.java"))
|
||||
.assertMethod("minmaxNumberTest")
|
||||
.assertParameter("number")
|
||||
.assertParameterAnnotations()
|
||||
.containsWithNameAndAttributes("DecimalMin", ImmutableMap.of(
|
||||
"value", "\"0.1\"",
|
||||
"message", "\"Must be positive\""
|
||||
))
|
||||
.containsWithNameAndAttributes("DecimalMax", ImmutableMap.of(
|
||||
"value", "\"99.9\"",
|
||||
"message", "\"Must be less than 100\""
|
||||
))
|
||||
.toParameter()
|
||||
.toMethod()
|
||||
.assertParameter("token")
|
||||
.assertParameterAnnotations()
|
||||
.containsWithNameAndAttributes("DecimalMin", ImmutableMap.of(
|
||||
"value", "\"0.1\"",
|
||||
"message", "\"Must be positive\""
|
||||
))
|
||||
.containsWithNameAndAttributes("DecimalMax", ImmutableMap.of(
|
||||
"value", "\"99.9\"",
|
||||
"message", "\"Must be less than 100\""
|
||||
))
|
||||
.toParameter()
|
||||
.toMethod()
|
||||
.assertParameter("clientNumber")
|
||||
.assertParameterAnnotations()
|
||||
.containsWithNameAndAttributes("DecimalMin", ImmutableMap.of(
|
||||
"value", "\"0.1\"",
|
||||
"message", "\"Must be positive\""
|
||||
))
|
||||
.containsWithNameAndAttributes("DecimalMax", ImmutableMap.of(
|
||||
"value", "\"99.9\"",
|
||||
"message", "\"Must be less than 100\""
|
||||
));
|
||||
JavaFileAssert.assertThat(files.get("NumberTest.java"))
|
||||
.assertMethod("getField1")
|
||||
.assertMethodAnnotations()
|
||||
.containsWithNameAndAttributes("DecimalMin", ImmutableMap.of(
|
||||
"value", "\"0.1\"",
|
||||
"message", "\"Must be positive\""
|
||||
))
|
||||
.containsWithNameAndAttributes("DecimalMax", ImmutableMap.of(
|
||||
"value", "\"99.9\"",
|
||||
"message", "\"Must be less than 100\""
|
||||
))
|
||||
.toMethod()
|
||||
.toFileAssert()
|
||||
.assertMethod("getField2")
|
||||
.assertMethodAnnotations()
|
||||
.containsWithNameAndDoesNotContainAttributes("DecimalMin", List.of("message"))
|
||||
.containsWithNameAndDoesNotContainAttributes("DecimalMax", List.of("message"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testXMinimumMessageAndXMaximumMessage_integer() throws IOException {
|
||||
final Map<String, File> files = generateFromContract("src/test/resources/3_0/error-message-for-size-max-min.yaml", SPRING_BOOT);
|
||||
JavaFileAssert.assertThat(files.get("TestApi.java"))
|
||||
.assertMethod("minmaxIntegerTest")
|
||||
.assertParameter("number")
|
||||
.assertParameterAnnotations()
|
||||
.containsWithNameAndAttributes("Min", ImmutableMap.of(
|
||||
"value", "1",
|
||||
"message", "\"Must be positive\""
|
||||
))
|
||||
.containsWithNameAndAttributes("Max", ImmutableMap.of(
|
||||
"value", "99",
|
||||
"message", "\"Must be less than 100\""
|
||||
))
|
||||
.toParameter()
|
||||
.toMethod()
|
||||
.assertParameter("token")
|
||||
.assertParameterAnnotations()
|
||||
.containsWithNameAndAttributes("Min", ImmutableMap.of(
|
||||
"value", "1",
|
||||
"message", "\"Must be positive\""
|
||||
))
|
||||
.containsWithNameAndAttributes("Max", ImmutableMap.of(
|
||||
"value", "99",
|
||||
"message", "\"Must be less than 100\""
|
||||
))
|
||||
.toParameter()
|
||||
.toMethod()
|
||||
.assertParameter("clientNumber")
|
||||
.assertParameterAnnotations()
|
||||
.containsWithNameAndAttributes("Min", ImmutableMap.of(
|
||||
"value", "1",
|
||||
"message", "\"Must be positive\""
|
||||
))
|
||||
.containsWithNameAndAttributes("Max", ImmutableMap.of(
|
||||
"value", "99",
|
||||
"message", "\"Must be less than 100\""
|
||||
));
|
||||
JavaFileAssert.assertThat(files.get("IntegerTest.java"))
|
||||
.assertMethod("getField1")
|
||||
.assertMethodAnnotations()
|
||||
.containsWithNameAndAttributes("Min", ImmutableMap.of(
|
||||
"value", "1",
|
||||
"message", "\"Must be positive\""
|
||||
))
|
||||
.containsWithNameAndAttributes("Max", ImmutableMap.of(
|
||||
"value", "99",
|
||||
"message", "\"Must be less than 100\""
|
||||
))
|
||||
.toMethod()
|
||||
.toFileAssert()
|
||||
.assertMethod("getField2")
|
||||
.assertMethodAnnotations()
|
||||
.containsWithNameAndDoesNotContainAttributes("Min", List.of("message"))
|
||||
.containsWithNameAndDoesNotContainAttributes("Max", List.of("message"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testXMinimumMessageAndXMaximumMessage_long() throws IOException {
|
||||
final Map<String, File> files = generateFromContract("src/test/resources/3_0/error-message-for-size-max-min.yaml", SPRING_BOOT);
|
||||
JavaFileAssert.assertThat(files.get("TestApi.java"))
|
||||
.assertMethod("minmaxLongTest")
|
||||
.assertParameter("number")
|
||||
.assertParameterAnnotations()
|
||||
.containsWithNameAndAttributes("Min", ImmutableMap.of(
|
||||
"value", "1L",
|
||||
"message", "\"Must be positive\""
|
||||
))
|
||||
.containsWithNameAndAttributes("Max", ImmutableMap.of(
|
||||
"value", "99L",
|
||||
"message", "\"Must be less than 100\""
|
||||
))
|
||||
.toParameter()
|
||||
.toMethod()
|
||||
.assertParameter("token")
|
||||
.assertParameterAnnotations()
|
||||
.containsWithNameAndAttributes("Min", ImmutableMap.of(
|
||||
"value", "1L",
|
||||
"message", "\"Must be positive\""
|
||||
))
|
||||
.containsWithNameAndAttributes("Max", ImmutableMap.of(
|
||||
"value", "99L",
|
||||
"message", "\"Must be less than 100\""
|
||||
))
|
||||
.toParameter()
|
||||
.toMethod()
|
||||
.assertParameter("clientNumber")
|
||||
.assertParameterAnnotations()
|
||||
.containsWithNameAndAttributes("Min", ImmutableMap.of(
|
||||
"value", "1L",
|
||||
"message", "\"Must be positive\""
|
||||
))
|
||||
.containsWithNameAndAttributes("Max", ImmutableMap.of(
|
||||
"value", "99L",
|
||||
"message", "\"Must be less than 100\""
|
||||
));
|
||||
JavaFileAssert.assertThat(files.get("LongTest.java"))
|
||||
.assertMethod("getField1")
|
||||
.assertMethodAnnotations()
|
||||
.containsWithNameAndAttributes("Min", ImmutableMap.of(
|
||||
"value", "1L",
|
||||
"message", "\"Must be positive\""
|
||||
))
|
||||
.containsWithNameAndAttributes("Max", ImmutableMap.of(
|
||||
"value", "99L",
|
||||
"message", "\"Must be less than 100\""
|
||||
))
|
||||
.toMethod()
|
||||
.toFileAssert()
|
||||
.assertMethod("getField2")
|
||||
.assertMethodAnnotations()
|
||||
.containsWithNameAndDoesNotContainAttributes("Min", List.of("message"))
|
||||
.containsWithNameAndDoesNotContainAttributes("Max", List.of("message"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
package org.openapitools.codegen.kotlin.assertions;
|
||||
|
||||
import org.assertj.core.api.AbstractAssert;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.assertj.core.util.CanIgnoreReturnValue;
|
||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@CanIgnoreReturnValue
|
||||
abstract class AbstractAnnotationAssert<SELF extends AbstractAnnotationAssert<SELF>> extends AbstractAssert<SELF, KtAnnotationEntry> {
|
||||
|
||||
AbstractAnnotationAssert(final KtAnnotationEntry annotationEntry, final Class<?> selfType) {
|
||||
super(annotationEntry, selfType);
|
||||
}
|
||||
|
||||
public SELF hasAttributes(final Map<String, String> expectedAttributes) {
|
||||
final Map<String, String> actualAttributes = actual.getValueArguments().stream()
|
||||
.collect(Collectors.toMap(
|
||||
a -> a.getArgumentName() != null ? a.getArgumentName().getAsName().asString() : null,
|
||||
a -> a.getArgumentExpression() != null ? a.getArgumentExpression().getText() : null
|
||||
));
|
||||
final boolean allAttributesFound = expectedAttributes.entrySet().stream()
|
||||
.allMatch(expected -> Objects.equals(actualAttributes.get(expected.getKey()), expected.getValue()));
|
||||
Assertions.assertThat(allAttributesFound)
|
||||
.withFailMessage("Expected annotation to have attributes %s, but has %s", expectedAttributes, actualAttributes)
|
||||
.isTrue();
|
||||
|
||||
return myself;
|
||||
}
|
||||
|
||||
public SELF hasNotAttributes(final List<String> notExpectedAttributes) {
|
||||
final List<String> actualAttributes = actual.getValueArguments().stream()
|
||||
.map(a -> a.getArgumentName() != null ? a.getArgumentName().getAsName().asString() : null)
|
||||
.collect(Collectors.toList());
|
||||
Assertions.assertThat(actualAttributes)
|
||||
.withFailMessage("Expected annotation to not have attributes %s, but has %s", notExpectedAttributes, actualAttributes)
|
||||
.noneMatch(notExpectedAttributes::contains);
|
||||
|
||||
return myself;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package org.openapitools.codegen.kotlin.assertions;
|
||||
|
||||
import org.assertj.core.api.AbstractAssert;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.assertj.core.util.CanIgnoreReturnValue;
|
||||
import org.jetbrains.kotlin.psi.KtClass;
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction;
|
||||
import org.jetbrains.kotlin.psi.KtParameter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@CanIgnoreReturnValue
|
||||
public class ClassAssert extends AbstractAssert<ClassAssert, KtClass> {
|
||||
private final KotlinFileAssert fileAssert;
|
||||
|
||||
ClassAssert(final KotlinFileAssert fileAssert, final KtClass actual) {
|
||||
super(actual, ClassAssert.class);
|
||||
this.fileAssert = fileAssert;
|
||||
}
|
||||
|
||||
public MethodAssert assertMethod(final String methodName) {
|
||||
Assertions.assertThat(actual.getBody())
|
||||
.withFailMessage("Expected class to have a body, but it was null")
|
||||
.isNotNull();
|
||||
final List<KtNamedFunction> methods = actual.getBody().getFunctions().stream()
|
||||
.filter(f -> Objects.equals(f.getName(), methodName))
|
||||
.collect(Collectors.toList());
|
||||
Assertions.assertThat(methods)
|
||||
.withFailMessage("Expected class to have a single method %s, but found %s", methodName, methods.size())
|
||||
.hasSize(1);
|
||||
|
||||
return new MethodAssert(this, methods.get(0));
|
||||
}
|
||||
|
||||
public PrimaryConstructorParameterAssert assertPrimaryConstructorParameter(final String propertyName) {
|
||||
final List<KtParameter> parameters = actual.getPrimaryConstructorParameters().stream()
|
||||
.filter(p -> Objects.equals(p.getName(), propertyName))
|
||||
.collect(Collectors.toList());
|
||||
Assertions.assertThat(parameters)
|
||||
.withFailMessage("Expected class to have a single property %s, but found %s", propertyName, parameters.size())
|
||||
.hasSize(1);
|
||||
|
||||
return new PrimaryConstructorParameterAssert(this, parameters.get(0));
|
||||
}
|
||||
|
||||
public KotlinFileAssert toFile() {
|
||||
return fileAssert;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package org.openapitools.codegen.kotlin.assertions;
|
||||
|
||||
import org.assertj.core.api.AbstractAssert;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.assertj.core.util.CanIgnoreReturnValue;
|
||||
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys;
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector;
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles;
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment;
|
||||
import org.jetbrains.kotlin.com.intellij.openapi.util.Disposer;
|
||||
import org.jetbrains.kotlin.com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.kotlin.com.intellij.openapi.vfs.local.CoreLocalFileSystem;
|
||||
import org.jetbrains.kotlin.com.intellij.psi.PsiManager;
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration;
|
||||
import org.jetbrains.kotlin.psi.KtClass;
|
||||
import org.jetbrains.kotlin.psi.KtFile;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@CanIgnoreReturnValue
|
||||
public class KotlinFileAssert extends AbstractAssert<KotlinFileAssert, KtFile> {
|
||||
|
||||
private KotlinFileAssert(final KtFile ktFile) {
|
||||
super(ktFile, KotlinFileAssert.class);
|
||||
}
|
||||
|
||||
public static KotlinFileAssert assertThat(final File file) {
|
||||
final CompilerConfiguration config = new CompilerConfiguration();
|
||||
config.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollector.Companion.getNONE());
|
||||
final KotlinCoreEnvironment env = KotlinCoreEnvironment.createForProduction(Disposer.newDisposable(), config, EnvironmentConfigFiles.JVM_CONFIG_FILES);
|
||||
final VirtualFile vFile = new CoreLocalFileSystem().findFileByIoFile(file);
|
||||
Assertions.assertThat(vFile)
|
||||
.withFailMessage("Expected file %s to exist but was not found", file.getAbsolutePath())
|
||||
.isNotNull();
|
||||
final KtFile ktFile = (KtFile) PsiManager.getInstance(env.getProject()).findFile(vFile);
|
||||
return new KotlinFileAssert(ktFile);
|
||||
}
|
||||
|
||||
public ClassAssert assertClass(final String className) {
|
||||
final List<KtClass> ktClasses = Arrays.stream(actual.findChildrenByClass(KtClass.class))
|
||||
.filter(clazz -> Objects.equals(clazz.getName(), className)).collect(Collectors.toList());
|
||||
Assertions.assertThat(ktClasses)
|
||||
.withFailMessage("Expected file to have single class %s, but found %s", className, ktClasses.size())
|
||||
.hasSize(1);
|
||||
|
||||
return new ClassAssert(this, ktClasses.get(0));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package org.openapitools.codegen.kotlin.assertions;
|
||||
|
||||
import org.assertj.core.api.AbstractAssert;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.assertj.core.util.CanIgnoreReturnValue;
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction;
|
||||
import org.jetbrains.kotlin.psi.KtParameter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@CanIgnoreReturnValue
|
||||
public class MethodAssert extends AbstractAssert<MethodAssert, KtNamedFunction> {
|
||||
private final ClassAssert classAssert;
|
||||
|
||||
MethodAssert(final ClassAssert classAssert, final KtNamedFunction method) {
|
||||
super(method, MethodAssert.class);
|
||||
this.classAssert = classAssert;
|
||||
}
|
||||
|
||||
public ParameterAssert assertParameter(final String parameterName) {
|
||||
final List<KtParameter> parameters = actual.getValueParameters().stream()
|
||||
.filter(p -> Objects.equals(p.getName(), parameterName))
|
||||
.collect(Collectors.toList());
|
||||
Assertions.assertThat(parameters)
|
||||
.withFailMessage("Expected class to have a single parameter %s, but found %s", parameterName, parameters.size())
|
||||
.hasSize(1);
|
||||
|
||||
return new ParameterAssert(this, parameters.get(0));
|
||||
}
|
||||
|
||||
public ClassAssert toClass() {
|
||||
return classAssert;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package org.openapitools.codegen.kotlin.assertions;
|
||||
|
||||
import org.assertj.core.util.CanIgnoreReturnValue;
|
||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry;
|
||||
|
||||
@CanIgnoreReturnValue
|
||||
public class ParameterAnnotationAssert extends AbstractAnnotationAssert<ParameterAnnotationAssert> {
|
||||
private final ParameterAssert parameterAssert;
|
||||
|
||||
ParameterAnnotationAssert(final ParameterAssert parameterAssert, final KtAnnotationEntry annotationEntry) {
|
||||
super(annotationEntry, ParameterAnnotationAssert.class);
|
||||
this.parameterAssert = parameterAssert;
|
||||
}
|
||||
|
||||
public ParameterAssert toParameter() {
|
||||
return parameterAssert;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package org.openapitools.codegen.kotlin.assertions;
|
||||
|
||||
import org.assertj.core.api.AbstractAssert;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.assertj.core.util.CanIgnoreReturnValue;
|
||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry;
|
||||
import org.jetbrains.kotlin.psi.KtParameter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@CanIgnoreReturnValue
|
||||
public class ParameterAssert extends AbstractAssert<ParameterAssert, KtParameter> {
|
||||
private final MethodAssert methodAssert;
|
||||
|
||||
ParameterAssert(final MethodAssert methodAssert, final KtParameter parameter) {
|
||||
super(parameter, ParameterAssert.class);
|
||||
this.methodAssert = methodAssert;
|
||||
}
|
||||
|
||||
public ParameterAnnotationAssert assertParameterAnnotation(final String annotationName) {
|
||||
final List<KtAnnotationEntry> annotations = actual.getAnnotationEntries().stream()
|
||||
.filter(a -> Objects.equals(a.getShortName() != null ? a.getShortName().asString() : null, annotationName))
|
||||
.collect(Collectors.toList());
|
||||
Assertions.assertThat(annotations)
|
||||
.withFailMessage("Expected parameter to have a single annotation %s, but found %s", annotationName, annotations.size())
|
||||
.hasSize(1);
|
||||
|
||||
return new ParameterAnnotationAssert(this, annotations.get(0));
|
||||
}
|
||||
|
||||
public MethodAssert toMethod() {
|
||||
return methodAssert;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package org.openapitools.codegen.kotlin.assertions;
|
||||
|
||||
import org.assertj.core.util.CanIgnoreReturnValue;
|
||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry;
|
||||
|
||||
@CanIgnoreReturnValue
|
||||
public class PrimaryConstructorParameterAnnotationAssert extends AbstractAnnotationAssert<PrimaryConstructorParameterAnnotationAssert> {
|
||||
private final PrimaryConstructorParameterAssert parameterAssert;
|
||||
|
||||
PrimaryConstructorParameterAnnotationAssert(final PrimaryConstructorParameterAssert parameterAssert, final KtAnnotationEntry annotationEntry) {
|
||||
super(annotationEntry, PrimaryConstructorParameterAnnotationAssert.class);
|
||||
this.parameterAssert = parameterAssert;
|
||||
}
|
||||
|
||||
public PrimaryConstructorParameterAssert toPrimaryConstructorParameter() {
|
||||
return parameterAssert;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package org.openapitools.codegen.kotlin.assertions;
|
||||
|
||||
import org.assertj.core.api.AbstractAssert;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.assertj.core.util.CanIgnoreReturnValue;
|
||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry;
|
||||
import org.jetbrains.kotlin.psi.KtParameter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@CanIgnoreReturnValue
|
||||
public class PrimaryConstructorParameterAssert extends AbstractAssert<PrimaryConstructorParameterAssert, KtParameter> {
|
||||
private final ClassAssert classAssert;
|
||||
|
||||
PrimaryConstructorParameterAssert(final ClassAssert classAssert, final KtParameter parameter) {
|
||||
super(parameter, PrimaryConstructorParameterAssert.class);
|
||||
this.classAssert = classAssert;
|
||||
}
|
||||
|
||||
public PrimaryConstructorParameterAnnotationAssert assertParameterAnnotation(final String annotationName, final String useSiteTarget) {
|
||||
final List<KtAnnotationEntry> annotations = actual.getAnnotationEntries().stream()
|
||||
.filter(a ->
|
||||
Objects.equals(a.getShortName() != null ? a.getShortName().asString() : null, annotationName)
|
||||
&& Objects.equals(a.getUseSiteTarget() != null ? a.getUseSiteTarget().getText() : null, useSiteTarget))
|
||||
.collect(Collectors.toList());
|
||||
Assertions.assertThat(annotations)
|
||||
.withFailMessage("Expected property to have a single annotation %s, but found %s", annotationName, annotations.size())
|
||||
.hasSize(1);
|
||||
|
||||
return new PrimaryConstructorParameterAnnotationAssert(this, annotations.get(0));
|
||||
}
|
||||
|
||||
public ClassAssert toClass() {
|
||||
return classAssert;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.openapitools.codegen.kotlin.spring;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import io.swagger.parser.OpenAPIParser;
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
import io.swagger.v3.oas.models.info.Info;
|
||||
@@ -17,6 +18,7 @@ import org.openapitools.codegen.DefaultGenerator;
|
||||
import org.openapitools.codegen.TestUtils;
|
||||
import org.openapitools.codegen.config.CodegenConfigurator;
|
||||
import org.openapitools.codegen.kotlin.KotlinTestUtils;
|
||||
import org.openapitools.codegen.kotlin.assertions.KotlinFileAssert;
|
||||
import org.openapitools.codegen.languages.KotlinSpringServerCodegen;
|
||||
import org.openapitools.codegen.languages.features.CXFServerFeatures;
|
||||
import org.openapitools.codegen.languages.features.DocumentationProviderFeatures;
|
||||
@@ -370,6 +372,44 @@ public class KotlinSpringServerCodegenTest {
|
||||
"ApiUtil");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testNullableMultipartFile() throws IOException {
|
||||
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
|
||||
output.deleteOnExit();
|
||||
String outputPath = output.getAbsolutePath().replace('\\', '/');
|
||||
|
||||
OpenAPI openAPI = new OpenAPIParser()
|
||||
.readLocation("src/test/resources/3_0/kotlin/feat-multipartfile_nullable.yaml", null, new ParseOptions()).getOpenAPI();
|
||||
|
||||
KotlinSpringServerCodegen codegen = new KotlinSpringServerCodegen();
|
||||
codegen.setOutputDir(output.getAbsolutePath());
|
||||
codegen.additionalProperties().put(CXFServerFeatures.LOAD_TEST_DATA_FROM_FILE, "true");
|
||||
|
||||
ClientOptInput input = new ClientOptInput();
|
||||
input.openAPI(openAPI);
|
||||
input.config(codegen);
|
||||
|
||||
DefaultGenerator generator = new DefaultGenerator();
|
||||
|
||||
generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "false");
|
||||
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false");
|
||||
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false");
|
||||
generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "true");
|
||||
generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false");
|
||||
|
||||
generator.opts(input).generate();
|
||||
|
||||
assertFileContains(Paths.get(outputPath + "/src/main/kotlin/org/openapitools/api/NullableMultipartfileApiController.kt"),
|
||||
"file: org.springframework.web.multipart.MultipartFile?)");
|
||||
assertFileContains(Paths.get(outputPath + "/src/main/kotlin/org/openapitools/api/NullableMultipartfileArrayApiController.kt"),
|
||||
"files: Array<org.springframework.web.multipart.MultipartFile>?)");
|
||||
assertFileContains(Paths.get(outputPath + "/src/main/kotlin/org/openapitools/api/NonNullableMultipartfileApiController.kt"),
|
||||
"file: org.springframework.web.multipart.MultipartFile)");
|
||||
assertFileContains(Paths.get(outputPath + "/src/main/kotlin/org/openapitools/api/NonNullableMultipartfileArrayApiController.kt"),
|
||||
"files: Array<org.springframework.web.multipart.MultipartFile>)");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void arrayItemsCanBeNullable() throws IOException {
|
||||
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
|
||||
@@ -752,7 +792,7 @@ public class KotlinSpringServerCodegenTest {
|
||||
|
||||
assertFileContains(
|
||||
Paths.get(files.get("AddApi.kt").getAbsolutePath()),
|
||||
"@Min(2)"
|
||||
"@Min(value=2)"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1377,6 +1417,358 @@ public class KotlinSpringServerCodegenTest {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testXSizeMessage_length() throws IOException {
|
||||
final Map<String, File> files = generateFromContract("src/test/resources/3_0/error-message-for-size-max-min.yaml");
|
||||
KotlinFileAssert.assertThat(files.get("TestApiController.kt"))
|
||||
.assertClass("TestApiController")
|
||||
.assertMethod("lengthTest")
|
||||
.assertParameter("word")
|
||||
.assertParameterAnnotation("Size")
|
||||
.hasAttributes(ImmutableMap.of(
|
||||
"max", "10",
|
||||
"message", "\"Must be max 10 characters\""
|
||||
))
|
||||
.toParameter()
|
||||
.toMethod()
|
||||
.assertParameter("token")
|
||||
.assertParameterAnnotation("Size")
|
||||
.hasAttributes(ImmutableMap.of(
|
||||
"min", "1",
|
||||
"message", "\"Must not be empty\""
|
||||
))
|
||||
.toParameter()
|
||||
.toMethod()
|
||||
.assertParameter("clientId")
|
||||
.assertParameterAnnotation("Size")
|
||||
.hasAttributes(ImmutableMap.of(
|
||||
"min", "3",
|
||||
"max", "5",
|
||||
"message", "\"Must be between 3 and 5 characters\""
|
||||
));
|
||||
KotlinFileAssert.assertThat(files.get("LengthTest.kt"))
|
||||
.assertClass("LengthTest")
|
||||
.assertPrimaryConstructorParameter("field1")
|
||||
.assertParameterAnnotation("Size", "get")
|
||||
.hasAttributes(ImmutableMap.of(
|
||||
"max", "10",
|
||||
"message", "\"Must be max 10 characters\""
|
||||
))
|
||||
.toPrimaryConstructorParameter()
|
||||
.toClass()
|
||||
.assertPrimaryConstructorParameter("field2")
|
||||
.assertParameterAnnotation("Size", "get")
|
||||
.hasAttributes(ImmutableMap.of(
|
||||
"min", "1",
|
||||
"message", "\"Must not be empty\""
|
||||
))
|
||||
.toPrimaryConstructorParameter()
|
||||
.toClass()
|
||||
.assertPrimaryConstructorParameter("field3")
|
||||
.assertParameterAnnotation("Size", "get")
|
||||
.hasAttributes(ImmutableMap.of(
|
||||
"min", "3",
|
||||
"max", "5",
|
||||
"message", "\"Must be between 3 and 5 characters\""
|
||||
))
|
||||
.toPrimaryConstructorParameter()
|
||||
.toClass()
|
||||
.assertPrimaryConstructorParameter("field4")
|
||||
.assertParameterAnnotation("Size", "get")
|
||||
.hasNotAttributes(List.of("message"))
|
||||
.toPrimaryConstructorParameter()
|
||||
.toClass()
|
||||
.assertPrimaryConstructorParameter("field5")
|
||||
.assertParameterAnnotation("Size", "get")
|
||||
.hasNotAttributes(List.of("message"))
|
||||
.toPrimaryConstructorParameter()
|
||||
.toClass()
|
||||
.assertPrimaryConstructorParameter("field6")
|
||||
.assertParameterAnnotation("Size", "get")
|
||||
.hasNotAttributes(List.of("message"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testXSizeMessage_size() throws IOException {
|
||||
final Map<String, File> files = generateFromContract("src/test/resources/3_0/error-message-for-size-max-min.yaml");
|
||||
KotlinFileAssert.assertThat(files.get("TestApiController.kt"))
|
||||
.assertClass("TestApiController")
|
||||
.assertMethod("sizeTest")
|
||||
.assertParameter("values")
|
||||
.assertParameterAnnotation("Size")
|
||||
.hasAttributes(ImmutableMap.of(
|
||||
"max", "10",
|
||||
"message", "\"Must be max 10 elements\""
|
||||
))
|
||||
.toParameter()
|
||||
.toMethod()
|
||||
.assertParameter("tokens")
|
||||
.assertParameterAnnotation("Size")
|
||||
.hasAttributes(ImmutableMap.of(
|
||||
"min", "1",
|
||||
"message", "\"Must not be empty\""
|
||||
))
|
||||
.toParameter()
|
||||
.toMethod()
|
||||
.assertParameter("clientIds")
|
||||
.assertParameterAnnotation("Size")
|
||||
.hasAttributes(ImmutableMap.of(
|
||||
"min", "3",
|
||||
"max", "5",
|
||||
"message", "\"Must be between 3 and 5 elements\""
|
||||
));
|
||||
KotlinFileAssert.assertThat(files.get("SizeTest.kt"))
|
||||
.assertClass("SizeTest")
|
||||
.assertPrimaryConstructorParameter("field1")
|
||||
.assertParameterAnnotation("Size", "get")
|
||||
.hasAttributes(ImmutableMap.of(
|
||||
"max", "10",
|
||||
"message", "\"Must be max 10 elements\""
|
||||
))
|
||||
.toPrimaryConstructorParameter()
|
||||
.toClass()
|
||||
.assertPrimaryConstructorParameter("field2")
|
||||
.assertParameterAnnotation("Size", "get")
|
||||
.hasAttributes(ImmutableMap.of(
|
||||
"min", "1",
|
||||
"message", "\"Must not be empty\""
|
||||
))
|
||||
.toPrimaryConstructorParameter()
|
||||
.toClass()
|
||||
.assertPrimaryConstructorParameter("field3")
|
||||
.assertParameterAnnotation("Size", "get")
|
||||
.hasAttributes(ImmutableMap.of(
|
||||
"min", "3",
|
||||
"max", "5",
|
||||
"message", "\"Must be between 3 and 5 elements\""
|
||||
))
|
||||
.toPrimaryConstructorParameter()
|
||||
.toClass()
|
||||
.assertPrimaryConstructorParameter("field4")
|
||||
.assertParameterAnnotation("Size", "get")
|
||||
.hasNotAttributes(List.of("message"))
|
||||
.toPrimaryConstructorParameter()
|
||||
.toClass()
|
||||
.assertPrimaryConstructorParameter("field5")
|
||||
.assertParameterAnnotation("Size", "get")
|
||||
.hasNotAttributes(List.of("message"))
|
||||
.toPrimaryConstructorParameter()
|
||||
.toClass()
|
||||
.assertPrimaryConstructorParameter("field6")
|
||||
.assertParameterAnnotation("Size", "get")
|
||||
.hasNotAttributes(List.of("message"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testXMinimumMessageAndXMaximumMessage_decimal() throws IOException {
|
||||
final Map<String, File> files = generateFromContract("src/test/resources/3_0/error-message-for-size-max-min.yaml");
|
||||
KotlinFileAssert.assertThat(files.get("TestApiController.kt"))
|
||||
.assertClass("TestApiController")
|
||||
.assertMethod("minmaxNumberTest")
|
||||
.assertParameter("number")
|
||||
.assertParameterAnnotation("DecimalMin")
|
||||
.hasAttributes(ImmutableMap.of(
|
||||
"value", "\"0.1\"",
|
||||
"message", "\"Must be positive\""
|
||||
))
|
||||
.toParameter()
|
||||
.assertParameterAnnotation("DecimalMax")
|
||||
.hasAttributes(ImmutableMap.of(
|
||||
"value", "\"99.9\"",
|
||||
"message", "\"Must be less than 100\""
|
||||
))
|
||||
.toParameter()
|
||||
.toMethod()
|
||||
.assertParameter("token")
|
||||
.assertParameterAnnotation("DecimalMin")
|
||||
.hasAttributes(ImmutableMap.of(
|
||||
"value", "\"0.1\"",
|
||||
"message", "\"Must be positive\""
|
||||
))
|
||||
.toParameter()
|
||||
.assertParameterAnnotation("DecimalMax")
|
||||
.hasAttributes(ImmutableMap.of(
|
||||
"value", "\"99.9\"",
|
||||
"message", "\"Must be less than 100\""
|
||||
))
|
||||
.toParameter()
|
||||
.toMethod()
|
||||
.assertParameter("clientNumber")
|
||||
.assertParameterAnnotation("DecimalMin")
|
||||
.hasAttributes(ImmutableMap.of(
|
||||
"value", "\"0.1\"",
|
||||
"message", "\"Must be positive\""
|
||||
))
|
||||
.toParameter()
|
||||
.assertParameterAnnotation("DecimalMax")
|
||||
.hasAttributes(ImmutableMap.of(
|
||||
"value", "\"99.9\"",
|
||||
"message", "\"Must be less than 100\""
|
||||
));
|
||||
KotlinFileAssert.assertThat(files.get("NumberTest.kt"))
|
||||
.assertClass("NumberTest")
|
||||
.assertPrimaryConstructorParameter("field1")
|
||||
.assertParameterAnnotation("DecimalMin", "get")
|
||||
.hasAttributes(ImmutableMap.of(
|
||||
"value", "\"0.1\"",
|
||||
"message", "\"Must be positive\""
|
||||
))
|
||||
.toPrimaryConstructorParameter()
|
||||
.assertParameterAnnotation("DecimalMax", "get")
|
||||
.hasAttributes(ImmutableMap.of(
|
||||
"value", "\"99.9\"",
|
||||
"message", "\"Must be less than 100\""
|
||||
))
|
||||
.toPrimaryConstructorParameter()
|
||||
.toClass()
|
||||
.assertPrimaryConstructorParameter("field2")
|
||||
.assertParameterAnnotation("DecimalMin", "get")
|
||||
.hasNotAttributes(List.of("message"))
|
||||
.toPrimaryConstructorParameter()
|
||||
.assertParameterAnnotation("DecimalMax", "get")
|
||||
.hasNotAttributes(List.of("message"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testXMinimumMessageAndXMaximumMessage_integer() throws IOException {
|
||||
final Map<String, File> files = generateFromContract("src/test/resources/3_0/error-message-for-size-max-min.yaml");
|
||||
KotlinFileAssert.assertThat(files.get("TestApiController.kt"))
|
||||
.assertClass("TestApiController")
|
||||
.assertMethod("minmaxIntegerTest")
|
||||
.assertParameter("number")
|
||||
.assertParameterAnnotation("Min")
|
||||
.hasAttributes(ImmutableMap.of(
|
||||
"value", "1",
|
||||
"message", "\"Must be positive\""
|
||||
))
|
||||
.toParameter()
|
||||
.assertParameterAnnotation("Max")
|
||||
.hasAttributes(ImmutableMap.of(
|
||||
"value", "99",
|
||||
"message", "\"Must be less than 100\""
|
||||
))
|
||||
.toParameter()
|
||||
.toMethod()
|
||||
.assertParameter("token")
|
||||
.assertParameterAnnotation("Min")
|
||||
.hasAttributes(ImmutableMap.of(
|
||||
"value", "1",
|
||||
"message", "\"Must be positive\""
|
||||
))
|
||||
.toParameter()
|
||||
.assertParameterAnnotation("Max")
|
||||
.hasAttributes(ImmutableMap.of(
|
||||
"value", "99",
|
||||
"message", "\"Must be less than 100\""
|
||||
))
|
||||
.toParameter()
|
||||
.toMethod()
|
||||
.assertParameter("clientNumber")
|
||||
.assertParameterAnnotation("Min")
|
||||
.hasAttributes(ImmutableMap.of(
|
||||
"value", "1",
|
||||
"message", "\"Must be positive\""
|
||||
))
|
||||
.toParameter()
|
||||
.assertParameterAnnotation("Max")
|
||||
.hasAttributes(ImmutableMap.of(
|
||||
"value", "99",
|
||||
"message", "\"Must be less than 100\""
|
||||
));
|
||||
KotlinFileAssert.assertThat(files.get("IntegerTest.kt"))
|
||||
.assertClass("IntegerTest")
|
||||
.assertPrimaryConstructorParameter("field1")
|
||||
.assertParameterAnnotation("Min", "get")
|
||||
.hasAttributes(ImmutableMap.of(
|
||||
"value", "1",
|
||||
"message", "\"Must be positive\""
|
||||
))
|
||||
.toPrimaryConstructorParameter()
|
||||
.assertParameterAnnotation("Max", "get")
|
||||
.hasAttributes(ImmutableMap.of(
|
||||
"value", "99",
|
||||
"message", "\"Must be less than 100\""
|
||||
))
|
||||
.toPrimaryConstructorParameter()
|
||||
.toClass()
|
||||
.assertPrimaryConstructorParameter("field2")
|
||||
.assertParameterAnnotation("Min", "get")
|
||||
.hasNotAttributes(List.of("message"))
|
||||
.toPrimaryConstructorParameter()
|
||||
.assertParameterAnnotation("Max", "get")
|
||||
.hasNotAttributes(List.of("message"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testXMinimumMessageAndXMaximumMessage_long() throws IOException {
|
||||
final Map<String, File> files = generateFromContract("src/test/resources/3_0/error-message-for-size-max-min.yaml");
|
||||
KotlinFileAssert.assertThat(files.get("TestApiController.kt"))
|
||||
.assertClass("TestApiController")
|
||||
.assertMethod("minmaxLongTest")
|
||||
.assertParameter("number")
|
||||
.assertParameterAnnotation("Min")
|
||||
.hasAttributes(ImmutableMap.of(
|
||||
"value", "1L",
|
||||
"message", "\"Must be positive\""
|
||||
))
|
||||
.toParameter()
|
||||
.assertParameterAnnotation("Max")
|
||||
.hasAttributes(ImmutableMap.of(
|
||||
"value", "99L",
|
||||
"message", "\"Must be less than 100\""
|
||||
))
|
||||
.toParameter()
|
||||
.toMethod()
|
||||
.assertParameter("token")
|
||||
.assertParameterAnnotation("Min")
|
||||
.hasAttributes(ImmutableMap.of(
|
||||
"value", "1L",
|
||||
"message", "\"Must be positive\""
|
||||
))
|
||||
.toParameter()
|
||||
.assertParameterAnnotation("Max")
|
||||
.hasAttributes(ImmutableMap.of(
|
||||
"value", "99L",
|
||||
"message", "\"Must be less than 100\""
|
||||
))
|
||||
.toParameter()
|
||||
.toMethod()
|
||||
.assertParameter("clientNumber")
|
||||
.assertParameterAnnotation("Min")
|
||||
.hasAttributes(ImmutableMap.of(
|
||||
"value", "1L",
|
||||
"message", "\"Must be positive\""
|
||||
))
|
||||
.toParameter()
|
||||
.assertParameterAnnotation("Max")
|
||||
.hasAttributes(ImmutableMap.of(
|
||||
"value", "99L",
|
||||
"message", "\"Must be less than 100\""
|
||||
));
|
||||
KotlinFileAssert.assertThat(files.get("LongTest.kt"))
|
||||
.assertClass("LongTest")
|
||||
.assertPrimaryConstructorParameter("field1")
|
||||
.assertParameterAnnotation("Min", "get")
|
||||
.hasAttributes(ImmutableMap.of(
|
||||
"value", "1L",
|
||||
"message", "\"Must be positive\""
|
||||
))
|
||||
.toPrimaryConstructorParameter()
|
||||
.assertParameterAnnotation("Max", "get")
|
||||
.hasAttributes(ImmutableMap.of(
|
||||
"value", "99L",
|
||||
"message", "\"Must be less than 100\""
|
||||
))
|
||||
.toPrimaryConstructorParameter()
|
||||
.toClass()
|
||||
.assertPrimaryConstructorParameter("field2")
|
||||
.assertParameterAnnotation("Min", "get")
|
||||
.hasNotAttributes(List.of("message"))
|
||||
.toPrimaryConstructorParameter()
|
||||
.assertParameterAnnotation("Max", "get")
|
||||
.hasNotAttributes(List.of("message"));
|
||||
}
|
||||
|
||||
private Map<String, File> generateFromContract(String url) throws IOException {
|
||||
return generateFromContract(url, new HashMap<>(), new HashMap<>());
|
||||
}
|
||||
|
||||
@@ -2935,6 +2935,16 @@ components:
|
||||
description: list of named parameters for current message
|
||||
additionalProperties:
|
||||
type: string
|
||||
ListAlias:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
DeepListAlias:
|
||||
type: array
|
||||
items:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
TestResult:
|
||||
type: object
|
||||
allOf:
|
||||
|
||||
@@ -2079,22 +2079,29 @@ components:
|
||||
TestEnum:
|
||||
type: string
|
||||
enum:
|
||||
- ""
|
||||
- "1"
|
||||
- "2"
|
||||
- ''
|
||||
- 'value_one'
|
||||
- 'value_two'
|
||||
title: TestEnum
|
||||
TestItem:
|
||||
ObjectWithEnum:
|
||||
type: object
|
||||
required:
|
||||
- test
|
||||
properties:
|
||||
test:
|
||||
type: integer
|
||||
title: test
|
||||
testEmum:
|
||||
$ref: '#/components/schemas/TestEnum'
|
||||
default: ""
|
||||
title: TestItem
|
||||
attribute:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/TestEnum'
|
||||
default: ''
|
||||
title: ObjectWithEnum
|
||||
ObjectWithInlineEnumDefaultValue:
|
||||
type: object
|
||||
properties:
|
||||
attribute:
|
||||
description: 'Object one attribute enum with default value'
|
||||
type: 'string'
|
||||
enum: [
|
||||
'value_one',
|
||||
'value_two'
|
||||
]
|
||||
default: 'value_one'
|
||||
ObjectWithInlineEnum:
|
||||
type: object
|
||||
properties:
|
||||
|
||||
@@ -7,6 +7,18 @@ info:
|
||||
servers:
|
||||
- url: http://api.example.xyz/v1
|
||||
paths:
|
||||
/v1/person:
|
||||
get:
|
||||
operationId: list
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
/v2/person:
|
||||
get:
|
||||
operationId: list
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
/person/display/{personId}:
|
||||
get:
|
||||
tags:
|
||||
@@ -47,6 +59,7 @@ paths:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Person"
|
||||
put:
|
||||
x-role: admin
|
||||
tags:
|
||||
- person
|
||||
parameters:
|
||||
@@ -83,4 +96,4 @@ components:
|
||||
type: object
|
||||
properties:
|
||||
test:
|
||||
type: string
|
||||
type: string
|
||||
|
||||
@@ -0,0 +1,310 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: sample spec
|
||||
version: 1.0.0
|
||||
paths:
|
||||
/test/length/{word}:
|
||||
post:
|
||||
operationId: lengthTest
|
||||
parameters:
|
||||
- in: path
|
||||
name: word
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
maxLength: 10
|
||||
x-size-message: "Must be max 10 characters"
|
||||
- in: query
|
||||
name: token
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
minLength: 1
|
||||
x-size-message: "Must not be empty"
|
||||
- in: header
|
||||
name: clientId
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
minLength: 3
|
||||
maxLength: 5
|
||||
x-size-message: "Must be between 3 and 5 characters"
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/LengthTest'
|
||||
responses:
|
||||
201:
|
||||
description: success
|
||||
/test/size/{values}:
|
||||
post:
|
||||
operationId: sizeTest
|
||||
parameters:
|
||||
- in: path
|
||||
name: values
|
||||
required: true
|
||||
schema:
|
||||
type: array
|
||||
maxItems: 10
|
||||
x-size-message: "Must be max 10 elements"
|
||||
items:
|
||||
type: string
|
||||
- in: query
|
||||
name: tokens
|
||||
required: true
|
||||
schema:
|
||||
type: array
|
||||
minItems: 1
|
||||
x-size-message: "Must not be empty"
|
||||
items:
|
||||
type: string
|
||||
- in: header
|
||||
name: clientIds
|
||||
required: true
|
||||
schema:
|
||||
type: array
|
||||
minItems: 3
|
||||
maxItems: 5
|
||||
x-size-message: "Must be between 3 and 5 elements"
|
||||
items:
|
||||
type: string
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SizeTest'
|
||||
responses:
|
||||
201:
|
||||
description: success
|
||||
/test/number/minmax/{number}:
|
||||
post:
|
||||
operationId: minmaxNumberTest
|
||||
parameters:
|
||||
- in: path
|
||||
name: number
|
||||
required: true
|
||||
schema:
|
||||
type: number
|
||||
minimum: 0.1
|
||||
maximum: 99.9
|
||||
x-minimum-message: "Must be positive"
|
||||
x-maximum-message: "Must be less than 100"
|
||||
- in: query
|
||||
name: token
|
||||
required: true
|
||||
schema:
|
||||
type: number
|
||||
minimum: 0.1
|
||||
maximum: 99.9
|
||||
x-minimum-message: "Must be positive"
|
||||
x-maximum-message: "Must be less than 100"
|
||||
- in: header
|
||||
name: clientNumber
|
||||
required: true
|
||||
schema:
|
||||
type: number
|
||||
minimum: 0.1
|
||||
maximum: 99.9
|
||||
x-minimum-message: "Must be positive"
|
||||
x-maximum-message: "Must be less than 100"
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/NumberTest'
|
||||
responses:
|
||||
201:
|
||||
description: success
|
||||
/test/integer/minmax/{number}:
|
||||
post:
|
||||
operationId: minmaxIntegerTest
|
||||
parameters:
|
||||
- in: path
|
||||
name: number
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int32
|
||||
minimum: 1
|
||||
maximum: 99
|
||||
x-minimum-message: "Must be positive"
|
||||
x-maximum-message: "Must be less than 100"
|
||||
- in: query
|
||||
name: token
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int32
|
||||
minimum: 1
|
||||
maximum: 99
|
||||
x-minimum-message: "Must be positive"
|
||||
x-maximum-message: "Must be less than 100"
|
||||
- in: header
|
||||
name: clientNumber
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int32
|
||||
minimum: 1
|
||||
maximum: 99
|
||||
x-minimum-message: "Must be positive"
|
||||
x-maximum-message: "Must be less than 100"
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/IntegerTest'
|
||||
responses:
|
||||
201:
|
||||
description: success
|
||||
/test/long/minmax/{number}:
|
||||
post:
|
||||
operationId: minmaxLongTest
|
||||
parameters:
|
||||
- in: path
|
||||
name: number
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
minimum: 1
|
||||
maximum: 99
|
||||
x-minimum-message: "Must be positive"
|
||||
x-maximum-message: "Must be less than 100"
|
||||
- in: query
|
||||
name: token
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
minimum: 1
|
||||
maximum: 99
|
||||
x-minimum-message: "Must be positive"
|
||||
x-maximum-message: "Must be less than 100"
|
||||
- in: header
|
||||
name: clientNumber
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
minimum: 1
|
||||
maximum: 99
|
||||
x-minimum-message: "Must be positive"
|
||||
x-maximum-message: "Must be less than 100"
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/LongTest'
|
||||
responses:
|
||||
201:
|
||||
description: success
|
||||
components:
|
||||
schemas:
|
||||
LengthTest:
|
||||
type: object
|
||||
properties:
|
||||
field1:
|
||||
type: string
|
||||
maxLength: 10
|
||||
x-size-message: "Must be max 10 characters"
|
||||
field2:
|
||||
type: string
|
||||
minLength: 1
|
||||
x-size-message: "Must not be empty"
|
||||
field3:
|
||||
type: string
|
||||
minLength: 3
|
||||
maxLength: 5
|
||||
x-size-message: "Must be between 3 and 5 characters"
|
||||
field4:
|
||||
type: string
|
||||
minLength: 3
|
||||
maxLength: 5
|
||||
field5:
|
||||
type: string
|
||||
minLength: 3
|
||||
field6:
|
||||
type: string
|
||||
maxLength: 5
|
||||
SizeTest:
|
||||
type: object
|
||||
properties:
|
||||
field1:
|
||||
type: array
|
||||
maxItems: 10
|
||||
x-size-message: "Must be max 10 elements"
|
||||
items:
|
||||
type: string
|
||||
field2:
|
||||
type: array
|
||||
minItems: 1
|
||||
x-size-message: "Must not be empty"
|
||||
items:
|
||||
type: string
|
||||
field3:
|
||||
type: array
|
||||
minItems: 3
|
||||
maxItems: 5
|
||||
x-size-message: "Must be between 3 and 5 elements"
|
||||
items:
|
||||
type: string
|
||||
field4:
|
||||
type: array
|
||||
minItems: 3
|
||||
maxItems: 5
|
||||
items:
|
||||
type: string
|
||||
field5:
|
||||
type: array
|
||||
minItems: 3
|
||||
items:
|
||||
type: string
|
||||
field6:
|
||||
type: array
|
||||
maxItems: 5
|
||||
items:
|
||||
type: string
|
||||
NumberTest:
|
||||
type: object
|
||||
properties:
|
||||
field1:
|
||||
type: number
|
||||
minimum: 0.1
|
||||
maximum: 99.9
|
||||
x-minimum-message: "Must be positive"
|
||||
x-maximum-message: "Must be less than 100"
|
||||
field2:
|
||||
type: number
|
||||
minimum: 0.1
|
||||
maximum: 99.9
|
||||
IntegerTest:
|
||||
type: object
|
||||
properties:
|
||||
field1:
|
||||
type: integer
|
||||
format: int32
|
||||
minimum: 1
|
||||
maximum: 99
|
||||
x-minimum-message: "Must be positive"
|
||||
x-maximum-message: "Must be less than 100"
|
||||
field2:
|
||||
type: integer
|
||||
format: int32
|
||||
minimum: 1
|
||||
maximum: 99
|
||||
LongTest:
|
||||
properties:
|
||||
field1:
|
||||
type: integer
|
||||
format: int64
|
||||
minimum: 1
|
||||
maximum: 99
|
||||
x-minimum-message: "Must be positive"
|
||||
x-maximum-message: "Must be less than 100"
|
||||
field2:
|
||||
type: integer
|
||||
format: int64
|
||||
minimum: 1
|
||||
maximum: 99
|
||||
@@ -0,0 +1,48 @@
|
||||
---
|
||||
# Corresponds to bug report 21680: https://github.com/openapitools/openapi-generator/issues/21680
|
||||
openapi: 3.0.1
|
||||
info:
|
||||
title: API that has problem with OpenAPI Generator
|
||||
version: 1.0.0
|
||||
paths:
|
||||
"/forbiddenaccesscsrf":
|
||||
get:
|
||||
summary: Forbidden access CSRF
|
||||
operationId: forbiddenAccessCsrfGet
|
||||
responses:
|
||||
'403':
|
||||
description: Expected response
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
"$ref": "#/components/schemas/errors"
|
||||
components:
|
||||
schemas:
|
||||
error:
|
||||
required:
|
||||
- code
|
||||
- horodatage
|
||||
- message
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: string
|
||||
description: Short error description
|
||||
message:
|
||||
type: string
|
||||
description: Complete human readable description
|
||||
error_uri:
|
||||
type: string
|
||||
description: Detailed error description URI
|
||||
format: uri
|
||||
horodatage:
|
||||
type: string
|
||||
description: Date time of occurence
|
||||
format: date-time
|
||||
errors:
|
||||
type: array
|
||||
properties:
|
||||
empty:
|
||||
type: boolean
|
||||
items:
|
||||
"$ref": "#/components/schemas/error"
|
||||
@@ -0,0 +1,182 @@
|
||||
openapi: 3.0.0
|
||||
servers:
|
||||
- url: 'https://example.org/v1'
|
||||
info:
|
||||
description: >-
|
||||
Example created for nullable multipartfile issue
|
||||
version: 1.0.0
|
||||
title: OpenAPI Stuff API created to reproduce issue
|
||||
license:
|
||||
name: Apache-2.0
|
||||
url: 'https://www.apache.org/licenses/LICENSE-2.0.html'
|
||||
tags:
|
||||
- name: multipartfile
|
||||
description: All about the nullable multipartfile
|
||||
security:
|
||||
- bearerAuth: []
|
||||
paths:
|
||||
/nullable-multipartfile:
|
||||
post:
|
||||
tags:
|
||||
- multipartfile
|
||||
summary: simple nullable multipartfile
|
||||
operationId: testNullableMultipartfile
|
||||
requestBody:
|
||||
content:
|
||||
multipart/form-data:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
file:
|
||||
type: string
|
||||
description: File to upload
|
||||
format: binary
|
||||
nullable: true
|
||||
jsonPayload:
|
||||
type: object
|
||||
description: simple json payload
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
required:
|
||||
- jsonPayload
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: string
|
||||
'400':
|
||||
description: Invalid status value
|
||||
|
||||
/nullable-multipartfile-array:
|
||||
post:
|
||||
tags:
|
||||
- multipartfile
|
||||
summary: simple nullable multipartfile
|
||||
operationId: testNullableMultipartfile
|
||||
requestBody:
|
||||
content:
|
||||
multipart/form-data:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
files:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
description: File to upload
|
||||
format: binary
|
||||
nullable: true
|
||||
jsonPayload:
|
||||
type: object
|
||||
description: simple json payload
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
required:
|
||||
- jsonPayload
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: string
|
||||
'400':
|
||||
description: Invalid status value
|
||||
/non-nullable-multipartfile:
|
||||
post:
|
||||
tags:
|
||||
- multipartfile
|
||||
summary: simple non nullable multipartfile
|
||||
operationId: testNonNullableMultipartfile
|
||||
requestBody:
|
||||
content:
|
||||
multipart/form-data:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
file:
|
||||
type: string
|
||||
description: File to upload
|
||||
format: binary
|
||||
nullable: false
|
||||
jsonPayload:
|
||||
type: object
|
||||
description: simple json payload
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
required:
|
||||
- jsonPayload
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: string
|
||||
'400':
|
||||
description: Invalid status value
|
||||
|
||||
/non-nullable-multipartfile-array:
|
||||
post:
|
||||
tags:
|
||||
- multipartfile
|
||||
summary: simple non nullable multipartfile
|
||||
operationId: testNonNullableMultipartfile
|
||||
requestBody:
|
||||
content:
|
||||
multipart/form-data:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
files:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
description: File to upload
|
||||
format: binary
|
||||
nullable: false
|
||||
jsonPayload:
|
||||
type: object
|
||||
description: simple json payload
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
required:
|
||||
- jsonPayload
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: string
|
||||
'400':
|
||||
description: Invalid status value
|
||||
externalDocs:
|
||||
description: Find out more about Swagger
|
||||
url: 'http://swagger.io'
|
||||
components:
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
schemas:
|
||||
Stuff:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
name:
|
||||
type: string
|
||||
tag:
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
openapi: 3.1.0
|
||||
info:
|
||||
title: Security scheme test
|
||||
version: 1.0.0
|
||||
paths:
|
||||
/test:
|
||||
get:
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: string
|
||||
components:
|
||||
securitySchemes:
|
||||
openId:
|
||||
type: openIdConnect
|
||||
openIdConnectUrl: https://localhost:8443
|
||||
security:
|
||||
- openId:
|
||||
- test
|
||||
@@ -12,7 +12,6 @@
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
|
||||
import type { Configuration } from "./configuration";
|
||||
import type { RequestArgs } from "./base";
|
||||
import type { AxiosInstance, AxiosResponse } from 'axios';
|
||||
@@ -63,6 +62,7 @@ export const setOAuthToObject = async function (object: any, name: string, scope
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function setFlattenedQueryParams(urlSearchParams: URLSearchParams, parameter: any, key: string = ""): void {
|
||||
if (parameter == null) return;
|
||||
if (typeof parameter === "object") {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* Echo Server API
|
||||
* Echo Server API
|
||||
@@ -12,12 +11,24 @@
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
interface AWSv4Configuration {
|
||||
options?: {
|
||||
region?: string
|
||||
service?: string
|
||||
}
|
||||
credentials?: {
|
||||
accessKeyId?: string
|
||||
secretAccessKey?: string,
|
||||
sessionToken?: string
|
||||
}
|
||||
}
|
||||
|
||||
export interface ConfigurationParameters {
|
||||
apiKey?: string | Promise<string> | ((name: string) => string) | ((name: string) => Promise<string>);
|
||||
username?: string;
|
||||
password?: string;
|
||||
accessToken?: string | Promise<string> | ((name?: string, scopes?: string[]) => string) | ((name?: string, scopes?: string[]) => Promise<string>);
|
||||
awsv4?: AWSv4Configuration;
|
||||
basePath?: string;
|
||||
serverIndex?: number;
|
||||
baseOptions?: any;
|
||||
@@ -44,6 +55,17 @@ export class Configuration {
|
||||
* @param scopes oauth2 scope
|
||||
*/
|
||||
accessToken?: string | Promise<string> | ((name?: string, scopes?: string[]) => string) | ((name?: string, scopes?: string[]) => Promise<string>);
|
||||
/**
|
||||
* parameter for aws4 signature security
|
||||
* @param {Object} AWS4Signature - AWS4 Signature security
|
||||
* @param {string} options.region - aws region
|
||||
* @param {string} options.service - name of the service.
|
||||
* @param {string} credentials.accessKeyId - aws access key id
|
||||
* @param {string} credentials.secretAccessKey - aws access key
|
||||
* @param {string} credentials.sessionToken - aws session token
|
||||
* @memberof Configuration
|
||||
*/
|
||||
awsv4?: AWSv4Configuration;
|
||||
/**
|
||||
* override base path
|
||||
*/
|
||||
@@ -70,6 +92,7 @@ export class Configuration {
|
||||
this.username = param.username;
|
||||
this.password = param.password;
|
||||
this.accessToken = param.accessToken;
|
||||
this.awsv4 = param.awsv4;
|
||||
this.basePath = param.basePath;
|
||||
this.serverIndex = param.serverIndex;
|
||||
this.baseOptions = {
|
||||
|
||||
@@ -129,17 +129,20 @@ components:
|
||||
allOf:
|
||||
- $ref: "#/components/schemas/Addressable"
|
||||
- $ref: "#/components/schemas/Extensible"
|
||||
description: Entity reference schema to be use for all entityRef class.
|
||||
- description: Entity reference schema to be use for all entityRef class.
|
||||
properties:
|
||||
name:
|
||||
description: Name of the related entity.
|
||||
type: string
|
||||
'@referredType':
|
||||
description: The actual type of the target instance when needed for disambiguation.
|
||||
type: string
|
||||
type: object
|
||||
example: null
|
||||
discriminator:
|
||||
propertyName: '@type'
|
||||
properties:
|
||||
name:
|
||||
description: Name of the related entity.
|
||||
type: string
|
||||
'@referredType':
|
||||
description: The actual type of the target instance when needed for disambiguation.
|
||||
type: string
|
||||
type: object
|
||||
example: null
|
||||
FooRefOrValue:
|
||||
discriminator:
|
||||
propertyName: '@type'
|
||||
@@ -151,22 +154,32 @@ components:
|
||||
Foo:
|
||||
allOf:
|
||||
- $ref: "#/components/schemas/Entity"
|
||||
- properties:
|
||||
fooPropA:
|
||||
type: string
|
||||
fooPropB:
|
||||
type: string
|
||||
type: object
|
||||
example: null
|
||||
example:
|
||||
'@baseType': '@baseType'
|
||||
'@type': '@type'
|
||||
fooPropA: fooPropA
|
||||
href: href
|
||||
id: id
|
||||
fooPropB: fooPropB
|
||||
properties:
|
||||
fooPropA:
|
||||
type: string
|
||||
fooPropB:
|
||||
type: string
|
||||
'@schemaLocation': '@schemaLocation'
|
||||
type: object
|
||||
FooRef:
|
||||
allOf:
|
||||
- $ref: "#/components/schemas/EntityRef"
|
||||
properties:
|
||||
foorefPropA:
|
||||
type: string
|
||||
- properties:
|
||||
foorefPropA:
|
||||
type: string
|
||||
type: object
|
||||
example: null
|
||||
type: object
|
||||
example: null
|
||||
BarRef:
|
||||
allOf:
|
||||
- $ref: "#/components/schemas/EntityRef"
|
||||
@@ -174,35 +187,49 @@ components:
|
||||
Bar_Create:
|
||||
allOf:
|
||||
- $ref: "#/components/schemas/Entity"
|
||||
properties:
|
||||
barPropA:
|
||||
type: string
|
||||
fooPropB:
|
||||
type: string
|
||||
foo:
|
||||
$ref: "#/components/schemas/FooRefOrValue"
|
||||
- properties:
|
||||
barPropA:
|
||||
type: string
|
||||
fooPropB:
|
||||
type: string
|
||||
foo:
|
||||
$ref: "#/components/schemas/FooRefOrValue"
|
||||
type: object
|
||||
example: null
|
||||
type: object
|
||||
example: null
|
||||
Bar:
|
||||
allOf:
|
||||
- $ref: "#/components/schemas/Entity"
|
||||
- properties:
|
||||
id:
|
||||
type: string
|
||||
barPropA:
|
||||
type: string
|
||||
fooPropB:
|
||||
type: string
|
||||
foo:
|
||||
$ref: "#/components/schemas/FooRefOrValue"
|
||||
required:
|
||||
- id
|
||||
type: object
|
||||
example: null
|
||||
example:
|
||||
'@baseType': '@baseType'
|
||||
'@type': '@type'
|
||||
foo:
|
||||
'@baseType': '@baseType'
|
||||
'@type': '@type'
|
||||
fooPropA: fooPropA
|
||||
href: href
|
||||
id: id
|
||||
fooPropB: fooPropB
|
||||
'@schemaLocation': '@schemaLocation'
|
||||
href: href
|
||||
id: id
|
||||
fooPropB: fooPropB
|
||||
'@schemaLocation': '@schemaLocation'
|
||||
barPropA: barPropA
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
barPropA:
|
||||
type: string
|
||||
fooPropB:
|
||||
type: string
|
||||
foo:
|
||||
$ref: "#/components/schemas/FooRefOrValue"
|
||||
required:
|
||||
- id
|
||||
type: object
|
||||
BarRefOrValue:
|
||||
oneOf:
|
||||
@@ -213,24 +240,33 @@ components:
|
||||
Pizza:
|
||||
allOf:
|
||||
- $ref: "#/components/schemas/Entity"
|
||||
properties:
|
||||
pizzaSize:
|
||||
type: number
|
||||
- properties:
|
||||
pizzaSize:
|
||||
type: number
|
||||
type: object
|
||||
example: null
|
||||
type: object
|
||||
example: null
|
||||
Pasta:
|
||||
allOf:
|
||||
- $ref: "#/components/schemas/Entity"
|
||||
properties:
|
||||
vendor:
|
||||
type: string
|
||||
- properties:
|
||||
vendor:
|
||||
type: string
|
||||
type: object
|
||||
example: null
|
||||
type: object
|
||||
example: null
|
||||
PizzaSpeziale:
|
||||
allOf:
|
||||
- $ref: "#/components/schemas/Pizza"
|
||||
properties:
|
||||
toppings:
|
||||
type: string
|
||||
- properties:
|
||||
toppings:
|
||||
type: string
|
||||
type: object
|
||||
example: null
|
||||
type: object
|
||||
example: null
|
||||
FruitType:
|
||||
enum:
|
||||
- APPLE
|
||||
|
||||
@@ -2,19 +2,18 @@
|
||||
|
||||
# EntityRef
|
||||
|
||||
Entity reference schema to be use for all entityRef class.
|
||||
|
||||
## Properties
|
||||
|
||||
| Name | Type | Description | Notes |
|
||||
|------------ | ------------- | ------------- | -------------|
|
||||
|**name** | **String** | Name of the related entity. | [optional] |
|
||||
|**atReferredType** | **String** | The actual type of the target instance when needed for disambiguation. | [optional] |
|
||||
|**href** | **String** | Hyperlink reference | [optional] |
|
||||
|**id** | **String** | unique identifier | [optional] |
|
||||
|**atSchemaLocation** | **String** | A URI to a JSON-Schema file that defines additional attributes and relationships | [optional] |
|
||||
|**atBaseType** | **String** | When sub-classing, this defines the super-class | [optional] |
|
||||
|**atType** | **String** | When sub-classing, this defines the sub-class Extensible name | |
|
||||
|**name** | **String** | Name of the related entity. | [optional] |
|
||||
|**atReferredType** | **String** | The actual type of the target instance when needed for disambiguation. | [optional] |
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -28,16 +28,16 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||
|
||||
/**
|
||||
* Entity reference schema to be use for all entityRef class.
|
||||
* EntityRef
|
||||
*/
|
||||
@JsonPropertyOrder({
|
||||
EntityRef.JSON_PROPERTY_NAME,
|
||||
EntityRef.JSON_PROPERTY_AT_REFERRED_TYPE,
|
||||
EntityRef.JSON_PROPERTY_HREF,
|
||||
EntityRef.JSON_PROPERTY_ID,
|
||||
EntityRef.JSON_PROPERTY_AT_SCHEMA_LOCATION,
|
||||
EntityRef.JSON_PROPERTY_AT_BASE_TYPE,
|
||||
EntityRef.JSON_PROPERTY_AT_TYPE
|
||||
EntityRef.JSON_PROPERTY_AT_TYPE,
|
||||
EntityRef.JSON_PROPERTY_NAME,
|
||||
EntityRef.JSON_PROPERTY_AT_REFERRED_TYPE
|
||||
})
|
||||
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.17.0-SNAPSHOT")
|
||||
@JsonIgnoreProperties(
|
||||
@@ -51,14 +51,6 @@ import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||
})
|
||||
|
||||
public class EntityRef {
|
||||
public static final String JSON_PROPERTY_NAME = "name";
|
||||
@javax.annotation.Nullable
|
||||
protected String name;
|
||||
|
||||
public static final String JSON_PROPERTY_AT_REFERRED_TYPE = "@referredType";
|
||||
@javax.annotation.Nullable
|
||||
protected String atReferredType;
|
||||
|
||||
public static final String JSON_PROPERTY_HREF = "href";
|
||||
@javax.annotation.Nullable
|
||||
protected String href;
|
||||
@@ -79,59 +71,17 @@ public class EntityRef {
|
||||
// The discriminator does not have Nullability-annotation since it is added during serialization by the @JsonTypeName annotation
|
||||
protected String atType;
|
||||
|
||||
public static final String JSON_PROPERTY_NAME = "name";
|
||||
@javax.annotation.Nullable
|
||||
protected String name;
|
||||
|
||||
public static final String JSON_PROPERTY_AT_REFERRED_TYPE = "@referredType";
|
||||
@javax.annotation.Nullable
|
||||
protected String atReferredType;
|
||||
|
||||
public EntityRef() {
|
||||
}
|
||||
|
||||
public EntityRef name(@javax.annotation.Nullable String name) {
|
||||
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Name of the related entity.
|
||||
* @return name
|
||||
*/
|
||||
@javax.annotation.Nullable
|
||||
@JsonProperty(value = JSON_PROPERTY_NAME, required = false)
|
||||
@JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
@JsonProperty(value = JSON_PROPERTY_NAME, required = false)
|
||||
@JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
|
||||
public void setName(@javax.annotation.Nullable String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public EntityRef atReferredType(@javax.annotation.Nullable String atReferredType) {
|
||||
|
||||
this.atReferredType = atReferredType;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The actual type of the target instance when needed for disambiguation.
|
||||
* @return atReferredType
|
||||
*/
|
||||
@javax.annotation.Nullable
|
||||
@JsonProperty(value = JSON_PROPERTY_AT_REFERRED_TYPE, required = false)
|
||||
@JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
|
||||
|
||||
public String getAtReferredType() {
|
||||
return atReferredType;
|
||||
}
|
||||
|
||||
|
||||
@JsonProperty(value = JSON_PROPERTY_AT_REFERRED_TYPE, required = false)
|
||||
@JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
|
||||
public void setAtReferredType(@javax.annotation.Nullable String atReferredType) {
|
||||
this.atReferredType = atReferredType;
|
||||
}
|
||||
|
||||
public EntityRef href(@javax.annotation.Nullable String href) {
|
||||
|
||||
this.href = href;
|
||||
@@ -257,6 +207,56 @@ public class EntityRef {
|
||||
this.atType = atType;
|
||||
}
|
||||
|
||||
public EntityRef name(@javax.annotation.Nullable String name) {
|
||||
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Name of the related entity.
|
||||
* @return name
|
||||
*/
|
||||
@javax.annotation.Nullable
|
||||
@JsonProperty(value = JSON_PROPERTY_NAME, required = false)
|
||||
@JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
@JsonProperty(value = JSON_PROPERTY_NAME, required = false)
|
||||
@JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
|
||||
public void setName(@javax.annotation.Nullable String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public EntityRef atReferredType(@javax.annotation.Nullable String atReferredType) {
|
||||
|
||||
this.atReferredType = atReferredType;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The actual type of the target instance when needed for disambiguation.
|
||||
* @return atReferredType
|
||||
*/
|
||||
@javax.annotation.Nullable
|
||||
@JsonProperty(value = JSON_PROPERTY_AT_REFERRED_TYPE, required = false)
|
||||
@JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
|
||||
|
||||
public String getAtReferredType() {
|
||||
return atReferredType;
|
||||
}
|
||||
|
||||
|
||||
@JsonProperty(value = JSON_PROPERTY_AT_REFERRED_TYPE, required = false)
|
||||
@JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
|
||||
public void setAtReferredType(@javax.annotation.Nullable String atReferredType) {
|
||||
this.atReferredType = atReferredType;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
@@ -267,31 +267,31 @@ public class EntityRef {
|
||||
return false;
|
||||
}
|
||||
EntityRef entityRef = (EntityRef) o;
|
||||
return Objects.equals(this.name, entityRef.name) &&
|
||||
Objects.equals(this.atReferredType, entityRef.atReferredType) &&
|
||||
Objects.equals(this.href, entityRef.href) &&
|
||||
return Objects.equals(this.href, entityRef.href) &&
|
||||
Objects.equals(this.id, entityRef.id) &&
|
||||
Objects.equals(this.atSchemaLocation, entityRef.atSchemaLocation) &&
|
||||
Objects.equals(this.atBaseType, entityRef.atBaseType) &&
|
||||
Objects.equals(this.atType, entityRef.atType);
|
||||
Objects.equals(this.atType, entityRef.atType) &&
|
||||
Objects.equals(this.name, entityRef.name) &&
|
||||
Objects.equals(this.atReferredType, entityRef.atReferredType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(name, atReferredType, href, id, atSchemaLocation, atBaseType, atType);
|
||||
return Objects.hash(href, id, atSchemaLocation, atBaseType, atType, name, atReferredType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("class EntityRef {\n");
|
||||
sb.append(" name: ").append(toIndentedString(name)).append("\n");
|
||||
sb.append(" atReferredType: ").append(toIndentedString(atReferredType)).append("\n");
|
||||
sb.append(" href: ").append(toIndentedString(href)).append("\n");
|
||||
sb.append(" id: ").append(toIndentedString(id)).append("\n");
|
||||
sb.append(" atSchemaLocation: ").append(toIndentedString(atSchemaLocation)).append("\n");
|
||||
sb.append(" atBaseType: ").append(toIndentedString(atBaseType)).append("\n");
|
||||
sb.append(" atType: ").append(toIndentedString(atType)).append("\n");
|
||||
sb.append(" name: ").append(toIndentedString(name)).append("\n");
|
||||
sb.append(" atReferredType: ").append(toIndentedString(atReferredType)).append("\n");
|
||||
sb.append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**id** | **String** | |
|
||||
**bar_prop_a** | Option<**String**> | | [optional]
|
||||
**foo_prop_b** | Option<**String**> | | [optional]
|
||||
**foo** | Option<[**models::FooRefOrValue**](FooRefOrValue.md)> | | [optional]
|
||||
**href** | Option<**String**> | Hyperlink reference | [optional]
|
||||
**id** | **String** | |
|
||||
**at_schema_location** | Option<**String**> | A URI to a JSON-Schema file that defines additional attributes and relationships | [optional]
|
||||
**at_base_type** | Option<**String**> | When sub-classing, this defines the super-class | [optional]
|
||||
**at_type** | **String** | When sub-classing, this defines the sub-class Extensible name |
|
||||
**bar_prop_a** | Option<**String**> | | [optional]
|
||||
**foo_prop_b** | Option<**String**> | | [optional]
|
||||
**foo** | Option<[**models::FooRefOrValue**](FooRefOrValue.md)> | | [optional]
|
||||
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**bar_prop_a** | Option<**String**> | | [optional]
|
||||
**foo_prop_b** | Option<**String**> | | [optional]
|
||||
**foo** | Option<[**models::FooRefOrValue**](FooRefOrValue.md)> | | [optional]
|
||||
**href** | Option<**String**> | Hyperlink reference | [optional]
|
||||
**id** | Option<**String**> | unique identifier | [optional]
|
||||
**at_schema_location** | Option<**String**> | A URI to a JSON-Schema file that defines additional attributes and relationships | [optional]
|
||||
**at_base_type** | Option<**String**> | When sub-classing, this defines the super-class | [optional]
|
||||
**at_type** | **String** | When sub-classing, this defines the sub-class Extensible name |
|
||||
**bar_prop_a** | Option<**String**> | | [optional]
|
||||
**foo_prop_b** | Option<**String**> | | [optional]
|
||||
**foo** | Option<[**models::FooRefOrValue**](FooRefOrValue.md)> | | [optional]
|
||||
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**name** | Option<**String**> | Name of the related entity. | [optional]
|
||||
**at_referred_type** | Option<**String**> | The actual type of the target instance when needed for disambiguation. | [optional]
|
||||
**href** | Option<**String**> | Hyperlink reference | [optional]
|
||||
**id** | Option<**String**> | unique identifier | [optional]
|
||||
**at_schema_location** | Option<**String**> | A URI to a JSON-Schema file that defines additional attributes and relationships | [optional]
|
||||
**at_base_type** | Option<**String**> | When sub-classing, this defines the super-class | [optional]
|
||||
**at_type** | **String** | When sub-classing, this defines the sub-class Extensible name |
|
||||
**name** | Option<**String**> | Name of the related entity. | [optional]
|
||||
**at_referred_type** | Option<**String**> | The actual type of the target instance when needed for disambiguation. | [optional]
|
||||
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**foo_prop_a** | Option<**String**> | | [optional]
|
||||
**foo_prop_b** | Option<**String**> | | [optional]
|
||||
**href** | Option<**String**> | Hyperlink reference | [optional]
|
||||
**id** | Option<**String**> | unique identifier | [optional]
|
||||
**at_schema_location** | Option<**String**> | A URI to a JSON-Schema file that defines additional attributes and relationships | [optional]
|
||||
**at_base_type** | Option<**String**> | When sub-classing, this defines the super-class | [optional]
|
||||
**at_type** | **String** | When sub-classing, this defines the sub-class Extensible name |
|
||||
**foo_prop_a** | Option<**String**> | | [optional]
|
||||
**foo_prop_b** | Option<**String**> | | [optional]
|
||||
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**fooref_prop_a** | Option<**String**> | | [optional]
|
||||
**name** | Option<**String**> | Name of the related entity. | [optional]
|
||||
**at_referred_type** | Option<**String**> | The actual type of the target instance when needed for disambiguation. | [optional]
|
||||
**href** | Option<**String**> | Hyperlink reference | [optional]
|
||||
**id** | Option<**String**> | unique identifier | [optional]
|
||||
**at_schema_location** | Option<**String**> | A URI to a JSON-Schema file that defines additional attributes and relationships | [optional]
|
||||
**at_base_type** | Option<**String**> | When sub-classing, this defines the super-class | [optional]
|
||||
**at_type** | **String** | When sub-classing, this defines the sub-class Extensible name |
|
||||
**name** | Option<**String**> | Name of the related entity. | [optional]
|
||||
**at_referred_type** | Option<**String**> | The actual type of the target instance when needed for disambiguation. | [optional]
|
||||
**fooref_prop_a** | Option<**String**> | | [optional]
|
||||
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**vendor** | Option<**String**> | | [optional]
|
||||
**href** | Option<**String**> | Hyperlink reference | [optional]
|
||||
**id** | Option<**String**> | unique identifier | [optional]
|
||||
**at_schema_location** | Option<**String**> | A URI to a JSON-Schema file that defines additional attributes and relationships | [optional]
|
||||
**at_base_type** | Option<**String**> | When sub-classing, this defines the super-class | [optional]
|
||||
**at_type** | **String** | When sub-classing, this defines the sub-class Extensible name |
|
||||
**vendor** | Option<**String**> | | [optional]
|
||||
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**pizza_size** | Option<**f64**> | | [optional]
|
||||
**href** | Option<**String**> | Hyperlink reference | [optional]
|
||||
**id** | Option<**String**> | unique identifier | [optional]
|
||||
**at_schema_location** | Option<**String**> | A URI to a JSON-Schema file that defines additional attributes and relationships | [optional]
|
||||
**at_base_type** | Option<**String**> | When sub-classing, this defines the super-class | [optional]
|
||||
**at_type** | **String** | When sub-classing, this defines the sub-class Extensible name |
|
||||
**pizza_size** | Option<**f64**> | | [optional]
|
||||
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**toppings** | Option<**String**> | | [optional]
|
||||
**pizza_size** | Option<**f64**> | | [optional]
|
||||
**href** | Option<**String**> | Hyperlink reference | [optional]
|
||||
**id** | Option<**String**> | unique identifier | [optional]
|
||||
**at_schema_location** | Option<**String**> | A URI to a JSON-Schema file that defines additional attributes and relationships | [optional]
|
||||
**at_base_type** | Option<**String**> | When sub-classing, this defines the super-class | [optional]
|
||||
**at_type** | **String** | When sub-classing, this defines the sub-class Extensible name |
|
||||
**pizza_size** | Option<**f64**> | | [optional]
|
||||
**toppings** | Option<**String**> | | [optional]
|
||||
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
@@ -13,17 +13,11 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Bar {
|
||||
#[serde(rename = "id")]
|
||||
pub id: String,
|
||||
#[serde(rename = "barPropA", skip_serializing_if = "Option::is_none")]
|
||||
pub bar_prop_a: Option<String>,
|
||||
#[serde(rename = "fooPropB", skip_serializing_if = "Option::is_none")]
|
||||
pub foo_prop_b: Option<String>,
|
||||
#[serde(rename = "foo", skip_serializing_if = "Option::is_none")]
|
||||
pub foo: Option<Box<models::FooRefOrValue>>,
|
||||
/// Hyperlink reference
|
||||
#[serde(rename = "href", skip_serializing_if = "Option::is_none")]
|
||||
pub href: Option<String>,
|
||||
#[serde(rename = "id")]
|
||||
pub id: String,
|
||||
/// A URI to a JSON-Schema file that defines additional attributes and relationships
|
||||
#[serde(rename = "@schemaLocation", skip_serializing_if = "Option::is_none")]
|
||||
pub at_schema_location: Option<String>,
|
||||
@@ -33,19 +27,25 @@ pub struct Bar {
|
||||
/// When sub-classing, this defines the sub-class Extensible name
|
||||
#[serde(rename = "@type")]
|
||||
pub at_type: String,
|
||||
#[serde(rename = "barPropA", skip_serializing_if = "Option::is_none")]
|
||||
pub bar_prop_a: Option<String>,
|
||||
#[serde(rename = "fooPropB", skip_serializing_if = "Option::is_none")]
|
||||
pub foo_prop_b: Option<String>,
|
||||
#[serde(rename = "foo", skip_serializing_if = "Option::is_none")]
|
||||
pub foo: Option<Box<models::FooRefOrValue>>,
|
||||
}
|
||||
|
||||
impl Bar {
|
||||
pub fn new(id: String, at_type: String) -> Bar {
|
||||
Bar {
|
||||
id,
|
||||
bar_prop_a: None,
|
||||
foo_prop_b: None,
|
||||
foo: None,
|
||||
href: None,
|
||||
id,
|
||||
at_schema_location: None,
|
||||
at_base_type: None,
|
||||
at_type,
|
||||
bar_prop_a: None,
|
||||
foo_prop_b: None,
|
||||
foo: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,12 +13,6 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct BarCreate {
|
||||
#[serde(rename = "barPropA", skip_serializing_if = "Option::is_none")]
|
||||
pub bar_prop_a: Option<String>,
|
||||
#[serde(rename = "fooPropB", skip_serializing_if = "Option::is_none")]
|
||||
pub foo_prop_b: Option<String>,
|
||||
#[serde(rename = "foo", skip_serializing_if = "Option::is_none")]
|
||||
pub foo: Option<Box<models::FooRefOrValue>>,
|
||||
/// Hyperlink reference
|
||||
#[serde(rename = "href", skip_serializing_if = "Option::is_none")]
|
||||
pub href: Option<String>,
|
||||
@@ -34,19 +28,25 @@ pub struct BarCreate {
|
||||
/// When sub-classing, this defines the sub-class Extensible name
|
||||
#[serde(rename = "@type")]
|
||||
pub at_type: String,
|
||||
#[serde(rename = "barPropA", skip_serializing_if = "Option::is_none")]
|
||||
pub bar_prop_a: Option<String>,
|
||||
#[serde(rename = "fooPropB", skip_serializing_if = "Option::is_none")]
|
||||
pub foo_prop_b: Option<String>,
|
||||
#[serde(rename = "foo", skip_serializing_if = "Option::is_none")]
|
||||
pub foo: Option<Box<models::FooRefOrValue>>,
|
||||
}
|
||||
|
||||
impl BarCreate {
|
||||
pub fn new(at_type: String) -> BarCreate {
|
||||
BarCreate {
|
||||
bar_prop_a: None,
|
||||
foo_prop_b: None,
|
||||
foo: None,
|
||||
href: None,
|
||||
id: None,
|
||||
at_schema_location: None,
|
||||
at_base_type: None,
|
||||
at_type,
|
||||
bar_prop_a: None,
|
||||
foo_prop_b: None,
|
||||
foo: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,12 +13,6 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct BarRef {
|
||||
/// Name of the related entity.
|
||||
#[serde(rename = "name", skip_serializing_if = "Option::is_none")]
|
||||
pub name: Option<String>,
|
||||
/// The actual type of the target instance when needed for disambiguation.
|
||||
#[serde(rename = "@referredType", skip_serializing_if = "Option::is_none")]
|
||||
pub at_referred_type: Option<String>,
|
||||
/// Hyperlink reference
|
||||
#[serde(rename = "href", skip_serializing_if = "Option::is_none")]
|
||||
pub href: Option<String>,
|
||||
@@ -34,18 +28,24 @@ pub struct BarRef {
|
||||
/// When sub-classing, this defines the sub-class Extensible name
|
||||
#[serde(rename = "@type")]
|
||||
pub at_type: String,
|
||||
/// Name of the related entity.
|
||||
#[serde(rename = "name", skip_serializing_if = "Option::is_none")]
|
||||
pub name: Option<String>,
|
||||
/// The actual type of the target instance when needed for disambiguation.
|
||||
#[serde(rename = "@referredType", skip_serializing_if = "Option::is_none")]
|
||||
pub at_referred_type: Option<String>,
|
||||
}
|
||||
|
||||
impl BarRef {
|
||||
pub fn new(at_type: String) -> BarRef {
|
||||
BarRef {
|
||||
name: None,
|
||||
at_referred_type: None,
|
||||
href: None,
|
||||
id: None,
|
||||
at_schema_location: None,
|
||||
at_base_type: None,
|
||||
at_type,
|
||||
name: None,
|
||||
at_referred_type: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,18 +11,11 @@
|
||||
use crate::models;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// EntityRef : Entity reference schema to be use for all entityRef class.
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(tag = "@type")]
|
||||
pub enum EntityRef {
|
||||
#[serde(rename="BarRef")]
|
||||
BarRef {
|
||||
/// Name of the related entity.
|
||||
#[serde(rename = "name", skip_serializing_if = "Option::is_none")]
|
||||
name: Option<String>,
|
||||
/// The actual type of the target instance when needed for disambiguation.
|
||||
#[serde(rename = "@referredType", skip_serializing_if = "Option::is_none")]
|
||||
at_referred_type: Option<String>,
|
||||
/// Hyperlink reference
|
||||
#[serde(rename = "href", skip_serializing_if = "Option::is_none")]
|
||||
href: Option<String>,
|
||||
@@ -35,15 +28,15 @@ pub enum EntityRef {
|
||||
/// When sub-classing, this defines the super-class
|
||||
#[serde(rename = "@baseType", skip_serializing_if = "Option::is_none")]
|
||||
at_base_type: Option<String>,
|
||||
/// Name of the related entity.
|
||||
#[serde(rename = "name", skip_serializing_if = "Option::is_none")]
|
||||
name: Option<String>,
|
||||
/// The actual type of the target instance when needed for disambiguation.
|
||||
#[serde(rename = "@referredType", skip_serializing_if = "Option::is_none")]
|
||||
at_referred_type: Option<String>,
|
||||
},
|
||||
#[serde(rename="FooRef")]
|
||||
FooRef {
|
||||
/// Name of the related entity.
|
||||
#[serde(rename = "name", skip_serializing_if = "Option::is_none")]
|
||||
name: Option<String>,
|
||||
/// The actual type of the target instance when needed for disambiguation.
|
||||
#[serde(rename = "@referredType", skip_serializing_if = "Option::is_none")]
|
||||
at_referred_type: Option<String>,
|
||||
/// Hyperlink reference
|
||||
#[serde(rename = "href", skip_serializing_if = "Option::is_none")]
|
||||
href: Option<String>,
|
||||
@@ -56,18 +49,24 @@ pub enum EntityRef {
|
||||
/// When sub-classing, this defines the super-class
|
||||
#[serde(rename = "@baseType", skip_serializing_if = "Option::is_none")]
|
||||
at_base_type: Option<String>,
|
||||
/// Name of the related entity.
|
||||
#[serde(rename = "name", skip_serializing_if = "Option::is_none")]
|
||||
name: Option<String>,
|
||||
/// The actual type of the target instance when needed for disambiguation.
|
||||
#[serde(rename = "@referredType", skip_serializing_if = "Option::is_none")]
|
||||
at_referred_type: Option<String>,
|
||||
},
|
||||
}
|
||||
|
||||
impl Default for EntityRef {
|
||||
fn default() -> Self {
|
||||
Self::BarRef {
|
||||
name: Default::default(),
|
||||
at_referred_type: Default::default(),
|
||||
href: Default::default(),
|
||||
id: Default::default(),
|
||||
at_schema_location: Default::default(),
|
||||
at_base_type: Default::default(),
|
||||
name: Default::default(),
|
||||
at_referred_type: Default::default(),
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,10 +13,6 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Foo {
|
||||
#[serde(rename = "fooPropA", skip_serializing_if = "Option::is_none")]
|
||||
pub foo_prop_a: Option<String>,
|
||||
#[serde(rename = "fooPropB", skip_serializing_if = "Option::is_none")]
|
||||
pub foo_prop_b: Option<String>,
|
||||
/// Hyperlink reference
|
||||
#[serde(rename = "href", skip_serializing_if = "Option::is_none")]
|
||||
pub href: Option<String>,
|
||||
@@ -32,18 +28,22 @@ pub struct Foo {
|
||||
/// When sub-classing, this defines the sub-class Extensible name
|
||||
#[serde(rename = "@type")]
|
||||
pub at_type: String,
|
||||
#[serde(rename = "fooPropA", skip_serializing_if = "Option::is_none")]
|
||||
pub foo_prop_a: Option<String>,
|
||||
#[serde(rename = "fooPropB", skip_serializing_if = "Option::is_none")]
|
||||
pub foo_prop_b: Option<String>,
|
||||
}
|
||||
|
||||
impl Foo {
|
||||
pub fn new(at_type: String) -> Foo {
|
||||
Foo {
|
||||
foo_prop_a: None,
|
||||
foo_prop_b: None,
|
||||
href: None,
|
||||
id: None,
|
||||
at_schema_location: None,
|
||||
at_base_type: None,
|
||||
at_type,
|
||||
foo_prop_a: None,
|
||||
foo_prop_b: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,14 +13,6 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct FooRef {
|
||||
#[serde(rename = "foorefPropA", skip_serializing_if = "Option::is_none")]
|
||||
pub fooref_prop_a: Option<String>,
|
||||
/// Name of the related entity.
|
||||
#[serde(rename = "name", skip_serializing_if = "Option::is_none")]
|
||||
pub name: Option<String>,
|
||||
/// The actual type of the target instance when needed for disambiguation.
|
||||
#[serde(rename = "@referredType", skip_serializing_if = "Option::is_none")]
|
||||
pub at_referred_type: Option<String>,
|
||||
/// Hyperlink reference
|
||||
#[serde(rename = "href", skip_serializing_if = "Option::is_none")]
|
||||
pub href: Option<String>,
|
||||
@@ -36,19 +28,27 @@ pub struct FooRef {
|
||||
/// When sub-classing, this defines the sub-class Extensible name
|
||||
#[serde(rename = "@type")]
|
||||
pub at_type: String,
|
||||
/// Name of the related entity.
|
||||
#[serde(rename = "name", skip_serializing_if = "Option::is_none")]
|
||||
pub name: Option<String>,
|
||||
/// The actual type of the target instance when needed for disambiguation.
|
||||
#[serde(rename = "@referredType", skip_serializing_if = "Option::is_none")]
|
||||
pub at_referred_type: Option<String>,
|
||||
#[serde(rename = "foorefPropA", skip_serializing_if = "Option::is_none")]
|
||||
pub fooref_prop_a: Option<String>,
|
||||
}
|
||||
|
||||
impl FooRef {
|
||||
pub fn new(at_type: String) -> FooRef {
|
||||
FooRef {
|
||||
fooref_prop_a: None,
|
||||
name: None,
|
||||
at_referred_type: None,
|
||||
href: None,
|
||||
id: None,
|
||||
at_schema_location: None,
|
||||
at_base_type: None,
|
||||
at_type,
|
||||
name: None,
|
||||
at_referred_type: None,
|
||||
fooref_prop_a: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user