@cap-js/ord 1.5.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cds-plugin.js +4 -14
- package/lib/auth/mtls-endpoint-service.js +1 -1
- package/lib/build.js +2 -7
- package/lib/common/register-compile-targets.js +31 -0
- package/lib/{extendOrdWithCustom.js → extend-ord-with-custom.js} +2 -8
- package/lib/index.js +1 -1
- package/lib/{interopCsn.js → interop-csn.js} +3 -3
- package/lib/meta-data.js +90 -0
- package/lib/ord.js +12 -4
- package/lib/services/mtx-ord-provider-service.cds +21 -0
- package/lib/services/mtx-ord-provider-service.js +39 -0
- package/lib/{ord-service.js → services/ord-service.js} +15 -6
- package/lib/threads/compile.js +4 -1
- package/package.json +10 -5
- package/lib/metaData.js +0 -108
- /package/lib/{integrationDependency.js → integration-dependency.js} +0 -0
- /package/lib/{ord-service.cds → services/ord-service.cds} +0 -0
package/cds-plugin.js
CHANGED
|
@@ -4,17 +4,7 @@ if (cds.cli.command === "build") {
|
|
|
4
4
|
cds.build?.register?.("ord", require("./lib/build"));
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const registerORDCompileTarget = () => {
|
|
14
|
-
Object.defineProperty(cds.compile.to, "ord", {
|
|
15
|
-
get: _lazyRegisterCompileTarget,
|
|
16
|
-
configurable: true,
|
|
17
|
-
});
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
registerORDCompileTarget();
|
|
7
|
+
Object.defineProperty(cds.compile.to, "ord", {
|
|
8
|
+
configurable: true,
|
|
9
|
+
get: () => (model) => require("./lib/index").ord(model, []),
|
|
10
|
+
});
|
package/lib/build.js
CHANGED
|
@@ -6,6 +6,7 @@ const cliProgress = require("cli-progress");
|
|
|
6
6
|
|
|
7
7
|
const os = require("os");
|
|
8
8
|
const { ord } = require("./index");
|
|
9
|
+
const registerCompileTargets = require("./common/register-compile-targets");
|
|
9
10
|
const { BUILD_DEFAULT_PATH, ORD_DOCUMENT_FILE_NAME } = require("./constants");
|
|
10
11
|
|
|
11
12
|
module.exports = class OrdBuildPlugin extends cds.build.Plugin {
|
|
@@ -16,13 +17,7 @@ module.exports = class OrdBuildPlugin extends cds.build.Plugin {
|
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
async build() {
|
|
19
|
-
|
|
20
|
-
// but cds build rebuilds cds.env afterward, losing both registrations.
|
|
21
|
-
// Re-apply so endpoints4() and cds.compile.to.graphql work during build.
|
|
22
|
-
if ("@cap-js/graphql" in cds.env.plugins && !cds.env.protocols?.graphql) {
|
|
23
|
-
cds.env.protocols.graphql = { path: "/graphql", impl: "@cap-js/graphql" };
|
|
24
|
-
require("@cap-js/graphql/lib/api").registerCompileTargets();
|
|
25
|
-
}
|
|
20
|
+
registerCompileTargets();
|
|
26
21
|
|
|
27
22
|
return this.model()
|
|
28
23
|
.then((model) => ({ model, document: ord(model) }))
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const cds = require("@sap/cds");
|
|
2
|
+
const Logger = require("../logger");
|
|
3
|
+
|
|
4
|
+
const PROTOCOL_PROVIDERS = Object.freeze({
|
|
5
|
+
["@cap-js/mcp"]: "mcp",
|
|
6
|
+
["@cap-js/graphql"]: "graphql",
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
module.exports = () => {
|
|
10
|
+
// Plugins like @cap-js/mcp and @cap-js/graphql register protocols and compile targets
|
|
11
|
+
// at runtime via cds-plugin.js, but cds build rebuilds cds.env afterward, losing both
|
|
12
|
+
// registrations. Re-apply so that compilation works accordingly during build and runtime.
|
|
13
|
+
|
|
14
|
+
Object.keys(cds.env.plugins || {})
|
|
15
|
+
.filter((plugin) => plugin !== "@cap-js/ord")
|
|
16
|
+
.forEach((plugin) => {
|
|
17
|
+
try {
|
|
18
|
+
const protocol = PROTOCOL_PROVIDERS[plugin];
|
|
19
|
+
|
|
20
|
+
require(`${plugin}/lib/api`)?.registerCompileTargets?.();
|
|
21
|
+
cds.env.protocols = {
|
|
22
|
+
...cds.env.protocols,
|
|
23
|
+
...(!protocol || cds.env.protocols?.[protocol]
|
|
24
|
+
? {}
|
|
25
|
+
: { [protocol]: { path: `/${protocol}`, impl: plugin } }),
|
|
26
|
+
};
|
|
27
|
+
} catch (error) {
|
|
28
|
+
Logger.warn(`Failed to register compile targets for ${plugin}: ${error}`);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
};
|
|
@@ -62,13 +62,7 @@ function getCustomORDContent(appConfig) {
|
|
|
62
62
|
return require(pathToCustomORDContent);
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
function extendCustomORDContentIfExists(appConfig, ordContent) {
|
|
66
|
-
const customORDContent = getCustomORDContent(appConfig);
|
|
67
|
-
return customORDContent
|
|
68
|
-
? compareAndHandleCustomORDContentWithExistingContent(ordContent, customORDContent)
|
|
69
|
-
: ordContent;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
65
|
module.exports = {
|
|
73
|
-
|
|
66
|
+
getCustomORDContent,
|
|
67
|
+
compareAndHandleCustomORDContentWithExistingContent,
|
|
74
68
|
};
|
package/lib/index.js
CHANGED
|
@@ -73,7 +73,7 @@ function remove_localized_assoc(csn) {
|
|
|
73
73
|
// - name is "localized"
|
|
74
74
|
// - type is "cds.Association"
|
|
75
75
|
// - target name is source name + ".texts"
|
|
76
|
-
// - there is an ON condition
|
|
76
|
+
// - there is an ON condition
|
|
77
77
|
for (let n1 in csn.definitions) {
|
|
78
78
|
let def = csn.definitions[n1];
|
|
79
79
|
if (def.kind === "entity")
|
|
@@ -141,7 +141,7 @@ function add_meta_info(csn) {
|
|
|
141
141
|
for (let k in csn.meta) {
|
|
142
142
|
if (!["flavor", "document", "features"].includes(k) && !k.startsWith("__")) {
|
|
143
143
|
delete csn.meta[k];
|
|
144
|
-
}
|
|
144
|
+
}
|
|
145
145
|
}
|
|
146
146
|
csn.meta.flavor = "effective";
|
|
147
147
|
|
|
@@ -165,5 +165,5 @@ function add_meta_info(csn) {
|
|
|
165
165
|
}
|
|
166
166
|
|
|
167
167
|
module.exports = {
|
|
168
|
-
interopCSN
|
|
168
|
+
interopCSN
|
|
169
169
|
};
|
package/lib/meta-data.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
const path = require("path");
|
|
2
|
+
const cds = require("@sap/cds/lib");
|
|
3
|
+
const assert = require("node:assert");
|
|
4
|
+
const cdsc = require("@sap/cds-compiler/lib/main");
|
|
5
|
+
const { compile: openapi } = require("@cap-js/openapi");
|
|
6
|
+
const { compile: asyncapi } = require("@cap-js/asyncapi");
|
|
7
|
+
|
|
8
|
+
const Logger = require("./logger");
|
|
9
|
+
const { interopCSN } = require("./interop-csn.js");
|
|
10
|
+
const { COMPILER_TYPES, OPENAPI_SERVERS_ANNOTATION } = require("./constants");
|
|
11
|
+
|
|
12
|
+
function extractServiceName(url) {
|
|
13
|
+
return path.basename(url, ".json").split(".").slice(0, -1).join(".");
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function extractCompilerType(url) {
|
|
17
|
+
return path.basename(url, ".json").split(".").pop();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const compilers = Object.freeze({
|
|
21
|
+
[COMPILER_TYPES.csn]: function (csn, options) {
|
|
22
|
+
return {
|
|
23
|
+
contentType: "application/json",
|
|
24
|
+
response: interopCSN(
|
|
25
|
+
cdsc.for.effective(csn, { beta: { effectiveCsn: true }, effectiveServiceName: options.service }),
|
|
26
|
+
),
|
|
27
|
+
};
|
|
28
|
+
},
|
|
29
|
+
[COMPILER_TYPES.mcp]: async function (csn, options) {
|
|
30
|
+
return {
|
|
31
|
+
contentType: "application/json",
|
|
32
|
+
response: cds.compile(csn).to["mcp"]({ ...options, ...(cds.env.ord?.compileOptions?.mcp || {}) }),
|
|
33
|
+
};
|
|
34
|
+
},
|
|
35
|
+
[COMPILER_TYPES.oas3]: function (csn, options) {
|
|
36
|
+
// Check for service-level @OpenAPI.servers annotation
|
|
37
|
+
const servers = csn?.definitions?.[options.service]?.[OPENAPI_SERVERS_ANNOTATION];
|
|
38
|
+
const openapiOptions = { ...options, ...(cds.env?.ord?.compileOptions?.openapi || {}) };
|
|
39
|
+
|
|
40
|
+
// Service-level annotation takes precedence over global config
|
|
41
|
+
if (Array.isArray(servers) && servers.length) {
|
|
42
|
+
openapiOptions["openapi:servers"] = JSON.stringify(servers);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
contentType: "application/json",
|
|
47
|
+
response: openapi(csn, openapiOptions),
|
|
48
|
+
};
|
|
49
|
+
},
|
|
50
|
+
[COMPILER_TYPES.edmx]: function (csn, options) {
|
|
51
|
+
return {
|
|
52
|
+
contentType: "application/xml",
|
|
53
|
+
response: cds
|
|
54
|
+
.compile(csn)
|
|
55
|
+
.to["edmx"]({ ...options, ...(cds.env?.ord?.compileOptions?.edmx || {}) }),
|
|
56
|
+
};
|
|
57
|
+
},
|
|
58
|
+
[COMPILER_TYPES.graphql]: function (csn, options) {
|
|
59
|
+
const { generateSchema4 } = require("@cap-js/graphql/lib/schema");
|
|
60
|
+
const { printSchema, lexicographicSortSchema } = require("graphql");
|
|
61
|
+
const srv = new cds.ApplicationService(options.service, cds.linked(csn));
|
|
62
|
+
|
|
63
|
+
return {
|
|
64
|
+
contentType: "text/plain",
|
|
65
|
+
response: printSchema(lexicographicSortSchema(generateSchema4({ [options.service]: srv }))),
|
|
66
|
+
};
|
|
67
|
+
},
|
|
68
|
+
[COMPILER_TYPES.asyncapi2]: function (csn, options) {
|
|
69
|
+
return {
|
|
70
|
+
contentType: "application/json",
|
|
71
|
+
response: asyncapi(csn, { ...options, ...(cds.env?.ord?.compileOptions?.asyncapi || {}) }),
|
|
72
|
+
};
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
module.exports = async (url, model = null) => {
|
|
77
|
+
const name = extractServiceName(url);
|
|
78
|
+
const type = extractCompilerType(url);
|
|
79
|
+
const csn = model || cds.services[name]?.model;
|
|
80
|
+
const options = { service: name, as: "str", messages: [] };
|
|
81
|
+
|
|
82
|
+
assert(Object.hasOwn(compilers, type), `Unsupported format: ${type}`);
|
|
83
|
+
|
|
84
|
+
try {
|
|
85
|
+
return await compilers[type](csn, options);
|
|
86
|
+
} catch(error) {
|
|
87
|
+
Logger.error(`Compilation failed for service ${name} (compiler: ${type}) - ${error.message}`);
|
|
88
|
+
throw error;
|
|
89
|
+
}
|
|
90
|
+
};
|
package/lib/ord.js
CHANGED
|
@@ -13,8 +13,11 @@ const {
|
|
|
13
13
|
createGroupsTemplateForService,
|
|
14
14
|
_propagateORDVisibility,
|
|
15
15
|
} = require("./templates");
|
|
16
|
-
const { getIntegrationDependencies } = require("./
|
|
17
|
-
const {
|
|
16
|
+
const { getIntegrationDependencies } = require("./integration-dependency");
|
|
17
|
+
const {
|
|
18
|
+
getCustomORDContent,
|
|
19
|
+
compareAndHandleCustomORDContentWithExistingContent,
|
|
20
|
+
} = require("./extend-ord-with-custom");
|
|
18
21
|
const { getRFC3339Date } = require("./date");
|
|
19
22
|
const { createAuthConfig } = require("./auth/authentication");
|
|
20
23
|
|
|
@@ -321,7 +324,7 @@ function _filterUnusedPackages(ordDocument) {
|
|
|
321
324
|
return ordDocument.packages.filter((pkg) => usedPackageIds.has(pkg.ordId));
|
|
322
325
|
}
|
|
323
326
|
|
|
324
|
-
module.exports = (csn) => {
|
|
327
|
+
module.exports = (csn, extensions = []) => {
|
|
325
328
|
const linkedCsn = _propagateORDVisibility(cds.linked(csn));
|
|
326
329
|
const appConfig = initializeAppConfig(linkedCsn);
|
|
327
330
|
|
|
@@ -358,7 +361,12 @@ module.exports = (csn) => {
|
|
|
358
361
|
ordDocument.integrationDependencies = integrationDependencies;
|
|
359
362
|
}
|
|
360
363
|
|
|
361
|
-
|
|
364
|
+
[...(extensions || []), getCustomORDContent(appConfig)]
|
|
365
|
+
.filter((extension) => !!extension)
|
|
366
|
+
.forEach((extension) => {
|
|
367
|
+
ordDocument = compareAndHandleCustomORDContentWithExistingContent(ordDocument, extension);
|
|
368
|
+
});
|
|
369
|
+
|
|
362
370
|
ordDocument.packages = _filterUnusedPackages(ordDocument);
|
|
363
371
|
|
|
364
372
|
return ordDocument;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
@protocol: 'rest'
|
|
2
|
+
@requires: [ 'internal-user' ]
|
|
3
|
+
@path: '/-/cds/ord-provider-service'
|
|
4
|
+
@impl:'@cap-js/ord/lib/services/mtx-ord-provider-service.js'
|
|
5
|
+
service cds.xt.ord.MtxOrdProviderService {
|
|
6
|
+
|
|
7
|
+
action getOrdDocument(
|
|
8
|
+
tenant : String,
|
|
9
|
+
@cds.validate: false
|
|
10
|
+
toggles : array of String,
|
|
11
|
+
for : String enum { nodejs; java; },
|
|
12
|
+
) returns {};
|
|
13
|
+
|
|
14
|
+
action getOrdResourceDefinition(
|
|
15
|
+
tenant : String,
|
|
16
|
+
@cds.validate: false
|
|
17
|
+
toggles : array of String,
|
|
18
|
+
for : String enum { nodejs; java; },
|
|
19
|
+
resource : String,
|
|
20
|
+
) returns LargeString;
|
|
21
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const cds = require("@sap/cds/lib");
|
|
2
|
+
const { ord, getMetadata } = require("@cap-js/ord/lib");
|
|
3
|
+
|
|
4
|
+
module.exports = class MtxOrdProviderService extends cds.ApplicationService {
|
|
5
|
+
init() {
|
|
6
|
+
this.on("getOrdDocument", async (req) => {
|
|
7
|
+
req._?.res?.set("Content-Type", "application/json");
|
|
8
|
+
|
|
9
|
+
return ord(
|
|
10
|
+
await (
|
|
11
|
+
await cds.connect.to("cds.xt.ModelProviderService")
|
|
12
|
+
).getCsn({
|
|
13
|
+
for: req.data.for,
|
|
14
|
+
tenant: req.data.tenant,
|
|
15
|
+
toggles: req.data.toggles,
|
|
16
|
+
}),
|
|
17
|
+
);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
this.on("getOrdResourceDefinition", async (req) => {
|
|
21
|
+
const { response, contentType } = await getMetadata(
|
|
22
|
+
req.data.resource,
|
|
23
|
+
await (
|
|
24
|
+
await cds.connect.to("cds.xt.ModelProviderService")
|
|
25
|
+
).getCsn({
|
|
26
|
+
for: req.data.for,
|
|
27
|
+
tenant: req.data.tenant,
|
|
28
|
+
toggles: req.data.toggles,
|
|
29
|
+
}),
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
req._?.res?.set("Content-Type", contentType);
|
|
33
|
+
|
|
34
|
+
return response;
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
return super.init();
|
|
38
|
+
}
|
|
39
|
+
};
|
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
const cds = require("@sap/cds");
|
|
2
|
-
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
2
|
+
|
|
3
|
+
const ord = require("../ord.js");
|
|
4
|
+
const Logger = require("../logger.js");
|
|
5
|
+
const defaults = require("../defaults.js");
|
|
6
|
+
const compileMetadata = require("../meta-data.js");
|
|
7
|
+
const { createAuthConfig, createAuthMiddleware } = require("../auth/authentication.js");
|
|
7
8
|
|
|
8
9
|
class OpenResourceDiscoveryService extends cds.ApplicationService {
|
|
9
10
|
async init() {
|
|
11
|
+
this.extensions = {};
|
|
12
|
+
|
|
13
|
+
cds.on("ord.extension.publish", ({ id, data }) => {
|
|
14
|
+
Logger.info(`Registering extension with id ${id}...`);
|
|
15
|
+
|
|
16
|
+
this.extensions[id] = data;
|
|
17
|
+
});
|
|
18
|
+
|
|
10
19
|
// Initialize authentication configuration from .cdsrc.json or environment variables
|
|
11
20
|
// CF mTLS validator is lazily initialized on first mTLS request
|
|
12
21
|
const authConfig = createAuthConfig();
|
|
@@ -23,7 +32,7 @@ class OpenResourceDiscoveryService extends cds.ApplicationService {
|
|
|
23
32
|
|
|
24
33
|
cds.app.get(`/ord/v1/documents/ord-document`, authMiddleware, async (_, res) => {
|
|
25
34
|
const csn = cds.context?.model || cds.model;
|
|
26
|
-
const data = ord(csn);
|
|
35
|
+
const data = ord(csn, Array.from(Object.values(this.extensions)));
|
|
27
36
|
return res.status(200).send(data);
|
|
28
37
|
});
|
|
29
38
|
|
package/lib/threads/compile.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
const { workerData } = require("piscina");
|
|
2
2
|
|
|
3
|
-
const compileMetadata = require("../
|
|
3
|
+
const compileMetadata = require("../meta-data");
|
|
4
|
+
const registerCompileTargets = require("../common/register-compile-targets");
|
|
5
|
+
|
|
6
|
+
registerCompileTargets(); // Worker threads skip cds-plugin.js — re-register compile targets
|
|
4
7
|
|
|
5
8
|
module.exports = ({ url }) => {
|
|
6
9
|
// JSON round-trip: CDS compiler output may contain Generator objects
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cap-js/ord",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "CAP Plugin for generating ORD document.",
|
|
5
5
|
"repository": "cap-js/ord",
|
|
6
6
|
"author": "SAP SE (https://www.sap.com)",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"eslint": "^10.0.0",
|
|
35
35
|
"express": "^4",
|
|
36
36
|
"jest": "^30.0.0",
|
|
37
|
-
"prettier": "3.8.
|
|
37
|
+
"prettier": "3.8.3",
|
|
38
38
|
"supertest": "^7.0.0"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
@@ -49,18 +49,23 @@
|
|
|
49
49
|
"piscina": "^5.1.4"
|
|
50
50
|
},
|
|
51
51
|
"engines": {
|
|
52
|
-
"node": ">=
|
|
52
|
+
"node": ">=20 <25"
|
|
53
53
|
},
|
|
54
54
|
"overrides": {
|
|
55
|
-
"@sap/cds-compiler": "6.
|
|
55
|
+
"@sap/cds-compiler": "6.9.0"
|
|
56
56
|
},
|
|
57
57
|
"cds": {
|
|
58
58
|
"requires": {
|
|
59
59
|
"SAP ORD Service": {
|
|
60
|
-
"model": "@cap-js/ord/lib/ord-service"
|
|
60
|
+
"model": "@cap-js/ord/lib/services/ord-service"
|
|
61
61
|
},
|
|
62
62
|
"[java]": {
|
|
63
63
|
"SAP ORD Service": false
|
|
64
|
+
},
|
|
65
|
+
"[mtx-sidecar]": {
|
|
66
|
+
"SAP ORD Service": {
|
|
67
|
+
"model": "@cap-js/ord/lib/services/mtx-ord-provider-service"
|
|
68
|
+
}
|
|
64
69
|
}
|
|
65
70
|
}
|
|
66
71
|
}
|
package/lib/metaData.js
DELETED
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
const cds = require("@sap/cds/lib");
|
|
2
|
-
const { compile: openapi } = require("@cap-js/openapi");
|
|
3
|
-
const { compile: asyncapi } = require("@cap-js/asyncapi");
|
|
4
|
-
const { COMPILER_TYPES, OPENAPI_SERVERS_ANNOTATION } = require("./constants");
|
|
5
|
-
const Logger = require("./logger");
|
|
6
|
-
const { interopCSN } = require("./interopCsn.js");
|
|
7
|
-
const cdsc = require("@sap/cds-compiler/lib/main");
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Read @OpenAPI.servers annotation from service definition
|
|
11
|
-
* @param {object} csn - The CSN model
|
|
12
|
-
* @param {string} serviceName - The service name
|
|
13
|
-
* @returns {string|undefined} - JSON string of servers array or undefined
|
|
14
|
-
*/
|
|
15
|
-
const _getServersFromAnnotation = (csn, serviceName) => {
|
|
16
|
-
const servers = csn?.definitions?.[serviceName]?.[OPENAPI_SERVERS_ANNOTATION];
|
|
17
|
-
const isValidServers = Array.isArray(servers) && servers.length > 0;
|
|
18
|
-
return isValidServers ? JSON.stringify(servers) : undefined;
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
const getMetadata = async (url, model = null) => {
|
|
22
|
-
const parts = url
|
|
23
|
-
?.split("/")
|
|
24
|
-
.pop()
|
|
25
|
-
.replace(/\.json$/, "")
|
|
26
|
-
.split(".");
|
|
27
|
-
const compilerType = parts.pop();
|
|
28
|
-
const serviceName = parts.join(".");
|
|
29
|
-
const csn = model || cds.services[serviceName]?.model;
|
|
30
|
-
const compileOptions = cds.env["ord"]?.compileOptions || {};
|
|
31
|
-
|
|
32
|
-
let responseFile;
|
|
33
|
-
const options = { service: serviceName, as: "str", messages: [] };
|
|
34
|
-
switch (compilerType) {
|
|
35
|
-
case COMPILER_TYPES.oas3:
|
|
36
|
-
try {
|
|
37
|
-
// Check for service-level @OpenAPI.servers annotation
|
|
38
|
-
const serversFromAnnotation = _getServersFromAnnotation(csn, serviceName);
|
|
39
|
-
const openapiOptions = { ...options, ...(compileOptions?.openapi || {}) };
|
|
40
|
-
|
|
41
|
-
// Service-level annotation takes precedence over global config
|
|
42
|
-
if (serversFromAnnotation) {
|
|
43
|
-
openapiOptions["openapi:servers"] = serversFromAnnotation;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
responseFile = openapi(csn, openapiOptions);
|
|
47
|
-
} catch (error) {
|
|
48
|
-
Logger.error(`OpenApi error for service ${serviceName} - ${error.message}`);
|
|
49
|
-
throw error;
|
|
50
|
-
}
|
|
51
|
-
break;
|
|
52
|
-
case COMPILER_TYPES.asyncapi2:
|
|
53
|
-
try {
|
|
54
|
-
responseFile = asyncapi(csn, { ...options, ...(compileOptions?.asyncapi || {}) });
|
|
55
|
-
} catch (error) {
|
|
56
|
-
Logger.error(`AsyncApi error for service ${serviceName} - ${error.message}`);
|
|
57
|
-
throw error;
|
|
58
|
-
}
|
|
59
|
-
break;
|
|
60
|
-
case COMPILER_TYPES.csn:
|
|
61
|
-
try {
|
|
62
|
-
const opt_eff = { beta: { effectiveCsn: true }, effectiveServiceName: serviceName };
|
|
63
|
-
let effCsn = cdsc.for.effective(csn, opt_eff);
|
|
64
|
-
responseFile = interopCSN(effCsn);
|
|
65
|
-
} catch (error) {
|
|
66
|
-
Logger.error(`Csn error for service ${serviceName} - ${error.message}`);
|
|
67
|
-
throw error;
|
|
68
|
-
}
|
|
69
|
-
break;
|
|
70
|
-
case COMPILER_TYPES.edmx:
|
|
71
|
-
try {
|
|
72
|
-
responseFile = await cds.compile(csn).to["edmx"]({ ...options, ...(compileOptions?.edmx || {}) });
|
|
73
|
-
} catch (error) {
|
|
74
|
-
Logger.error(`Edmx error for service ${serviceName} - ${error.message}`);
|
|
75
|
-
throw error;
|
|
76
|
-
}
|
|
77
|
-
break;
|
|
78
|
-
case COMPILER_TYPES.mcp:
|
|
79
|
-
try {
|
|
80
|
-
responseFile = await cds.compile(csn).to["mcp"]({ ...options, ...(compileOptions?.mcp || {}) });
|
|
81
|
-
} catch (error) {
|
|
82
|
-
Logger.error("MCP error:", error.message);
|
|
83
|
-
throw error;
|
|
84
|
-
}
|
|
85
|
-
break;
|
|
86
|
-
case COMPILER_TYPES.graphql:
|
|
87
|
-
try {
|
|
88
|
-
const { generateSchema4 } = require("@cap-js/graphql/lib/schema");
|
|
89
|
-
const { lexicographicSortSchema, printSchema } = require("graphql");
|
|
90
|
-
const linked = cds.linked(csn);
|
|
91
|
-
const srv = new cds.ApplicationService(serviceName, linked);
|
|
92
|
-
let schema = generateSchema4({ [serviceName]: srv });
|
|
93
|
-
schema = lexicographicSortSchema(schema);
|
|
94
|
-
responseFile = printSchema(schema);
|
|
95
|
-
} catch (error) {
|
|
96
|
-
Logger.error("GraphQL SDL error:", error.message);
|
|
97
|
-
throw error;
|
|
98
|
-
}
|
|
99
|
-
break;
|
|
100
|
-
}
|
|
101
|
-
return {
|
|
102
|
-
contentType:
|
|
103
|
-
compilerType === "graphql" ? "text/plain" : `application/${compilerType === "edmx" ? "xml" : "json"}`,
|
|
104
|
-
response: responseFile,
|
|
105
|
-
};
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
module.exports = getMetadata;
|
|
File without changes
|
|
File without changes
|