diff --git a/CHANGELOG.md b/CHANGELOG.md index ae70785..c187501 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/). ## Version 1.0.7 - 17.10.2024 +### Fixed + +- Removed duplicates in `tags`. + + ### Fixed - Multiple protocols for a service now renders multiple openapi documents. diff --git a/lib/compile/csdl2openapi.js b/lib/compile/csdl2openapi.js index 1968066..aa36c96 100644 --- a/lib/compile/csdl2openapi.js +++ b/lib/compile/csdl2openapi.js @@ -549,18 +549,20 @@ module.exports.csdl2openapi = function ( * @return {Array} The list of tags */ function getTags(container) { - const tags = []; - // all entity sets and singletons - Object.keys(container).filter(name => isIdentifier(name) && container[name].$Type).forEach(child => { - const type = modelElement(container[child].$Type) || {}; - const tag = { - name: type[voc.Common.Label] || child - }; - const description = container[child][voc.Core.Description] || type[voc.Core.Description]; - if (description) tag.description = description; - tags.push(tag); - }) - return tags.sort(function (pre, next) { return pre.name.localeCompare(next.name) }); + const tags = new Map(); + // all entity sets and singletons + Object.keys(container) + .filter(name => isIdentifier(name) && container[name].$Type) + .forEach(child => { + const type = modelElement(container[child].$Type) || {}; + const tag = { + name: type[voc.Common.Label] || child + }; + const description = container[child][voc.Core.Description] || type[voc.Core.Description]; + if (description) tag.description = description; + tags.set(tag.name, tag); + }); + return Array.from(tags.values()).sort((pre, next) => pre.name.localeCompare(next.name)); } /** diff --git a/test/lib/compile/csdl2openapi.test.js b/test/lib/compile/csdl2openapi.test.js index 8aec582..53594f3 100644 --- a/test/lib/compile/csdl2openapi.test.js +++ b/test/lib/compile/csdl2openapi.test.js @@ -101,8 +101,8 @@ describe('Edge cases', function () { }; const openapi = lib.csdl2openapi(csdl, {}); assert.deepStrictEqual(openapi, expected, 'Empty CSDL document'); - }) - + }); + it('omit unused types', function () { const csdl = { $Reference: { dummy: { '$Include': [{ '$Namespace': 'Org.OData.Core.V1', '$Alias': 'Core' }] } }, diff --git a/test/lib/compile/openapi.test.js b/test/lib/compile/openapi.test.js index 6f330cc..629c3e9 100644 --- a/test/lib/compile/openapi.test.js +++ b/test/lib/compile/openapi.test.js @@ -117,6 +117,39 @@ describe('OpenAPI export', () => { expect(filesFound).toMatchObject(new Set(['.odata', '.rest'])); }); + test('Check for tags object having any duplicate entries ', () => { + const csn = cds.compile.to.csn(` + namespace my.sample; +service CatalogService { + + @title: 'Auditable Fields' + aspect Auditable { + createdAt : Timestamp; + createdBy : String; + modifiedAt : Timestamp; + modifiedBy : String; + } + entity Products : Auditable { + key ID : UUID; + name : String; + description : String; + price : Decimal(10, 2); + } + entity Orders : Auditable { + key ID : UUID; + orderDate : Date; + totalAmount : Decimal(10, 2); + product : Association to Products; + } + +} + `); + + const openAPI = toOpenApi(csn); + expect(openAPI).toBeDefined(); + expect(openAPI.tags.length).toBe(1); + }); + test('multiple services', () => { const csn = cds.compile.to.csn(` service A {entity E { key ID : UUID; };};