@ui5/mcp-server 0.1.6 → 0.2.1
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/CHANGELOG.md +40 -0
- package/README.md +3 -1
- package/lib/registerTools.d.ts +2 -0
- package/lib/registerTools.js +4 -0
- package/lib/registerTools.js.map +1 -1
- package/lib/tools/get_typescript_conversion_guidelines/index.d.ts +3 -0
- package/lib/tools/get_typescript_conversion_guidelines/index.js +29 -0
- package/lib/tools/get_typescript_conversion_guidelines/index.js.map +1 -0
- package/lib/tools/get_typescript_conversion_guidelines/typescriptConversionGuidelines.d.ts +1 -0
- package/lib/tools/get_typescript_conversion_guidelines/typescriptConversionGuidelines.js +66 -0
- package/lib/tools/get_typescript_conversion_guidelines/typescriptConversionGuidelines.js.map +1 -0
- package/lib/tools/run_manifest_validation/index.d.ts +3 -0
- package/lib/tools/run_manifest_validation/index.js +30 -0
- package/lib/tools/run_manifest_validation/index.js.map +1 -0
- package/lib/tools/run_manifest_validation/runValidation.d.ts +2 -0
- package/lib/tools/run_manifest_validation/runValidation.js +130 -0
- package/lib/tools/run_manifest_validation/runValidation.js.map +1 -0
- package/lib/tools/run_manifest_validation/schema.d.ts +28 -0
- package/lib/tools/run_manifest_validation/schema.js +27 -0
- package/lib/tools/run_manifest_validation/schema.js.map +1 -0
- package/lib/utils/ui5Manifest.d.ts +17 -0
- package/lib/utils/ui5Manifest.js +105 -5
- package/lib/utils/ui5Manifest.js.map +1 -1
- package/npm-shrinkwrap.json +595 -100
- package/package.json +17 -15
- package/resources/integration_cards_guidelines.md +1 -0
- package/resources/typescript_conversion_guidelines.md +990 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,45 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.2.1](https://github.com/UI5/mcp-server/compare/v0.2.0...v0.2.1) (2026-01-02)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* Add manifest validation tool ([#93](https://github.com/UI5/mcp-server/issues/93)) ([01fc0b4](https://github.com/UI5/mcp-server/commit/01fc0b4dcad81accf991b190eba99cdefdabc149))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Dependencies
|
|
12
|
+
|
|
13
|
+
* Bump @modelcontextprotocol/sdk from 1.24.3 to 1.25.0 ([10250cf](https://github.com/UI5/mcp-server/commit/10250cf2c43e1e93cc3f1afeec6c3a7de7873cb7))
|
|
14
|
+
* Bump @modelcontextprotocol/sdk from 1.25.0 to 1.25.1 ([d7f8fea](https://github.com/UI5/mcp-server/commit/d7f8fea9c3ede27d2379222c3b5cea87766d2aaf))
|
|
15
|
+
* Bump @ui5/linter from 1.20.5 to 1.20.6 ([24de07d](https://github.com/UI5/mcp-server/commit/24de07d4eb4d27669fcc74213dd667269b2a3ab3))
|
|
16
|
+
* Bump @ui5/linter from 1.20.6 to 1.20.7 ([ed52e26](https://github.com/UI5/mcp-server/commit/ed52e2636c2d69e0900e3c5e6041d5b5978759e9))
|
|
17
|
+
* Bump fast-xml-parser from 5.3.2 to 5.3.3 ([709b96b](https://github.com/UI5/mcp-server/commit/709b96bee4a2f6b8bc70c9fd7967f6720d44dea6))
|
|
18
|
+
* Bump globby from 16.0.0 to 16.1.0 ([af274e0](https://github.com/UI5/mcp-server/commit/af274e05c4d6c1ac47950e3abb4b445f835db404))
|
|
19
|
+
* Bump qs from 6.14.0 to 6.14.1 ([cb2871f](https://github.com/UI5/mcp-server/commit/cb2871f985d4086a825cefdf80f596656b5bb43d))
|
|
20
|
+
* Bump zod from 4.1.13 to 4.2.0 ([5888a2b](https://github.com/UI5/mcp-server/commit/5888a2b57efa38da01adea45c51615d8c7114da5))
|
|
21
|
+
* Bump zod from 4.2.0 to 4.2.1 ([d2e746a](https://github.com/UI5/mcp-server/commit/d2e746a1f60c58fe2e74ee08832bc7f578a2980d))
|
|
22
|
+
* Bump zod from 4.2.1 to 4.3.2 ([d34c2ef](https://github.com/UI5/mcp-server/commit/d34c2efa743064f99041eda5943efb9444516e66))
|
|
23
|
+
* Bump zod from 4.3.2 to 4.3.4 ([2e61f66](https://github.com/UI5/mcp-server/commit/2e61f666a2b86369678c984e8a5524ad919aecb4))
|
|
24
|
+
|
|
25
|
+
## [0.2.0](https://github.com/UI5/mcp-server/compare/v0.1.6...v0.2.0) (2025-12-12)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
### ⚠ BREAKING CHANGES
|
|
29
|
+
|
|
30
|
+
* Update node engines version range: ^20.17.0 || >=22.9.0 ([#156](https://github.com/UI5/mcp-server/issues/156))
|
|
31
|
+
|
|
32
|
+
### Features
|
|
33
|
+
|
|
34
|
+
* Add tool with JavaScript to TypeScript conversion guidelines ([#137](https://github.com/UI5/mcp-server/issues/137)) ([52d7169](https://github.com/UI5/mcp-server/commit/52d7169b6d4dccaddf52ff32ea5f8056a221be06))
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
### Dependencies
|
|
38
|
+
|
|
39
|
+
* Bump @modelcontextprotocol/sdk from 1.24.2 to 1.24.3 ([ae346e4](https://github.com/UI5/mcp-server/commit/ae346e4910da4bfc1692ac09efb09ad2dd95b802))
|
|
40
|
+
* Bump make-fetch-happen from 14.0.3 to 15.0.3 ([#116](https://github.com/UI5/mcp-server/issues/116)) ([a9aa08a](https://github.com/UI5/mcp-server/commit/a9aa08aac55d2af7c03a02e632b6dfab29738b09))
|
|
41
|
+
* Update node engines version range: ^20.17.0 || >=22.9.0 ([#156](https://github.com/UI5/mcp-server/issues/156)) ([6a84d44](https://github.com/UI5/mcp-server/commit/6a84d443963525e5f0cc24292a50aa90c843c87c))
|
|
42
|
+
|
|
3
43
|
## [0.1.6](https://github.com/UI5/mcp-server/compare/v0.1.5...v0.1.6) (2025-12-03)
|
|
4
44
|
|
|
5
45
|
|
package/README.md
CHANGED
|
@@ -29,12 +29,14 @@ The UI5 [Model Context Protocol](https://modelcontextprotocol.io/) server offers
|
|
|
29
29
|
- `get_project_info`: Extracts metadata and configuration from a UI5 project.
|
|
30
30
|
- `get_version_info`: Retrieves version information for the UI5 framework.
|
|
31
31
|
- `run_ui5_linter`: Integrates with [`@ui5/linter`](https://github.com/UI5/linter) to analyze and report issues in UI5 code.
|
|
32
|
+
- `get_typescript_conversion_guidelines`: Provides guidelines for converting UI5 applications and controls from JavaScript to TypeScript.
|
|
32
33
|
- `get_integration_cards_guidelines`: Provides access to UI Integration Cards development best practices.
|
|
33
34
|
- `create_integration_card`: Scaffolds a new UI Integration Card.
|
|
35
|
+
- `run_manifest_validation`: Validates the manifest against the UI5 Manifest schema.
|
|
34
36
|
|
|
35
37
|
## Requirements
|
|
36
38
|
|
|
37
|
-
- [Node.js](https://nodejs.org/) Version v20.
|
|
39
|
+
- [Node.js](https://nodejs.org/) Version v20.17.0, v22.9.0 or higher
|
|
38
40
|
- [npm](https://www.npmjs.com/) Version v8.0.0 or higher
|
|
39
41
|
- An MCP client such as VS Code, Cline, or any other MCP-compatible client
|
|
40
42
|
|
package/lib/registerTools.d.ts
CHANGED
|
@@ -64,6 +64,7 @@ export declare function _processResponse({ content, structuredContent }: CallToo
|
|
|
64
64
|
src: string;
|
|
65
65
|
mimeType?: string | undefined;
|
|
66
66
|
sizes?: string[] | undefined;
|
|
67
|
+
theme?: "light" | "dark" | undefined;
|
|
67
68
|
}[] | undefined;
|
|
68
69
|
title?: string | undefined;
|
|
69
70
|
} | {
|
|
@@ -146,6 +147,7 @@ export declare function _processResponse({ content, structuredContent }: CallToo
|
|
|
146
147
|
src: string;
|
|
147
148
|
mimeType?: string | undefined;
|
|
148
149
|
sizes?: string[] | undefined;
|
|
150
|
+
theme?: "light" | "dark" | undefined;
|
|
149
151
|
}[] | undefined;
|
|
150
152
|
title?: string | undefined;
|
|
151
153
|
} | {
|
package/lib/registerTools.js
CHANGED
|
@@ -7,6 +7,8 @@ import registerGetGuidelinesTool from "./tools/get_guidelines/index.js";
|
|
|
7
7
|
import registerGetVersionInfoTool from "./tools/get_version_info/index.js";
|
|
8
8
|
import registerGetIntegrationCardsGuidelinesTool from "./tools/get_integration_cards_guidelines/index.js";
|
|
9
9
|
import registerCreateIntegrationCardTool from "./tools/create_integration_card/index.js";
|
|
10
|
+
import registerRunManifestValidationTool from "./tools/run_manifest_validation/index.js";
|
|
11
|
+
import registerGetTypescriptConversionGuidelinesTool from "./tools/get_typescript_conversion_guidelines/index.js";
|
|
10
12
|
export default function (server, context, options) {
|
|
11
13
|
const registerTool = (name, config, callback) => {
|
|
12
14
|
if (!options.useStructuredContentInResponse) {
|
|
@@ -36,6 +38,8 @@ export default function (server, context, options) {
|
|
|
36
38
|
registerGetVersionInfoTool(registerTool, context);
|
|
37
39
|
registerGetIntegrationCardsGuidelinesTool(registerTool, context);
|
|
38
40
|
registerCreateIntegrationCardTool(registerTool, context);
|
|
41
|
+
registerRunManifestValidationTool(registerTool, context);
|
|
42
|
+
registerGetTypescriptConversionGuidelinesTool(registerTool, context);
|
|
39
43
|
}
|
|
40
44
|
export function _processResponse({ content, structuredContent }, options) {
|
|
41
45
|
if (!options.useResourcesInResponse) {
|
package/lib/registerTools.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registerTools.js","sourceRoot":"","sources":["../src/registerTools.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,WAAW,EAAC,MAAM,YAAY,CAAC;AAEvC,OAAO,uBAAuB,MAAM,mCAAmC,CAAC;AACxE,OAAO,wBAAwB,MAAM,iCAAiC,CAAC;AACvE,OAAO,qBAAqB,MAAM,iCAAiC,CAAC;AACpE,OAAO,kBAAkB,MAAM,oCAAoC,CAAC;AACpE,OAAO,yBAAyB,MAAM,iCAAiC,CAAC;AACxE,OAAO,0BAA0B,MAAM,mCAAmC,CAAC;AAC3E,OAAO,yCAAyC,MAAM,mDAAmD,CAAC;AAC1G,OAAO,iCAAiC,MAAM,0CAA0C,CAAC;
|
|
1
|
+
{"version":3,"file":"registerTools.js","sourceRoot":"","sources":["../src/registerTools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { getTypescriptConversionGuidelines } from "./typescriptConversionGuidelines.js";
|
|
2
|
+
import { getLogger } from "@ui5/logger";
|
|
3
|
+
const log = getLogger("tools:get_typescript_conversion_guidelines");
|
|
4
|
+
export default function registerTool(registerTool, _context) {
|
|
5
|
+
registerTool("get_typescript_conversion_guidelines", {
|
|
6
|
+
description: "This tool MUST be called once before converting a " +
|
|
7
|
+
"UI5 (SAPUI5/OpenUI5) project from JavaScript to TypeScript. " +
|
|
8
|
+
"The instructions provided by this tool MUST be followed to ensure " +
|
|
9
|
+
"that the project setup and code is correctly converted.",
|
|
10
|
+
annotations: {
|
|
11
|
+
title: "Get TypeScript Conversion Guidelines",
|
|
12
|
+
readOnlyHint: true,
|
|
13
|
+
idempotentHint: true,
|
|
14
|
+
openWorldHint: false,
|
|
15
|
+
},
|
|
16
|
+
}, async () => {
|
|
17
|
+
log.info("Retrieving TypeScript conversion guidelines...");
|
|
18
|
+
const guidelines = await getTypescriptConversionGuidelines();
|
|
19
|
+
return {
|
|
20
|
+
content: [
|
|
21
|
+
{
|
|
22
|
+
type: "text",
|
|
23
|
+
text: guidelines,
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
};
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/get_typescript_conversion_guidelines/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,iCAAiC,EAAC,MAAM,qCAAqC,CAAC;AACtF,OAAO,EAAC,SAAS,EAAC,MAAM,aAAa,CAAC;AAItC,MAAM,GAAG,GAAG,SAAS,CAAC,4CAA4C,CAAC,CAAC;AAEpE,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,YAA0B,EAAE,QAAiB;IACjF,YAAY,CAAC,sCAAsC,EAAE;QACpD,WAAW,EAAE,oDAAoD;YAChE,8DAA8D;YAC9D,oEAAoE;YACpE,yDAAyD;QAC1D,WAAW,EAAE;YACZ,KAAK,EAAE,sCAAsC;YAC7C,YAAY,EAAE,IAAI;YAClB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,KAAK;SACpB;KACD,EAAE,KAAK,IAAI,EAAE;QACb,GAAG,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC;QAC3D,MAAM,UAAU,GAAG,MAAM,iCAAiC,EAAE,CAAC;QAC7D,OAAO;YACN,OAAO,EAAE;gBACR;oBACC,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,UAAU;iBAChB;aACD;SACD,CAAC;IACH,CAAC,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getTypescriptConversionGuidelines(): Promise<string>;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import https from "https";
|
|
3
|
+
const typescriptConversionGuidelinesFileUrl = new URL("../../../resources/typescript_conversion_guidelines.md", import.meta.url);
|
|
4
|
+
async function getLatestVersion(packageName) {
|
|
5
|
+
return new Promise((resolve, reject) => {
|
|
6
|
+
https
|
|
7
|
+
.get(`https://registry.npmjs.org/${packageName}`, (res) => {
|
|
8
|
+
let data = "";
|
|
9
|
+
res.on("data", (chunk) => {
|
|
10
|
+
data += chunk;
|
|
11
|
+
});
|
|
12
|
+
res.on("end", () => {
|
|
13
|
+
try {
|
|
14
|
+
const json = JSON.parse(data);
|
|
15
|
+
resolve(json["dist-tags"].latest);
|
|
16
|
+
}
|
|
17
|
+
catch (_err) {
|
|
18
|
+
reject(new Error(`Failed to parse response for package ${packageName}`));
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
})
|
|
22
|
+
.on("error", (err) => {
|
|
23
|
+
reject(err);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
async function getLatestVersions(dependencies) {
|
|
28
|
+
const packageNames = Object.keys(dependencies);
|
|
29
|
+
const versionPromises = packageNames.map((packageName) => {
|
|
30
|
+
return getLatestVersion(packageName).catch((_error) => {
|
|
31
|
+
return dependencies[packageName];
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
const versions = await Promise.all(versionPromises);
|
|
35
|
+
const latestVersions = {};
|
|
36
|
+
packageNames.forEach((packageName, index) => {
|
|
37
|
+
latestVersions[packageName] = versions[index];
|
|
38
|
+
});
|
|
39
|
+
return latestVersions;
|
|
40
|
+
}
|
|
41
|
+
const getLatestDevDependencies = async () => {
|
|
42
|
+
const packages = await getLatestVersions({
|
|
43
|
+
"@ui5/cli": "^4",
|
|
44
|
+
"typescript": "^5",
|
|
45
|
+
"typescript-eslint": "^8",
|
|
46
|
+
"ui5-middleware-livereload": "^3",
|
|
47
|
+
"ui5-tooling-transpile": "^3",
|
|
48
|
+
});
|
|
49
|
+
return {
|
|
50
|
+
devDependencies: packages,
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
const getLatestTsInterfaceGeneratorVersion = async () => {
|
|
54
|
+
const version = await getLatestVersion("@ui5/ts-interface-generator").catch(() => {
|
|
55
|
+
return "^0";
|
|
56
|
+
});
|
|
57
|
+
return version;
|
|
58
|
+
};
|
|
59
|
+
export async function getTypescriptConversionGuidelines() {
|
|
60
|
+
let guidelines = await readFile(typescriptConversionGuidelinesFileUrl, { encoding: "utf-8" });
|
|
61
|
+
guidelines = guidelines
|
|
62
|
+
.replace("{{dependencies}}", JSON.stringify(await getLatestDevDependencies(), null, 3))
|
|
63
|
+
.replace("{{ts-interface-generator-version}}", await getLatestTsInterfaceGeneratorVersion());
|
|
64
|
+
return guidelines;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=typescriptConversionGuidelines.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typescriptConversionGuidelines.js","sourceRoot":"","sources":["../../../src/tools/get_typescript_conversion_guidelines/typescriptConversionGuidelines.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import runValidation from "./runValidation.js";
|
|
2
|
+
import { inputSchema, outputSchema } from "./schema.js";
|
|
3
|
+
import { getLogger } from "@ui5/logger";
|
|
4
|
+
const log = getLogger("tools:run_manifest_validation");
|
|
5
|
+
export default function registerTool(registerTool, context) {
|
|
6
|
+
registerTool("run_manifest_validation", {
|
|
7
|
+
title: "Manifest Validation",
|
|
8
|
+
description: "Validates UI5 manifest file. " +
|
|
9
|
+
"After making changes, you should always run the validation again " +
|
|
10
|
+
"to verify that no new problems have been introduced.",
|
|
11
|
+
annotations: {
|
|
12
|
+
title: "Manifest Validation",
|
|
13
|
+
readOnlyHint: true,
|
|
14
|
+
},
|
|
15
|
+
inputSchema,
|
|
16
|
+
outputSchema,
|
|
17
|
+
}, async ({ manifestPath }) => {
|
|
18
|
+
log.info(`Running manifest validation on ${manifestPath}...`);
|
|
19
|
+
const normalizedManifestPath = await context.normalizePath(manifestPath);
|
|
20
|
+
const result = await runValidation(normalizedManifestPath);
|
|
21
|
+
return {
|
|
22
|
+
content: [{
|
|
23
|
+
type: "text",
|
|
24
|
+
text: JSON.stringify(result),
|
|
25
|
+
}],
|
|
26
|
+
structuredContent: result,
|
|
27
|
+
};
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/run_manifest_validation/index.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAC,WAAW,EAAE,YAAY,EAAC,MAAM,aAAa,CAAC;AACtD,OAAO,EAAC,SAAS,EAAC,MAAM,aAAa,CAAC;AAItC,MAAM,GAAG,GAAG,SAAS,CAAC,+BAA+B,CAAC,CAAC;AAEvD,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,YAA0B,EAAE,OAAgB;IAChF,YAAY,CAAC,yBAAyB,EAAE;QACvC,KAAK,EAAE,qBAAqB;QAC5B,WAAW,EACV,+BAA+B;YAC/B,mEAAmE;YACnE,sDAAsD;QACvD,WAAW,EAAE;YACZ,KAAK,EAAE,qBAAqB;YAC5B,YAAY,EAAE,IAAI;SAClB;QACD,WAAW;QACX,YAAY;KACZ,EAAE,KAAK,EAAE,EAAC,YAAY,EAAC,EAAE,EAAE;QAC3B,GAAG,CAAC,IAAI,CAAC,kCAAkC,YAAY,KAAK,CAAC,CAAC;QAE9D,MAAM,sBAAsB,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;QACzE,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,sBAAsB,CAAC,CAAC;QAE3D,OAAO;YACN,OAAO,EAAE,CAAC;oBACT,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;iBAC5B,CAAC;YACF,iBAAiB,EAAE,MAAM;SACzB,CAAC;IACH,CAAC,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { fetchCdn } from "../../utils/cdnHelper.js";
|
|
2
|
+
import Ajv2020 from "ajv/dist/2020.js";
|
|
3
|
+
import addFormats from "ajv-formats";
|
|
4
|
+
import { readFile } from "fs/promises";
|
|
5
|
+
import { getLogger } from "@ui5/logger";
|
|
6
|
+
import { InvalidInputError } from "../../utils.js";
|
|
7
|
+
import { getManifestSchema, getManifestVersion } from "../../utils/ui5Manifest.js";
|
|
8
|
+
import { Mutex } from "async-mutex";
|
|
9
|
+
import { fileURLToPath } from "url";
|
|
10
|
+
import { isAbsolute } from "path";
|
|
11
|
+
const log = getLogger("tools:run_manifest_validation:runValidation");
|
|
12
|
+
const schemaCache = new Map();
|
|
13
|
+
const fetchSchemaMutex = new Mutex();
|
|
14
|
+
const AJV_SCHEMA_PATHS = {
|
|
15
|
+
draft06: fileURLToPath(import.meta.resolve("ajv/dist/refs/json-schema-draft-06.json")),
|
|
16
|
+
draft07: fileURLToPath(import.meta.resolve("ajv/dist/refs/json-schema-draft-07.json")),
|
|
17
|
+
};
|
|
18
|
+
async function createUI5ManifestValidateFunction(ui5Schema) {
|
|
19
|
+
try {
|
|
20
|
+
const ajv = new Ajv2020.default({
|
|
21
|
+
// Collect all errors, not just the first one
|
|
22
|
+
allErrors: true,
|
|
23
|
+
// Allow additional properties that are not in schema such as "i18n",
|
|
24
|
+
// otherwise compilation fails
|
|
25
|
+
strict: false,
|
|
26
|
+
// Don't use Unicode-aware regular expressions,
|
|
27
|
+
// otherwise compilation fails with "Invalid escape" errors
|
|
28
|
+
unicodeRegExp: false,
|
|
29
|
+
loadSchema: async (uri) => {
|
|
30
|
+
const release = await fetchSchemaMutex.acquire();
|
|
31
|
+
try {
|
|
32
|
+
if (schemaCache.has(uri)) {
|
|
33
|
+
log.info(`Loading cached schema: ${uri}`);
|
|
34
|
+
return schemaCache.get(uri);
|
|
35
|
+
}
|
|
36
|
+
log.info(`Loading external schema: ${uri}`);
|
|
37
|
+
const schema = await fetchCdn(uri);
|
|
38
|
+
// Special handling for Adaptive Card schema to fix unsupported "id" property
|
|
39
|
+
// According to the JSON Schema spec Draft 06 (used by Adaptive Card schema),
|
|
40
|
+
// "$id" should be used instead of "id"
|
|
41
|
+
// See https://github.com/microsoft/AdaptiveCards/issues/9274
|
|
42
|
+
if (uri.includes("adaptive-card.json") && typeof schema.id === "string") {
|
|
43
|
+
schema.$id = schema.id;
|
|
44
|
+
delete schema.id;
|
|
45
|
+
}
|
|
46
|
+
schemaCache.set(uri, schema);
|
|
47
|
+
return schema;
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
log.warn(`Failed to load external schema ${uri}:` +
|
|
51
|
+
`${error instanceof Error ? error.message : String(error)}`);
|
|
52
|
+
throw error;
|
|
53
|
+
}
|
|
54
|
+
finally {
|
|
55
|
+
release();
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
addFormats.default(ajv);
|
|
60
|
+
const draft06MetaSchema = JSON.parse(await readFile(AJV_SCHEMA_PATHS.draft06, "utf-8"));
|
|
61
|
+
const draft07MetaSchema = JSON.parse(await readFile(AJV_SCHEMA_PATHS.draft07, "utf-8"));
|
|
62
|
+
// Add meta-schemas for draft-06 and draft-07.
|
|
63
|
+
// These are required to support schemas that reference these drafts,
|
|
64
|
+
// for example the Adaptive Card schema and some sap.bpa.task properties.
|
|
65
|
+
ajv.addMetaSchema(draft06MetaSchema, "http://json-schema.org/draft-06/schema#");
|
|
66
|
+
ajv.addMetaSchema(draft07MetaSchema, "http://json-schema.org/draft-07/schema#");
|
|
67
|
+
const validate = await ajv.compileAsync(ui5Schema);
|
|
68
|
+
return validate;
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
throw new Error(`Failed to create UI5 manifest validate function: ` +
|
|
72
|
+
`${error instanceof Error ? error.message : String(error)}`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
async function readManifest(path) {
|
|
76
|
+
let content;
|
|
77
|
+
let json;
|
|
78
|
+
if (!isAbsolute(path)) {
|
|
79
|
+
throw new InvalidInputError(`The manifest path must be absolute: '${path}'`);
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
content = await readFile(path, "utf-8");
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
throw new InvalidInputError(`Failed to read manifest file at ${path}: ` +
|
|
86
|
+
`${error instanceof Error ? error.message : String(error)}`);
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
json = JSON.parse(content);
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
throw new InvalidInputError(`Failed to parse manifest file at ${path} as JSON: ` +
|
|
93
|
+
`${error instanceof Error ? error.message : String(error)}`);
|
|
94
|
+
}
|
|
95
|
+
return json;
|
|
96
|
+
}
|
|
97
|
+
export default async function runValidation(manifestPath) {
|
|
98
|
+
log.info(`Starting manifest validation for file: ${manifestPath}`);
|
|
99
|
+
const manifest = await readManifest(manifestPath);
|
|
100
|
+
const manifestVersion = await getManifestVersion(manifest);
|
|
101
|
+
log.info(`Using manifest version: ${manifestVersion}`);
|
|
102
|
+
const ui5ManifestSchema = await getManifestSchema(manifestVersion);
|
|
103
|
+
const validate = await createUI5ManifestValidateFunction(ui5ManifestSchema);
|
|
104
|
+
const isValid = validate(manifest);
|
|
105
|
+
if (isValid) {
|
|
106
|
+
log.info("Manifest validation successful");
|
|
107
|
+
return {
|
|
108
|
+
isValid: true,
|
|
109
|
+
errors: [],
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
// Map AJV errors to our schema format
|
|
113
|
+
const validationErrors = validate.errors ?? [];
|
|
114
|
+
const errors = validationErrors.map((error) => {
|
|
115
|
+
return {
|
|
116
|
+
keyword: error.keyword ?? "",
|
|
117
|
+
instancePath: error.instancePath ?? "",
|
|
118
|
+
schemaPath: error.schemaPath ?? "",
|
|
119
|
+
params: error.params ?? {},
|
|
120
|
+
propertyName: error.propertyName,
|
|
121
|
+
message: error.message,
|
|
122
|
+
};
|
|
123
|
+
});
|
|
124
|
+
log.info(`Manifest validation failed with ${errors.length} error(s)`);
|
|
125
|
+
return {
|
|
126
|
+
isValid: false,
|
|
127
|
+
errors: errors,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=runValidation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runValidation.js","sourceRoot":"","sources":["../../../src/tools/run_manifest_validation/runValidation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const inputSchema: {
|
|
3
|
+
manifestPath: z.ZodString;
|
|
4
|
+
};
|
|
5
|
+
export declare const outputSchema: {
|
|
6
|
+
isValid: z.ZodBoolean;
|
|
7
|
+
errors: z.ZodArray<z.ZodObject<{
|
|
8
|
+
keyword: z.ZodString;
|
|
9
|
+
instancePath: z.ZodString;
|
|
10
|
+
schemaPath: z.ZodString;
|
|
11
|
+
params: z.ZodRecord<z.ZodAny, z.ZodAny>;
|
|
12
|
+
propertyName: z.ZodOptional<z.ZodString>;
|
|
13
|
+
message: z.ZodOptional<z.ZodString>;
|
|
14
|
+
}, z.core.$strip>>;
|
|
15
|
+
};
|
|
16
|
+
declare const _outputSchemaObject: z.ZodObject<{
|
|
17
|
+
isValid: z.ZodBoolean;
|
|
18
|
+
errors: z.ZodArray<z.ZodObject<{
|
|
19
|
+
keyword: z.ZodString;
|
|
20
|
+
instancePath: z.ZodString;
|
|
21
|
+
schemaPath: z.ZodString;
|
|
22
|
+
params: z.ZodRecord<z.ZodAny, z.ZodAny>;
|
|
23
|
+
propertyName: z.ZodOptional<z.ZodString>;
|
|
24
|
+
message: z.ZodOptional<z.ZodString>;
|
|
25
|
+
}, z.core.$strip>>;
|
|
26
|
+
}, z.core.$strip>;
|
|
27
|
+
export type RunSchemaValidationResult = z.infer<typeof _outputSchemaObject>;
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const inputSchema = {
|
|
3
|
+
manifestPath: z.string()
|
|
4
|
+
.describe("Absolute path to the manifest file to validate."),
|
|
5
|
+
};
|
|
6
|
+
export const outputSchema = {
|
|
7
|
+
isValid: z.boolean()
|
|
8
|
+
.describe("Whether the manifest is valid according to the UI5 Manifest schema."),
|
|
9
|
+
errors: z.array(z.object({
|
|
10
|
+
keyword: z.string()
|
|
11
|
+
.describe("Validation keyword."),
|
|
12
|
+
instancePath: z.string()
|
|
13
|
+
.describe("JSON Pointer to the location in the data instance (e.g., `/prop/1/subProp`)."),
|
|
14
|
+
schemaPath: z.string()
|
|
15
|
+
.describe("JSON Pointer to the location of the failing keyword in the schema."),
|
|
16
|
+
params: z.record(z.any(), z.any())
|
|
17
|
+
.describe("An object with additional information about the error."),
|
|
18
|
+
propertyName: z.string()
|
|
19
|
+
.optional()
|
|
20
|
+
.describe("Set for errors in `propertyNames` keyword schema."),
|
|
21
|
+
message: z.string()
|
|
22
|
+
.optional()
|
|
23
|
+
.describe("The error message."),
|
|
24
|
+
})).describe("Array of validation error objects as returned by Ajv."),
|
|
25
|
+
};
|
|
26
|
+
const _outputSchemaObject = z.object(outputSchema);
|
|
27
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/tools/run_manifest_validation/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB,MAAM,CAAC,MAAM,WAAW,GAAG;IAC1B,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;SACtB,QAAQ,CAAC,iDAAiD,CAAC;CAC7D,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG;IAC3B,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;SAClB,QAAQ,CAAC,qEAAqE,CAAC;IACjF,MAAM,EAAE,CAAC,CAAC,KAAK,CACd,CAAC,CAAC,MAAM,CAAC;QACR,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;aACjB,QAAQ,CAAC,qBAAqB,CAAC;QACjC,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;aACtB,QAAQ,CAAC,8EAA8E,CAAC;QAC1F,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;aACpB,QAAQ,CAAC,oEAAoE,CAAC;QAChF,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC;aAChC,QAAQ,CAAC,wDAAwD,CAAC;QACpE,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;aACtB,QAAQ,EAAE;aACV,QAAQ,CAAC,mDAAmD,CAAC;QAC/D,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;aACjB,QAAQ,EAAE;aACV,QAAQ,CAAC,oBAAoB,CAAC;KAChC,CAAC,CACF,CAAC,QAAQ,CAAC,uDAAuD,CAAC;CACnE,CAAC;AACF,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC"}
|
|
@@ -1 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get the manifest schema for a specific manifest version.
|
|
3
|
+
* @param manifestVersion The manifest version
|
|
4
|
+
* @returns The manifest schema
|
|
5
|
+
* @throws Error if the manifest version is unsupported
|
|
6
|
+
*/
|
|
7
|
+
export declare function getManifestSchema(manifestVersion: string): Promise<object>;
|
|
8
|
+
/**
|
|
9
|
+
* Get the manifest version from the manifest object.
|
|
10
|
+
* @param manifest The manifest object
|
|
11
|
+
* @returns The manifest version
|
|
12
|
+
* @throws Error if the manifest version is missing or invalid
|
|
13
|
+
*/
|
|
14
|
+
export declare function getManifestVersion(manifest: object): Promise<string>;
|
|
15
|
+
/**
|
|
16
|
+
* @returns The latest manifest version
|
|
17
|
+
*/
|
|
1
18
|
export declare function getLatestManifestVersion(): Promise<string>;
|
package/lib/utils/ui5Manifest.js
CHANGED
|
@@ -1,11 +1,111 @@
|
|
|
1
|
+
import { getLogger } from "@ui5/logger";
|
|
1
2
|
import { fetchCdn } from "./cdnHelper.js";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
import { Mutex } from "async-mutex";
|
|
4
|
+
import semver from "semver";
|
|
5
|
+
const log = getLogger("utils:ui5Manifest");
|
|
6
|
+
const schemaCache = new Map();
|
|
7
|
+
const fetchSchemaMutex = new Mutex();
|
|
8
|
+
let UI5ToManifestVersionMapping = null;
|
|
9
|
+
const MAPPING_URL = "https://raw.githubusercontent.com/UI5/manifest/main/mapping.json";
|
|
10
|
+
const ui5ToManifestVersionMappingMutex = new Mutex();
|
|
11
|
+
// Manifests prior to 1.68.0 use older meta-schema, which is not supported by the current implementation
|
|
12
|
+
const LOWEST_SUPPORTED_MANIFEST_VERSION = "1.68.0";
|
|
13
|
+
function getSchemaURL(manifestVersion) {
|
|
14
|
+
return `https://raw.githubusercontent.com/UI5/manifest/v${manifestVersion}/schema.json`;
|
|
6
15
|
}
|
|
16
|
+
async function getUI5toManifestVersionMapping() {
|
|
17
|
+
const release = await ui5ToManifestVersionMappingMutex.acquire();
|
|
18
|
+
try {
|
|
19
|
+
if (UI5ToManifestVersionMapping) {
|
|
20
|
+
log.info("Loading cached UI5 to manifest version mapping");
|
|
21
|
+
return UI5ToManifestVersionMapping;
|
|
22
|
+
}
|
|
23
|
+
log.info("Fetching UI5 to manifest version mapping");
|
|
24
|
+
const mapping = await fetchCdn(MAPPING_URL);
|
|
25
|
+
log.info(`Fetched UI5 to manifest version mapping from ${MAPPING_URL}`);
|
|
26
|
+
UI5ToManifestVersionMapping = mapping;
|
|
27
|
+
return UI5ToManifestVersionMapping;
|
|
28
|
+
}
|
|
29
|
+
finally {
|
|
30
|
+
release();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
async function fetchSchema(manifestVersion) {
|
|
34
|
+
const release = await fetchSchemaMutex.acquire();
|
|
35
|
+
try {
|
|
36
|
+
if (schemaCache.has(manifestVersion)) {
|
|
37
|
+
log.info(`Loading cached schema for manifest version: ${manifestVersion}`);
|
|
38
|
+
return schemaCache.get(manifestVersion);
|
|
39
|
+
}
|
|
40
|
+
log.info(`Fetching schema for manifest version: ${manifestVersion}`);
|
|
41
|
+
const schemaURL = getSchemaURL(manifestVersion);
|
|
42
|
+
const schema = await fetchCdn(schemaURL);
|
|
43
|
+
log.info(`Fetched UI5 manifest schema from ${schemaURL}`);
|
|
44
|
+
schemaCache.set(manifestVersion, schema);
|
|
45
|
+
return schema;
|
|
46
|
+
}
|
|
47
|
+
finally {
|
|
48
|
+
release();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
async function failWithSupportedVersionsHint(errorMessage) {
|
|
52
|
+
let supportedVersions;
|
|
53
|
+
try {
|
|
54
|
+
const versionMap = await getUI5toManifestVersionMapping();
|
|
55
|
+
supportedVersions = [
|
|
56
|
+
...new Set(Object.values(versionMap).filter((version) => semver.gte(version, LOWEST_SUPPORTED_MANIFEST_VERSION))),
|
|
57
|
+
];
|
|
58
|
+
}
|
|
59
|
+
catch (_) {
|
|
60
|
+
supportedVersions = null;
|
|
61
|
+
}
|
|
62
|
+
;
|
|
63
|
+
throw new Error(errorMessage +
|
|
64
|
+
(supportedVersions ?
|
|
65
|
+
`\nSupported versions are: ${supportedVersions.join(", ")}.` :
|
|
66
|
+
""));
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Get the manifest schema for a specific manifest version.
|
|
70
|
+
* @param manifestVersion The manifest version
|
|
71
|
+
* @returns The manifest schema
|
|
72
|
+
* @throws Error if the manifest version is unsupported
|
|
73
|
+
*/
|
|
74
|
+
export async function getManifestSchema(manifestVersion) {
|
|
75
|
+
if (semver.lt(manifestVersion, LOWEST_SUPPORTED_MANIFEST_VERSION)) {
|
|
76
|
+
return failWithSupportedVersionsHint(`Manifest version '${manifestVersion}' is not supported. Please upgrade to a newer one.`);
|
|
77
|
+
}
|
|
78
|
+
try {
|
|
79
|
+
return await fetchSchema(manifestVersion);
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
return failWithSupportedVersionsHint(`Failed to fetch schema for manifest version '${manifestVersion}': ` +
|
|
83
|
+
`${error instanceof Error ? error.message : String(error)}`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Get the manifest version from the manifest object.
|
|
88
|
+
* @param manifest The manifest object
|
|
89
|
+
* @returns The manifest version
|
|
90
|
+
* @throws Error if the manifest version is missing or invalid
|
|
91
|
+
*/
|
|
92
|
+
export async function getManifestVersion(manifest) {
|
|
93
|
+
if (!("_version" in manifest)) {
|
|
94
|
+
return failWithSupportedVersionsHint("Manifest does not contain a '_version' property.");
|
|
95
|
+
}
|
|
96
|
+
if (typeof manifest._version !== "string") {
|
|
97
|
+
return failWithSupportedVersionsHint("Manifest '_version' property is not a string.");
|
|
98
|
+
}
|
|
99
|
+
if (!semver.valid(manifest._version)) {
|
|
100
|
+
return failWithSupportedVersionsHint("Manifest '_version' property is not a valid semantic version.");
|
|
101
|
+
}
|
|
102
|
+
return manifest._version;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* @returns The latest manifest version
|
|
106
|
+
*/
|
|
7
107
|
export async function getLatestManifestVersion() {
|
|
8
|
-
const versionMap = await
|
|
108
|
+
const versionMap = await getUI5toManifestVersionMapping();
|
|
9
109
|
if (!versionMap.latest) {
|
|
10
110
|
throw new Error("Could not determine latest manifest version.");
|
|
11
111
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui5Manifest.js","sourceRoot":"","sources":["../../src/utils/ui5Manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"ui5Manifest.js","sourceRoot":"","sources":["../../src/utils/ui5Manifest.ts"],"names":[],"mappings":"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"}
|