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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
### Deprecated
### Removed
### Fixed
- Autoexposed `.texts` entities are now excluded from OpenAPI document

### Security

## [1.3.1] - 2026-01-08
Expand Down
15 changes: 13 additions & 2 deletions lib/compile/csdl2openapi.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
// - system query options for actions/functions/imports depending on $Collection
// - 200 response for PATCH
// - ETag for GET / If-Match for PATCH and DELETE depending on @Core.OptimisticConcurrency
// - CountRestrictions for GET collection-valued (containment) navigation - https://issues.oasis-open.org/browse/ODATA-1300

Check warning on line 22 in lib/compile/csdl2openapi.js

View workflow job for this annotation

GitHub Actions / lint

This line has a length of 123. Maximum allowed is 120

Check warning on line 22 in lib/compile/csdl2openapi.js

View workflow job for this annotation

GitHub Actions / Node.js 24

This line has a length of 123. Maximum allowed is 120

Check warning on line 22 in lib/compile/csdl2openapi.js

View workflow job for this annotation

GitHub Actions / Node.js 20

This line has a length of 123. Maximum allowed is 120
// - InsertRestrictions/NonInsertableProperties
// - InsertRestrictions/NonInsertableNavigationProperties
// - see //TODO comments below
Expand Down Expand Up @@ -87,10 +87,10 @@
/**
* Construct an OpenAPI description from a CSDL document
* @param {CSDL} csdl CSDL document
* @param {{ url?: string, servers?: object, odataVersion?: string, scheme?: string, host?: string, basePath?: string, diagram?: boolean, maxLevels?: number }} options Optional parameters

Check warning on line 90 in lib/compile/csdl2openapi.js

View workflow job for this annotation

GitHub Actions / lint

This line has a length of 187. Maximum allowed is 120

Check warning on line 90 in lib/compile/csdl2openapi.js

View workflow job for this annotation

GitHub Actions / Node.js 24

This line has a length of 187. Maximum allowed is 120

Check warning on line 90 in lib/compile/csdl2openapi.js

View workflow job for this annotation

GitHub Actions / Node.js 20

This line has a length of 187. Maximum allowed is 120
* @return {object} OpenAPI description
*/
module.exports.csdl2openapi = function (

Check warning on line 93 in lib/compile/csdl2openapi.js

View workflow job for this annotation

GitHub Actions / lint

Function has a complexity of 20. Maximum allowed is 15

Check warning on line 93 in lib/compile/csdl2openapi.js

View workflow job for this annotation

GitHub Actions / Node.js 24

Function has a complexity of 20. Maximum allowed is 15

Check warning on line 93 in lib/compile/csdl2openapi.js

View workflow job for this annotation

GitHub Actions / Node.js 20

Function has a complexity of 20. Maximum allowed is 15
csdl,
{
url: serviceRoot,
Expand All @@ -104,10 +104,10 @@
} = {}
) {
// as preProcess below mutates the csdl, copy it before, to avoid side-effects on the caller side
csdl = JSON.parse(JSON.stringify(csdl))

Check warning on line 107 in lib/compile/csdl2openapi.js

View workflow job for this annotation

GitHub Actions / lint

Assignment to function parameter 'csdl'

Check warning on line 107 in lib/compile/csdl2openapi.js

View workflow job for this annotation

GitHub Actions / Node.js 24

Assignment to function parameter 'csdl'

Check warning on line 107 in lib/compile/csdl2openapi.js

View workflow job for this annotation

GitHub Actions / Node.js 20

Assignment to function parameter 'csdl'
csdl.$Version = odataVersion ? odataVersion : '4.01'
const meta = new CSDLMeta(csdl)
serviceRoot = serviceRoot ?? (`${scheme}://${host}${basePath}`);

Check warning on line 110 in lib/compile/csdl2openapi.js

View workflow job for this annotation

GitHub Actions / lint

Assignment to function parameter 'serviceRoot'

Check warning on line 110 in lib/compile/csdl2openapi.js

View workflow job for this annotation

GitHub Actions / Node.js 24

Assignment to function parameter 'serviceRoot'

Check warning on line 110 in lib/compile/csdl2openapi.js

View workflow job for this annotation

GitHub Actions / Node.js 20

Assignment to function parameter 'serviceRoot'
const queryOptionPrefix = csdl.$Version <= '4.01' ? '$' : '';
const typesToInline = {}; // filled in schema() and used in inlineTypes()

Expand All @@ -119,9 +119,14 @@
const serviceName = nameParts(csdl.$EntityContainer).qualifier;
Object.keys(entityContainer).forEach(element => {
if (entityContainer[element].$Type) {
const type = nameParts(entityContainer[element].$Type).name;
if ((csdl[serviceName]?.[type]?.['@cds.autoexpose'] || csdl[serviceName]?.[type]?.['@cds.autoexposed']) && !entityContainer[type])
const fullTypeName = entityContainer[element].$Type;
const type = fullTypeName.startsWith(serviceName + '.')
? fullTypeName.substring(serviceName.length + 1)
: nameParts(fullTypeName).name;
if ((csdl[serviceName]?.[type]?.['@cds.autoexpose'] || csdl[serviceName]?.[type]?.['@cds.autoexposed'])
&& (!entityContainer[type] || type.endsWith('_texts'))) {
entityContainer[element]['$cds.autoexpose'] = true;
}
}
});
}
Expand Down Expand Up @@ -374,6 +379,9 @@
Object.keys(container)
.filter(name => isIdentifier(name) && container[name].$Type)
.forEach(child => {
if (child.endsWith('_texts') && container[child]['$cds.autoexpose']) {
return;
}
const type = meta.modelElement(container[child].$Type) || {};
const tag = {
name: type[meta.voc.Common.Label] || child
Expand Down Expand Up @@ -416,6 +424,9 @@
const resources = Object.keys(container).filter(name => isIdentifier(name));
resources.forEach(name => {
const child = container[name];
if (name.endsWith('_texts') && child['$cds.autoexpose']) {
return;
}
if (child.$Type) {
const type = meta.modelElement(child.$Type);
const sourceName = (type && type[meta.voc.Common.Label]) || name;
Expand Down
8 changes: 8 additions & 0 deletions test/lib/compile/csdl2openapi.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ const result10 = require("./data/immutable-composition.openapi3.json");
const example11 = require("./data/description-fallback.json");
const result11 = require("./data/description-fallback.openapi3.json");

const example12 = require("./data/autoexposed-texts.json");
const result12 = require("./data/autoexposed-texts.openapi3.json");

describe("Examples", () => {
test("csdl-16.1", () => {
const openapi = lib.csdl2openapi(example1, { diagram: true });
Expand Down Expand Up @@ -95,6 +98,11 @@ describe("Examples", () => {
const openapi = lib.csdl2openapi(example11, { diagram: true });
check(openapi, result11);
});

test("autoexposed-texts", () => {
const openapi = lib.csdl2openapi(example12);
check(openapi, result12);
});
});

describe("Edge cases", () => {
Expand Down
37 changes: 37 additions & 0 deletions test/lib/compile/data/autoexposed-texts.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"$Version": "4.01",
"$EntityContainer": "AdminService.EntityContainer",
"$Reference": {},
"AdminService": {
"$Kind": "Schema",
"EntityContainer": {
"$Kind": "EntityContainer",
"Books": {
"$Collection": true,
"$Type": "AdminService.Books"
},
"Books_texts": {
"$Collection": true,
"$Type": "AdminService.Books_texts"
}
},
"Books": {
"$Kind": "EntityType",
"$Key": ["ID"],
"ID": {
"$Type": "Edm.Int32"
}
},
"Books_texts": {
"$Kind": "EntityType",
"$Key": ["locale", "ID"],
"@cds.autoexposed": true,
"locale": {
"$MaxLength": 14
},
"ID": {
"$Type": "Edm.Int32"
}
}
}
}
Loading
Loading