Add mapping features to Julia generators (#16370)

* add mapping features to julia generators

* additional changes required for mapped names (#16383)

---------

Co-authored-by: Tanmay Mohapatra <tanmaykm@gmail.com>
This commit is contained in:
William Cheng 2023-08-24 10:09:54 +08:00 committed by GitHub
parent 7e67e3aafb
commit 91fc151451
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 880 additions and 4 deletions

View File

@ -1,9 +1,13 @@
generatorName: julia-client
outputDir: samples/client/petstore/julia
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
inputSpec: modules/openapi-generator/src/test/resources/3_0/julia/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/julia-client
additionalProperties:
hideGenerationTimestamp: "true"
packageName: OpenAPIGenPetStoreClient
exportOperations: "true"
exportModels: "true"
exportModels: "true"
modelNameMappings:
another_model: MappedModel
nameMappings:
another_property: mappedProperty

View File

@ -1,9 +1,9 @@
generatorName: julia-server
outputDir: samples/server/petstore/julia
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
inputSpec: modules/openapi-generator/src/test/resources/3_0/julia/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/julia-server
additionalProperties:
hideGenerationTimestamp: "true"
packageName: OpenAPIGenPetStoreServer
exportOperations: "true"
exportModels: "true"
exportModels: "true"

View File

@ -209,6 +209,11 @@ public abstract class AbstractJuliaCodegen extends DefaultCodegen {
return "model_" + toModelName(name);
}
@Override
public String toModelDocFilename(String name) {
return toModelName(name);
}
@Override
public String toApiFilename(String name) {
name = name.replaceAll("-", "_");
@ -226,6 +231,12 @@ public abstract class AbstractJuliaCodegen extends DefaultCodegen {
@Override
public String toParamName(String name) {
// obtain the name from parameterNameMapping directly if provided
if (parameterNameMapping.containsKey(name)) {
return parameterNameMapping.get(name);
}
name = toVarName(name);
CamelizeOption camelizeOption = CamelizeOption.UPPERCASE_FIRST_CHAR;
name = camelize(sanitizeName(name), camelizeOption);
name = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, name);
@ -242,7 +253,13 @@ public abstract class AbstractJuliaCodegen extends DefaultCodegen {
@Override
public String toVarName(String name) {
// obtain the name from nameMapping directly if provided
if (nameMapping.containsKey(name)) {
return nameMapping.get(name);
}
return name;
}
/**
@ -288,6 +305,11 @@ public abstract class AbstractJuliaCodegen extends DefaultCodegen {
*/
@Override
public String toModelName(final String name) {
// obtain the name from modelNameMapping directly if provided
if (modelNameMapping.containsKey(name)) {
return modelNameMapping.get(name);
}
String result = sanitizeName(name);
// remove dollar sign

View File

@ -0,0 +1,748 @@
openapi: 3.0.0
servers:
- url: 'http://petstore.swagger.io/v2'
info:
description: >-
This is a sample server Petstore server. For this sample, you can use the api key
`special-key` to test the authorization filters.
version: 1.0.0
title: OpenAPI Petstore
license:
name: Apache-2.0
url: 'https://www.apache.org/licenses/LICENSE-2.0.html'
tags:
- name: pet
description: Everything about your Pets
- name: store
description: Access to Petstore orders
- name: user
description: Operations about user
paths:
/pet:
post:
tags:
- pet
summary: Add a new pet to the store
description: ''
operationId: addPet
responses:
'200':
description: successful operation
content:
application/xml:
schema:
$ref: '#/components/schemas/Pet'
application/json:
schema:
$ref: '#/components/schemas/Pet'
'405':
description: Invalid input
security:
- petstore_auth:
- 'write:pets'
- 'read:pets'
requestBody:
$ref: '#/components/requestBodies/Pet'
put:
tags:
- pet
summary: Update an existing pet
description: ''
operationId: updatePet
externalDocs:
url: "http://petstore.swagger.io/v2/doc/updatePet"
description: "API documentation for the updatePet operation"
responses:
'200':
description: successful operation
content:
application/xml:
schema:
$ref: '#/components/schemas/Pet'
application/json:
schema:
$ref: '#/components/schemas/Pet'
'400':
description: Invalid ID supplied
'404':
description: Pet not found
'405':
description: Validation exception
security:
- petstore_auth:
- 'write:pets'
- 'read:pets'
requestBody:
$ref: '#/components/requestBodies/Pet'
/pet/findByStatus:
get:
tags:
- pet
summary: Finds Pets by status
description: Multiple status values can be provided with comma separated strings
operationId: findPetsByStatus
parameters:
- name: status
in: query
description: Status values that need to be considered for filter
required: true
style: form
explode: false
deprecated: true
schema:
type: array
items:
type: string
enum:
- available
- pending
- sold
default: available
responses:
'200':
description: successful operation
content:
application/xml:
schema:
type: array
items:
$ref: '#/components/schemas/Pet'
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Pet'
'400':
description: Invalid status value
security:
- petstore_auth:
- 'read:pets'
/pet/findByTags:
get:
tags:
- pet
summary: Finds Pets by tags
description: >-
Multiple tags can be provided with comma separated strings. Use tag1,
tag2, tag3 for testing.
operationId: findPetsByTags
parameters:
- name: tags
in: query
description: Tags to filter by
required: true
style: form
explode: false
schema:
type: array
items:
type: string
responses:
'200':
description: successful operation
content:
application/xml:
schema:
type: array
items:
$ref: '#/components/schemas/Pet'
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Pet'
'400':
description: Invalid tag value
security:
- petstore_auth:
- 'read:pets'
deprecated: true
'/pet/{petId}':
get:
tags:
- pet
summary: Find pet by ID
description: Returns a single pet
operationId: getPetById
parameters:
- name: petId
in: path
description: ID of pet to return
required: true
schema:
type: integer
format: int64
responses:
'200':
description: successful operation
content:
application/xml:
schema:
$ref: '#/components/schemas/Pet'
application/json:
schema:
$ref: '#/components/schemas/Pet'
'400':
description: Invalid ID supplied
'404':
description: Pet not found
security:
- api_key: []
post:
tags:
- pet
summary: Updates a pet in the store with form data
description: ''
operationId: updatePetWithForm
parameters:
- name: petId
in: path
description: ID of pet that needs to be updated
required: true
schema:
type: integer
format: int64
responses:
'405':
description: Invalid input
security:
- petstore_auth:
- 'write:pets'
- 'read:pets'
requestBody:
content:
application/x-www-form-urlencoded:
schema:
type: object
properties:
name:
description: Updated name of the pet
type: string
status:
description: Updated status of the pet
type: string
delete:
tags:
- pet
summary: Deletes a pet
description: ''
operationId: deletePet
parameters:
- name: api_key
in: header
required: false
schema:
type: string
- name: petId
in: path
description: Pet id to delete
required: true
schema:
type: integer
format: int64
responses:
'400':
description: Invalid pet value
security:
- petstore_auth:
- 'write:pets'
- 'read:pets'
'/pet/{petId}/uploadImage':
post:
tags:
- pet
summary: uploads an image
description: ''
operationId: uploadFile
parameters:
- name: petId
in: path
description: ID of pet to update
required: true
schema:
type: integer
format: int64
responses:
'200':
description: successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/ApiResponse'
security:
- petstore_auth:
- 'write:pets'
- 'read:pets'
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
additionalMetadata:
description: Additional data to pass to server
type: string
file:
description: file to upload
type: string
format: binary
/store/inventory:
get:
tags:
- store
summary: Returns pet inventories by status
description: Returns a map of status codes to quantities
operationId: getInventory
responses:
'200':
description: successful operation
content:
application/json:
schema:
type: object
additionalProperties:
type: integer
format: int32
security:
- api_key: []
/store/order:
post:
tags:
- store
summary: Place an order for a pet
description: ''
operationId: placeOrder
responses:
'200':
description: successful operation
content:
application/xml:
schema:
$ref: '#/components/schemas/Order'
application/json:
schema:
$ref: '#/components/schemas/Order'
'400':
description: Invalid Order
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Order'
description: order placed for purchasing the pet
required: true
'/store/order/{orderId}':
get:
tags:
- store
summary: Find purchase order by ID
description: >-
For valid response try integer IDs with value <= 5 or > 10. Other values
will generate exceptions
operationId: getOrderById
parameters:
- name: orderId
in: path
description: ID of pet that needs to be fetched
required: true
schema:
type: integer
format: int64
minimum: 1
maximum: 5
responses:
'200':
description: successful operation
content:
application/xml:
schema:
$ref: '#/components/schemas/Order'
application/json:
schema:
$ref: '#/components/schemas/Order'
'400':
description: Invalid ID supplied
'404':
description: Order not found
delete:
tags:
- store
summary: Delete purchase order by ID
description: >-
For valid response try integer IDs with value < 1000. Anything above
1000 or nonintegers will generate API errors
operationId: deleteOrder
parameters:
- name: orderId
in: path
description: ID of the order that needs to be deleted
required: true
schema:
type: string
responses:
'400':
description: Invalid ID supplied
'404':
description: Order not found
/user:
post:
tags:
- user
summary: Create user
description: This can only be done by the logged in user.
operationId: createUser
responses:
default:
description: successful operation
security:
- api_key: []
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/User'
description: Created user object
required: true
/user/createWithArray:
post:
tags:
- user
summary: Creates list of users with given input array
description: ''
operationId: createUsersWithArrayInput
responses:
default:
description: successful operation
security:
- api_key: []
requestBody:
$ref: '#/components/requestBodies/UserArray'
/user/createWithList:
post:
tags:
- user
summary: Creates list of users with given input array
description: ''
operationId: createUsersWithListInput
responses:
default:
description: successful operation
security:
- api_key: []
requestBody:
$ref: '#/components/requestBodies/UserArray'
/user/login:
get:
tags:
- user
summary: Logs user into the system
description: ''
operationId: loginUser
parameters:
- name: username
in: query
description: The user name for login
required: true
schema:
type: string
pattern: '^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$'
- name: password
in: query
description: The password for login in clear text
required: true
schema:
type: string
responses:
'200':
description: successful operation
headers:
Set-Cookie:
description: >-
Cookie authentication key for use with the `api_key`
apiKey authentication.
schema:
type: string
example: AUTH_KEY=abcde12345; Path=/; HttpOnly
X-Rate-Limit:
description: calls per hour allowed by the user
schema:
type: integer
format: int32
X-Expires-After:
description: date in UTC when token expires
schema:
type: string
format: date-time
content:
application/xml:
schema:
type: string
application/json:
schema:
type: string
'400':
description: Invalid username/password supplied
/user/logout:
get:
tags:
- user
summary: Logs out current logged in user session
description: ''
operationId: logoutUser
responses:
default:
description: successful operation
security:
- api_key: []
'/user/{username}':
get:
tags:
- user
summary: Get user by user name
description: ''
operationId: getUserByName
parameters:
- name: username
in: path
description: The name that needs to be fetched. Use user1 for testing.
required: true
schema:
type: string
responses:
'200':
description: successful operation
content:
application/xml:
schema:
$ref: '#/components/schemas/User'
application/json:
schema:
$ref: '#/components/schemas/User'
'400':
description: Invalid username supplied
'404':
description: User not found
put:
tags:
- user
summary: Updated user
description: This can only be done by the logged in user.
operationId: updateUser
parameters:
- name: username
in: path
description: name that need to be deleted
required: true
schema:
type: string
responses:
'400':
description: Invalid user supplied
'404':
description: User not found
security:
- api_key: []
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/User'
description: Updated user object
required: true
delete:
tags:
- user
summary: Delete user
description: This can only be done by the logged in user.
operationId: deleteUser
parameters:
- name: username
in: path
description: The name that needs to be deleted
required: true
schema:
type: string
responses:
'400':
description: Invalid username supplied
'404':
description: User not found
security:
- api_key: []
externalDocs:
description: Find out more about Swagger
url: 'http://swagger.io'
components:
requestBodies:
UserArray:
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/User'
description: List of user object
required: true
Pet:
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
application/xml:
schema:
$ref: '#/components/schemas/Pet'
description: Pet object that needs to be added to the store
required: true
securitySchemes:
petstore_auth:
type: oauth2
flows:
implicit:
authorizationUrl: 'http://petstore.swagger.io/api/oauth/dialog'
scopes:
'write:pets': modify pets in your account
'read:pets': read your pets
api_key:
type: apiKey
name: api_key
in: header
schemas:
Order:
title: Pet Order
description: An order for a pets from the pet store
type: object
properties:
id:
type: integer
format: int64
petId:
type: integer
format: int64
quantity:
type: integer
format: int32
shipDate:
type: string
format: date-time
status:
type: string
description: Order Status
enum:
- placed
- approved
- delivered
complete:
type: boolean
default: false
xml:
name: Order
Category:
title: Pet category
description: A category for a pet
type: object
properties:
id:
type: integer
format: int64
name:
type: string
pattern: '^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$'
xml:
name: Category
User:
title: a User
description: A User who is purchasing from the pet store
type: object
properties:
id:
type: integer
format: int64
username:
type: string
firstName:
type: string
lastName:
type: string
email:
type: string
password:
type: string
phone:
type: string
userStatus:
type: integer
format: int32
description: User Status
xml:
name: User
Tag:
title: Pet Tag
description: A tag for a pet
type: object
properties:
id:
type: integer
format: int64
name:
type: string
xml:
name: Tag
Pet:
title: a Pet
description: A pet for sale in the pet store
type: object
required:
- name
- photoUrls
properties:
id:
type: integer
format: int64
category:
$ref: '#/components/schemas/Category'
name:
type: string
example: doggie
photoUrls:
type: array
xml:
name: photoUrl
wrapped: true
items:
type: string
tags:
type: array
xml:
name: tag
wrapped: true
items:
$ref: '#/components/schemas/Tag'
status:
type: string
description: pet status in the store
deprecated: true
enum:
- available
- pending
- sold
xml:
name: Pet
ApiResponse:
title: An uploaded response
description: Describes the result of uploading an image resource
type: object
properties:
code:
type: integer
format: int32
type:
type: string
message:
type: string
another_model:
description: to test mapping features
type: object
properties:
another_property:
type: integer
format: int32

View File

@ -1,6 +1,7 @@
README.md
docs/ApiResponse.md
docs/Category.md
docs/MappedModel.md
docs/Order.md
docs/Pet.md
docs/PetApi.md
@ -15,6 +16,7 @@ src/apis/api_UserApi.jl
src/modelincludes.jl
src/models/model_ApiResponse.jl
src/models/model_Category.jl
src/models/model_MappedModel.jl
src/models/model_Order.jl
src/models/model_Pet.jl
src/models/model_Tag.jl

View File

@ -46,6 +46,7 @@ Class | Method
- [ApiResponse](docs/ApiResponse.md)
- [Category](docs/Category.md)
- [MappedModel](docs/MappedModel.md)
- [Order](docs/Order.md)
- [Pet](docs/Pet.md)
- [Tag](docs/Tag.md)

View File

@ -0,0 +1,12 @@
# MappedModel
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**mappedProperty** | **Int64** | | [optional] [default to nothing]
[[Back to Model list]](../README.md#models) [[Back to API list]](../README.md#api-endpoints) [[Back to README]](../README.md)

View File

@ -18,6 +18,7 @@ include("apis/api_UserApi.jl")
# export models
export ApiResponse
export Category
export MappedModel
export Order
export Pet
export Tag

View File

@ -3,6 +3,7 @@
include("models/model_ApiResponse.jl")
include("models/model_Category.jl")
include("models/model_MappedModel.jl")
include("models/model_Order.jl")
include("models/model_Pet.jl")
include("models/model_Tag.jl")

View File

@ -0,0 +1,34 @@
# This file was generated by the Julia OpenAPI Code Generator
# Do not modify this file directly. Modify the OpenAPI specification instead.
@doc raw"""another_model
to test mapping features
MappedModel(;
mappedProperty=nothing,
)
- mappedProperty::Int64
"""
Base.@kwdef mutable struct MappedModel <: OpenAPI.APIModel
mappedProperty::Union{Nothing, Int64} = nothing
function MappedModel(mappedProperty, )
OpenAPI.validate_property(MappedModel, Symbol("another_property"), mappedProperty)
return new(mappedProperty, )
end
end # type MappedModel
const _property_types_MappedModel = Dict{Symbol,String}(Symbol("another_property")=>"Int64", )
OpenAPI.property_type(::Type{ MappedModel }, name::Symbol) = Union{Nothing,eval(Base.Meta.parse(_property_types_MappedModel[name]))}
function check_required(o::MappedModel)
true
end
function OpenAPI.validate_property(::Type{ MappedModel }, name::Symbol, val)
if name === Symbol("another_property")
OpenAPI.validate_param(name, "MappedModel", :format, val, "int32")
end
end

View File

@ -1,4 +1,5 @@
README.md
docs/AnotherModel.md
docs/ApiResponse.md
docs/Category.md
docs/Order.md
@ -13,6 +14,7 @@ src/apis/api_PetApi.jl
src/apis/api_StoreApi.jl
src/apis/api_UserApi.jl
src/modelincludes.jl
src/models/model_AnotherModel.jl
src/models/model_ApiResponse.jl
src/models/model_Category.jl
src/models/model_Order.jl

View File

@ -66,6 +66,7 @@ Class | Method | HTTP request | Description
## Models
- [AnotherModel](docs/AnotherModel.md)
- [ApiResponse](docs/ApiResponse.md)
- [Category](docs/Category.md)
- [Order](docs/Order.md)

View File

@ -0,0 +1,12 @@
# AnotherModel
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**another_property** | **Int64** | | [optional] [default to nothing]
[[Back to Model list]](../README.md#models) [[Back to API list]](../README.md#api-endpoints) [[Back to README]](../README.md)

View File

@ -113,6 +113,7 @@ function register(router::HTTP.Router, impl; path_prefix::String="", optional_mi
end
# export models
export AnotherModel
export ApiResponse
export Category
export Order

View File

@ -1,6 +1,7 @@
# This file was generated by the Julia OpenAPI Code Generator
# Do not modify this file directly. Modify the OpenAPI specification instead.
include("models/model_AnotherModel.jl")
include("models/model_ApiResponse.jl")
include("models/model_Category.jl")
include("models/model_Order.jl")

View File

@ -0,0 +1,34 @@
# This file was generated by the Julia OpenAPI Code Generator
# Do not modify this file directly. Modify the OpenAPI specification instead.
@doc raw"""another_model
to test mapping features
AnotherModel(;
another_property=nothing,
)
- another_property::Int64
"""
Base.@kwdef mutable struct AnotherModel <: OpenAPI.APIModel
another_property::Union{Nothing, Int64} = nothing
function AnotherModel(another_property, )
OpenAPI.validate_property(AnotherModel, Symbol("another_property"), another_property)
return new(another_property, )
end
end # type AnotherModel
const _property_types_AnotherModel = Dict{Symbol,String}(Symbol("another_property")=>"Int64", )
OpenAPI.property_type(::Type{ AnotherModel }, name::Symbol) = Union{Nothing,eval(Base.Meta.parse(_property_types_AnotherModel[name]))}
function check_required(o::AnotherModel)
true
end
function OpenAPI.validate_property(::Type{ AnotherModel }, name::Symbol, val)
if name === Symbol("another_property")
OpenAPI.validate_param(name, "AnotherModel", :format, val, "int32")
end
end