Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 60 additions & 4 deletions src/oatpp-swagger/Generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ oatpp::Fields<Object<oas3::OperationResponse>> Generator::generateResponses(cons

}

void Generator::generatePathItemData(const std::shared_ptr<Endpoint>& endpoint, const oatpp::Object<oas3::PathItem>& pathItem, UsedTypes& usedTypes, UsedSecuritySchemes &usedSecuritySchemes) {
void Generator::generatePathItemData(const std::shared_ptr<Endpoint>& endpoint, const oatpp::Object<oas3::PathItem>& pathItem, UsedTypes& usedTypes, UsedSecuritySchemes &usedSecuritySchemes, UsedTags &usedTags) {

auto info = endpoint->info();

Expand All @@ -389,6 +389,7 @@ void Generator::generatePathItemData(const std::shared_ptr<Endpoint>& endpoint,
operation->tags = oatpp::List<String>({});
for(auto& tag : info->tags) {
operation->tags->push_back(tag);
usedTags[tag] = true;
}
}

Expand Down Expand Up @@ -471,7 +472,7 @@ void Generator::generatePathItemData(const std::shared_ptr<Endpoint>& endpoint,
}
}

Generator::Paths Generator::generatePaths(const Endpoints& endpoints, UsedTypes& usedTypes, UsedSecuritySchemes &usedSecuritySchemes) {
Generator::Paths Generator::generatePaths(const Endpoints& endpoints, UsedTypes& usedTypes, UsedSecuritySchemes &usedSecuritySchemes, UsedTags &usedTags) {

auto result = Paths::createShared();

Expand All @@ -490,7 +491,7 @@ Generator::Paths Generator::generatePaths(const Endpoints& endpoints, UsedTypes&
pathItem = oas3::PathItem::createShared();
}

generatePathItemData(endpoint, pathItem, usedTypes, usedSecuritySchemes);
generatePathItemData(endpoint, pathItem, usedTypes, usedSecuritySchemes, usedTags);
}
}

Expand Down Expand Up @@ -603,6 +604,54 @@ oatpp::Object<oas3::Components> Generator::generateComponents(const UsedTypes &d

}

Generator::Tags Generator::generateTags(const std::shared_ptr<std::list<std::shared_ptr<oatpp::swagger::Tag>>> &tags,
const UsedTags &usedTags) {
auto result = Tags::createShared();

UsedTags missingTags{ usedTags};

if (tags) {
for (const auto &tag : *tags) {
if (!tag || !tag->name) {
continue;
}

if ( usedTags.find(tag->name)== usedTags.end()) {
continue;
}

missingTags.erase(tag->name);

auto oasTagItem = oatpp::swagger::oas3::TagItem::createShared();
oasTagItem->name = tag->name;
oasTagItem->description = tag->description;
if (tag->externalDocs) {
oasTagItem->externalDocs = generateExternalDocs(*tag->externalDocs);
}

result->push_back(oasTagItem);
}
}

// Add placeholder tags that where discovered but were missing in the declaration.
for (const auto &missingTag : missingTags) {
auto oasTagItem = oatpp::swagger::oas3::TagItem::createShared();
oasTagItem->name = missingTag.first;
result->push_back(oasTagItem);
}

return result;
}

oatpp::Object<oas3::ExternalDocumentation> Generator::generateExternalDocs(const ExternalDocumentation &externalDocs) {

auto oasExternalDocumentation = oatpp::swagger::oas3::ExternalDocumentation::createShared();
oasExternalDocumentation->url = externalDocs.url;
oasExternalDocumentation->description = externalDocs.description;

return oasExternalDocumentation;
}


oatpp::Object<oas3::SecurityScheme> Generator::generateSecurityScheme(const std::shared_ptr<oatpp::swagger::SecurityScheme> &ss) {
auto oasSS = oatpp::swagger::oas3::SecurityScheme::createShared();
Expand Down Expand Up @@ -687,9 +736,16 @@ oatpp::Object<oas3::Document> Generator::generateDocument(const std::shared_ptr<

}

if (docInfo->externalDocs) {
document->externalDocs = generateExternalDocs(*docInfo->externalDocs);
}

UsedTypes usedTypes;
UsedSecuritySchemes usedSecuritySchemes;
document->paths = generatePaths(endpoints, usedTypes, usedSecuritySchemes);
UsedTags usedTags;

document->paths = generatePaths(endpoints, usedTypes, usedSecuritySchemes, usedTags);
document->tags = generateTags(docInfo->tags, usedTags);
auto decomposedTypes = decomposeTypes(usedTypes);
document->components = generateComponents(decomposedTypes, docInfo->securitySchemes, usedSecuritySchemes);

Expand Down
13 changes: 11 additions & 2 deletions src/oatpp-swagger/Generator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ class Generator {

typedef std::unordered_map<oatpp::String, bool> UsedSecuritySchemes;

typedef std::unordered_map<oatpp::String, bool> UsedTags;

typedef oatpp::List<Object<oas3::TagItem>> Tags;

private:
void addParamsToParametersList(const PathItemParameters& paramsList,
Endpoint::Info::Params& params,
Expand All @@ -76,12 +80,12 @@ class Generator {

oatpp::Object<oas3::RequestBody> generateRequestBody(const Endpoint::Info& endpointInfo, bool linkSchema, UsedTypes& usedTypes);
Fields<Object<oas3::OperationResponse>> generateResponses(const Endpoint::Info& endpointInfo, bool linkSchema, UsedTypes& usedTypes);
void generatePathItemData(const std::shared_ptr<Endpoint>& endpoint, const oatpp::Object<oas3::PathItem>& pathItem, UsedTypes& usedTypes, UsedSecuritySchemes &usedSecuritySchemes);
void generatePathItemData(const std::shared_ptr<Endpoint>& endpoint, const oatpp::Object<oas3::PathItem>& pathItem, UsedTypes& usedTypes, UsedSecuritySchemes &usedSecuritySchemes, UsedTags &usedTags);

/*
* UsedTypes& usedTypes is used to put Types of objects whos schema should be reused
*/
Paths generatePaths(const Endpoints& endpoints, UsedTypes& usedTypes, UsedSecuritySchemes &usedSecuritySchemes);
Paths generatePaths(const Endpoints& endpoints, UsedTypes& usedTypes, UsedSecuritySchemes &usedSecuritySchemes, UsedTags &usedTags);

oatpp::Object<oas3::SecurityScheme> generateSecurityScheme(const std::shared_ptr<oatpp::swagger::SecurityScheme> &ss);

Expand All @@ -96,6 +100,11 @@ class Generator {
const std::shared_ptr<std::unordered_map<oatpp::String,std::shared_ptr<oatpp::swagger::SecurityScheme>>> &securitySchemes,
UsedSecuritySchemes &usedSecuritySchemes);

Tags generateTags(const std::shared_ptr<std::list<std::shared_ptr<oatpp::swagger::Tag>>> &tags,
const UsedTags &usedTags);

oatpp::Object<oas3::ExternalDocumentation> generateExternalDocs(const ExternalDocumentation &externalDocs);

public:

struct Config {
Expand Down
117 changes: 117 additions & 0 deletions src/oatpp-swagger/Model.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,52 @@ struct SecurityScheme {

};

/**
* External documentation object - https://swagger.io/specification/#external-documentation-object .
*/

struct ExternalDocumentation {

static std::shared_ptr<ExternalDocumentation> createShared() {
return std::make_shared<ExternalDocumentation>();
}

/**
* Description
*/
oatpp::String description;

/**
* Url
*/
oatpp::String url;
};

/**
* Tag object - https://swagger.io/specification/#tag-object .
*/
struct Tag {

static std::shared_ptr<Tag> createShared() {
return std::make_shared<Tag>();
}

/**
* Name
*/
oatpp::String name;

/**
* Description
*/
oatpp::String description;

/**
* External Documentation
*/
std::shared_ptr<ExternalDocumentation> externalDocs;
};

/**
* Document Info.
*/
Expand Down Expand Up @@ -334,6 +380,16 @@ class DocumentInfo {
*/
std::shared_ptr<std::unordered_map<oatpp::String, std::shared_ptr<SecurityScheme>>> securitySchemes;

/**
* List of &l:Tag;.
*/
std::shared_ptr<std::list<std::shared_ptr<Tag>>> tags;

/**
* &l:ExternalDocumentation;.
*/
std::shared_ptr<ExternalDocumentation> externalDocs;

/**
* SecurityScheme Builder.
*/
Expand Down Expand Up @@ -604,6 +660,8 @@ class DocumentInfo {
std::shared_ptr<DocumentHeader> m_header;
std::shared_ptr<std::list<std::shared_ptr<Server>>> m_servers;
std::shared_ptr<std::unordered_map<oatpp::String, std::shared_ptr<SecurityScheme>>> m_securitySchemes;
std::shared_ptr<ExternalDocumentation> m_externalDocs;
std::shared_ptr<std::list<std::shared_ptr<Tag>>> m_tags;

private:

Expand Down Expand Up @@ -637,6 +695,21 @@ class DocumentInfo {
return m_securitySchemes;
}

std::shared_ptr<ExternalDocumentation> getExternalDocs() {
if(!m_externalDocs) {
m_externalDocs = ExternalDocumentation::createShared();
}
return m_externalDocs;
}

std::shared_ptr<std::list<std::shared_ptr<Tag>>> getTags() {
if (!m_tags)
{
m_tags = std::make_shared<std::list<std::shared_ptr<Tag>>>();
}
return m_tags;
}

public:

/**
Expand Down Expand Up @@ -719,6 +792,11 @@ class DocumentInfo {
return *this;
}

Builder& setExternalDocs(const oatpp::String &url, const oatpp::String &description) {
getExternalDocs()->url = url;
getExternalDocs()->description = description;
return *this;
}
/**
* Set license url.
* @param url
Expand Down Expand Up @@ -770,6 +848,43 @@ class DocumentInfo {
return *this;
}

/**
* Add &l:Tag.
* @param name
* @param description
* @return - &l:DocumentInfo::Builder;.
*/
Builder& addTag(const oatpp::String& name, const oatpp::String& description) {
auto tag = Tag::createShared();
tag->name = name;
tag->description = description;

getTags()->push_back(tag);
return *this;
}

/**
* Add &l:ExternalDocumentation to &l:Tag
* @param tagname
* @param description
* @param url
* @return - &l:DocumentInfo::Builder;.
*/
Builder& setExternalDocsForTag(const oatpp::String& tagName, const oatpp::String& url, const oatpp::String& description ) {

for (auto tag : *getTags())
{
if (tag->name == tagName)
{
tag->externalDocs = ExternalDocumentation::createShared();
tag->externalDocs->url = url;
tag->externalDocs->description = description;
break;
}
}
return *this;
}

/**
* Build Document Info.
* @return - &l:DocumentInfo;.
Expand All @@ -779,6 +894,8 @@ class DocumentInfo {
document->header = m_header;
document->servers = m_servers;
document->securitySchemes = m_securitySchemes;
document->tags = m_tags;
document->externalDocs = m_externalDocs;
return document;
}

Expand Down
Loading