Skip to content
Merged
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
- Back-reference navigation properties on child entities in compositions (the generated `parent` nav pointing back up) are no longer emitted in the OpenAPI read schema
- Implicitly auto-exposed composition targets (annotated `@cds.autoexposed` by the CDS compiler) no longer generate top-level GET paths that CAP would reject with 405
- OpenAPI compilation is now pure: the input CSN is no longer mutated during compilation
- Services annotated with `@protocol: 'rest'` no longer include a `/$batch` path in the generated OpenAPI document
### Security

## [1.6.0] - 2026-08-04
Expand Down
7 changes: 5 additions & 2 deletions lib/compile/csdl2openapi.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ const propertyUtil = require('./property-util');
const pluralize = require('pluralize')
const DEBUG = cds.debug('openapi'); // Initialize cds.debug with the 'openapi'

const isODataProtocol = (protocol) => !protocol || protocol.startsWith('odata');

//TODO
// - Core.Example for complex types
// - reduce number of loops over schemas
Expand Down Expand Up @@ -122,7 +124,7 @@ function normalizeDiagramFlag(diagram) {
/**
* 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, shortActionPaths?: boolean }} options Optional parameters
* @param {{ url?: string, servers?: object, odataVersion?: string, protocol?: string, scheme?: string, host?: string, basePath?: string, diagram?: boolean, maxLevels?: number, shortActionPaths?: boolean }} options Optional parameters
* @return {*} OpenAPI description
*/
module.exports.csdl2openapi = function (
Expand All @@ -131,6 +133,7 @@ module.exports.csdl2openapi = function (
url: serviceRoot,
servers: serversObject,
odataVersion,
protocol,
scheme = 'https',
host = 'localhost',
basePath = '/service-root',
Expand Down Expand Up @@ -511,7 +514,7 @@ module.exports.csdl2openapi = function (
DEBUG?.(`Unrecognized entity container child: ${name}`);
}
})
if (resources.length > 0) pathItemBatch(paths, container);
if (resources.length > 0 && isODataProtocol(protocol)) pathItemBatch(paths, container);
return Object.keys(paths).sort().reduce((p, c) => (p[c] = paths[c], p), {});
}

Expand Down
1 change: 1 addition & 0 deletions lib/compile/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ function _getOpenApi(csdl, options, serviceName = "") {
}

sOptions.url = url;
sOptions.protocol = protocol;

const openapi = csdl2openapi.csdl2openapi(csdl, sOptions);

Expand Down
13 changes: 13 additions & 0 deletions test/lib/compile/openapi.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,19 @@ service CatalogService {
'@protocol must not be mutated by toOpenApi');
});

test('REST service does not include /$batch path', () => {
const csn = cds.compile.to.csn(`
@path: '/rest/v1/myRestAPI'
@protocol: 'rest'
service MyRestAPI {
entity Items { key ID : UUID; }
}`
);
const openapi = toOpenApi(csn);
assert.strictEqual(openapi.paths?.['/$batch'], undefined,
'/$batch must not be present in OpenAPI output for a REST service');
});

test('options: Multiple servers', () => {
const csn = cds.compile.to.csn(`
service A {entity E { key ID : UUID; };};`
Expand Down
Loading