@sap-ux/fiori-mcp-server 0.0.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/LICENSE +201 -0
- package/README.md +99 -0
- package/dist/constant.d.ts +5 -0
- package/dist/constant.js +8 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +7 -0
- package/dist/page-editor-api/api.d.ts +48 -0
- package/dist/page-editor-api/api.js +93 -0
- package/dist/page-editor-api/index.d.ts +5 -0
- package/dist/page-editor-api/index.js +24 -0
- package/dist/page-editor-api/json-helper.d.ts +11 -0
- package/dist/page-editor-api/json-helper.js +64 -0
- package/dist/page-editor-api/parser/annotations.d.ts +9 -0
- package/dist/page-editor-api/parser/annotations.js +13 -0
- package/dist/page-editor-api/parser/index.d.ts +3 -0
- package/dist/page-editor-api/parser/index.js +19 -0
- package/dist/page-editor-api/parser/model/AggregationValidator.d.ts +64 -0
- package/dist/page-editor-api/parser/model/AggregationValidator.js +209 -0
- package/dist/page-editor-api/parser/model/ArrayAggregation.d.ts +49 -0
- package/dist/page-editor-api/parser/model/ArrayAggregation.js +122 -0
- package/dist/page-editor-api/parser/model/ObjectAggregation.d.ts +374 -0
- package/dist/page-editor-api/parser/model/ObjectAggregation.js +802 -0
- package/dist/page-editor-api/parser/model/PageEditModel.d.ts +223 -0
- package/dist/page-editor-api/parser/model/PageEditModel.js +954 -0
- package/dist/page-editor-api/parser/model/PageEditProperty.d.ts +38 -0
- package/dist/page-editor-api/parser/model/PageEditProperty.js +49 -0
- package/dist/page-editor-api/parser/model/RootAggregation.d.ts +24 -0
- package/dist/page-editor-api/parser/model/RootAggregation.js +54 -0
- package/dist/page-editor-api/parser/model/actions/ActionAggregation.d.ts +34 -0
- package/dist/page-editor-api/parser/model/actions/ActionAggregation.js +92 -0
- package/dist/page-editor-api/parser/model/actions/ActionsAggregation.d.ts +96 -0
- package/dist/page-editor-api/parser/model/actions/ActionsAggregation.js +252 -0
- package/dist/page-editor-api/parser/model/actions/index.d.ts +3 -0
- package/dist/page-editor-api/parser/model/actions/index.js +19 -0
- package/dist/page-editor-api/parser/model/additionalObjects/AdditionalObjectAggregation.d.ts +17 -0
- package/dist/page-editor-api/parser/model/additionalObjects/AdditionalObjectAggregation.js +26 -0
- package/dist/page-editor-api/parser/model/additionalObjects/AdditionalObjectsAggregation.d.ts +46 -0
- package/dist/page-editor-api/parser/model/additionalObjects/AdditionalObjectsAggregation.js +66 -0
- package/dist/page-editor-api/parser/model/additionalObjects/index.d.ts +3 -0
- package/dist/page-editor-api/parser/model/additionalObjects/index.js +19 -0
- package/dist/page-editor-api/parser/model/chart/ChartAggregation.d.ts +41 -0
- package/dist/page-editor-api/parser/model/chart/ChartAggregation.js +94 -0
- package/dist/page-editor-api/parser/model/chart/index.d.ts +2 -0
- package/dist/page-editor-api/parser/model/chart/index.js +18 -0
- package/dist/page-editor-api/parser/model/fields/ConnectedFieldsAggregation.d.ts +9 -0
- package/dist/page-editor-api/parser/model/fields/ConnectedFieldsAggregation.js +13 -0
- package/dist/page-editor-api/parser/model/fields/FieldAggregation.d.ts +25 -0
- package/dist/page-editor-api/parser/model/fields/FieldAggregation.js +42 -0
- package/dist/page-editor-api/parser/model/fields/FieldsAggregation.d.ts +22 -0
- package/dist/page-editor-api/parser/model/fields/FieldsAggregation.js +34 -0
- package/dist/page-editor-api/parser/model/fields/index.d.ts +4 -0
- package/dist/page-editor-api/parser/model/fields/index.js +20 -0
- package/dist/page-editor-api/parser/model/filter-fields/FilterFieldAggregation.d.ts +39 -0
- package/dist/page-editor-api/parser/model/filter-fields/FilterFieldAggregation.js +94 -0
- package/dist/page-editor-api/parser/model/filter-fields/FilterFieldsAggregation.d.ts +36 -0
- package/dist/page-editor-api/parser/model/filter-fields/FilterFieldsAggregation.js +59 -0
- package/dist/page-editor-api/parser/model/filter-fields/index.d.ts +3 -0
- package/dist/page-editor-api/parser/model/filter-fields/index.js +19 -0
- package/dist/page-editor-api/parser/model/index.d.ts +19 -0
- package/dist/page-editor-api/parser/model/index.js +35 -0
- package/dist/page-editor-api/parser/model/macros/MacrosRoot.d.ts +48 -0
- package/dist/page-editor-api/parser/model/macros/MacrosRoot.js +114 -0
- package/dist/page-editor-api/parser/model/macros/index.d.ts +2 -0
- package/dist/page-editor-api/parser/model/macros/index.js +18 -0
- package/dist/page-editor-api/parser/model/sections/HeaderSectionsAggregation.d.ts +31 -0
- package/dist/page-editor-api/parser/model/sections/HeaderSectionsAggregation.js +82 -0
- package/dist/page-editor-api/parser/model/sections/SectionAggregation.d.ts +78 -0
- package/dist/page-editor-api/parser/model/sections/SectionAggregation.js +131 -0
- package/dist/page-editor-api/parser/model/sections/SectionsAggregation.d.ts +135 -0
- package/dist/page-editor-api/parser/model/sections/SectionsAggregation.js +402 -0
- package/dist/page-editor-api/parser/model/sections/SectionsObjectAggregation.d.ts +50 -0
- package/dist/page-editor-api/parser/model/sections/SectionsObjectAggregation.js +119 -0
- package/dist/page-editor-api/parser/model/sections/SubSectionsAggregation.d.ts +39 -0
- package/dist/page-editor-api/parser/model/sections/SubSectionsAggregation.js +70 -0
- package/dist/page-editor-api/parser/model/sections/index.d.ts +6 -0
- package/dist/page-editor-api/parser/model/sections/index.js +22 -0
- package/dist/page-editor-api/parser/model/table/ColumnAggregation.d.ts +89 -0
- package/dist/page-editor-api/parser/model/table/ColumnAggregation.js +175 -0
- package/dist/page-editor-api/parser/model/table/ColumnsAggregation.d.ts +113 -0
- package/dist/page-editor-api/parser/model/table/ColumnsAggregation.js +293 -0
- package/dist/page-editor-api/parser/model/table/TableAggregation.d.ts +13 -0
- package/dist/page-editor-api/parser/model/table/TableAggregation.js +21 -0
- package/dist/page-editor-api/parser/model/table/ToolbarAggregation.d.ts +15 -0
- package/dist/page-editor-api/parser/model/table/ToolbarAggregation.js +22 -0
- package/dist/page-editor-api/parser/model/table/index.d.ts +5 -0
- package/dist/page-editor-api/parser/model/table/index.js +21 -0
- package/dist/page-editor-api/parser/model/table/utils.d.ts +12 -0
- package/dist/page-editor-api/parser/model/table/utils.js +44 -0
- package/dist/page-editor-api/parser/model/types/annotations.d.ts +63 -0
- package/dist/page-editor-api/parser/model/types/annotations.js +29 -0
- package/dist/page-editor-api/parser/model/types/common.d.ts +13 -0
- package/dist/page-editor-api/parser/model/types/common.js +3 -0
- package/dist/page-editor-api/parser/model/types/index.d.ts +220 -0
- package/dist/page-editor-api/parser/model/types/index.js +149 -0
- package/dist/page-editor-api/parser/model/utils/annotations.d.ts +38 -0
- package/dist/page-editor-api/parser/model/utils/annotations.js +120 -0
- package/dist/page-editor-api/parser/model/utils/i18n.d.ts +33 -0
- package/dist/page-editor-api/parser/model/utils/i18n.js +69 -0
- package/dist/page-editor-api/parser/model/utils/index.d.ts +6 -0
- package/dist/page-editor-api/parser/model/utils/index.js +22 -0
- package/dist/page-editor-api/parser/model/utils/object.d.ts +25 -0
- package/dist/page-editor-api/parser/model/utils/object.js +68 -0
- package/dist/page-editor-api/parser/model/utils/sort.d.ts +31 -0
- package/dist/page-editor-api/parser/model/utils/sort.js +18 -0
- package/dist/page-editor-api/parser/model/utils/utils.d.ts +94 -0
- package/dist/page-editor-api/parser/model/utils/utils.js +267 -0
- package/dist/page-editor-api/parser/model/views/ViewAggregation.d.ts +62 -0
- package/dist/page-editor-api/parser/model/views/ViewAggregation.js +112 -0
- package/dist/page-editor-api/parser/model/views/ViewsAggregation.d.ts +54 -0
- package/dist/page-editor-api/parser/model/views/ViewsAggregation.js +141 -0
- package/dist/page-editor-api/parser/model/views/index.d.ts +3 -0
- package/dist/page-editor-api/parser/model/views/index.js +19 -0
- package/dist/page-editor-api/parser/model/visual-filters/VisualFilterAggregation.d.ts +11 -0
- package/dist/page-editor-api/parser/model/visual-filters/VisualFilterAggregation.js +15 -0
- package/dist/page-editor-api/parser/model/visual-filters/VisualFiltersAggregation.d.ts +11 -0
- package/dist/page-editor-api/parser/model/visual-filters/VisualFiltersAggregation.js +15 -0
- package/dist/page-editor-api/parser/model/visual-filters/index.d.ts +3 -0
- package/dist/page-editor-api/parser/model/visual-filters/index.js +19 -0
- package/dist/page-editor-api/parser/tree.d.ts +135 -0
- package/dist/page-editor-api/parser/tree.js +464 -0
- package/dist/page-editor-api/project.d.ts +40 -0
- package/dist/page-editor-api/project.js +124 -0
- package/dist/page-editor-api/sapuxFtfsFileIO.d.ts +84 -0
- package/dist/page-editor-api/sapuxFtfsFileIO.js +195 -0
- package/dist/server.d.ts +35 -0
- package/dist/server.js +120 -0
- package/dist/tools/execute-functionality.d.ts +19 -0
- package/dist/tools/execute-functionality.js +175 -0
- package/dist/tools/functionalities/controller-extension/index.d.ts +4 -0
- package/dist/tools/functionalities/controller-extension/index.js +136 -0
- package/dist/tools/functionalities/functionalities.d.ts +4 -0
- package/dist/tools/functionalities/functionalities.js +19 -0
- package/dist/tools/functionalities/generate-fiori-ui-app/command.d.ts +9 -0
- package/dist/tools/functionalities/generate-fiori-ui-app/command.js +158 -0
- package/dist/tools/functionalities/generate-fiori-ui-app/generate-fiori-ui-app.d.ts +4 -0
- package/dist/tools/functionalities/generate-fiori-ui-app/generate-fiori-ui-app.js +240 -0
- package/dist/tools/functionalities/generate-fiori-ui-app/index.d.ts +2 -0
- package/dist/tools/functionalities/generate-fiori-ui-app/index.js +7 -0
- package/dist/tools/functionalities/index.d.ts +2 -0
- package/dist/tools/functionalities/index.js +18 -0
- package/dist/tools/functionalities/page/add-page.d.ts +5 -0
- package/dist/tools/functionalities/page/add-page.js +89 -0
- package/dist/tools/functionalities/page/application.d.ts +212 -0
- package/dist/tools/functionalities/page/application.js +616 -0
- package/dist/tools/functionalities/page/delete-page.d.ts +4 -0
- package/dist/tools/functionalities/page/delete-page.js +71 -0
- package/dist/tools/functionalities/page/index.d.ts +3 -0
- package/dist/tools/functionalities/page/index.js +10 -0
- package/dist/tools/functionalities/page/service.d.ts +82 -0
- package/dist/tools/functionalities/page/service.js +114 -0
- package/dist/tools/functionalities/page/serviceStore.d.ts +17 -0
- package/dist/tools/functionalities/page/serviceStore.js +34 -0
- package/dist/tools/functionalities/page/types.d.ts +42 -0
- package/dist/tools/functionalities/page/types.js +11 -0
- package/dist/tools/functionalities/page/utils.d.ts +12 -0
- package/dist/tools/functionalities/page/utils.js +63 -0
- package/dist/tools/get-functionality-details.d.ts +24 -0
- package/dist/tools/get-functionality-details.js +142 -0
- package/dist/tools/index.d.ts +7 -0
- package/dist/tools/index.js +55 -0
- package/dist/tools/input-schema/execute-functionality.json +28 -0
- package/dist/tools/input-schema/get-functionality-details.json +24 -0
- package/dist/tools/input-schema/index.d.ts +5 -0
- package/dist/tools/input-schema/index.js +15 -0
- package/dist/tools/input-schema/list-fiori-apps.json +12 -0
- package/dist/tools/input-schema/list-functionality.json +10 -0
- package/dist/tools/list-fiori-apps.d.ts +10 -0
- package/dist/tools/list-fiori-apps.js +33 -0
- package/dist/tools/list-functionalities.d.ts +10 -0
- package/dist/tools/list-functionalities.js +145 -0
- package/dist/tools/output-schema/execute-functionality.json +39 -0
- package/dist/tools/output-schema/get-functionality-details.json +142 -0
- package/dist/tools/output-schema/index.d.ts +5 -0
- package/dist/tools/output-schema/index.js +15 -0
- package/dist/tools/output-schema/list-fiori-apps.json +41 -0
- package/dist/tools/output-schema/list-functionality.json +37 -0
- package/dist/tools/utils.d.ts +16 -0
- package/dist/tools/utils.js +74 -0
- package/dist/types.d.ts +170 -0
- package/dist/types.js +3 -0
- package/package.json +63 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type { v4, ExportResults, PageConfig, File, GenerateCustomExtensionParams, Application, PageType } from '@sap/ux-specification/dist/types/src';
|
|
2
|
+
import type { ApplicationAccess } from '@sap-ux/project-access';
|
|
3
|
+
export interface PageData {
|
|
4
|
+
pageId: string;
|
|
5
|
+
config: PageConfig;
|
|
6
|
+
pageType: PageType;
|
|
7
|
+
schema: string;
|
|
8
|
+
entitySet?: string;
|
|
9
|
+
entityType?: string;
|
|
10
|
+
contextPath?: string;
|
|
11
|
+
page: v4.Page;
|
|
12
|
+
}
|
|
13
|
+
export interface AppData {
|
|
14
|
+
config: Application;
|
|
15
|
+
schema: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Class for handling file I/O operations for page editor.
|
|
19
|
+
* Mainly it uses specification to import(manifest->config/schema) or export(config->manifest).
|
|
20
|
+
*/
|
|
21
|
+
export declare class SapuxFtfsFileIO {
|
|
22
|
+
private readonly appAccess;
|
|
23
|
+
/**
|
|
24
|
+
* Creates an instance of SapuxFtfsFileIO.
|
|
25
|
+
*
|
|
26
|
+
* @param appAccess - The application access object
|
|
27
|
+
*/
|
|
28
|
+
constructor(appAccess: ApplicationAccess);
|
|
29
|
+
/**
|
|
30
|
+
* Retrieves the Specification object.
|
|
31
|
+
*
|
|
32
|
+
* @returns A promise that resolves to a Specification object
|
|
33
|
+
*/
|
|
34
|
+
private getSpecification;
|
|
35
|
+
/**
|
|
36
|
+
* Extracts the application ID from the manifest.
|
|
37
|
+
*
|
|
38
|
+
* @param manifest - The Manifest object
|
|
39
|
+
* @returns The application ID as a string
|
|
40
|
+
*/
|
|
41
|
+
private getAppId;
|
|
42
|
+
/**
|
|
43
|
+
* Retrieves virtual files for the project.
|
|
44
|
+
*
|
|
45
|
+
* @returns A promise that resolves to an array of File objects
|
|
46
|
+
*/
|
|
47
|
+
private getVirtualFiles;
|
|
48
|
+
/**
|
|
49
|
+
* Reads the application data.
|
|
50
|
+
*
|
|
51
|
+
* @param files - Optional array of File objects
|
|
52
|
+
* @returns A promise that resolves to an AppData object
|
|
53
|
+
*/
|
|
54
|
+
readApp(files?: File[]): Promise<AppData>;
|
|
55
|
+
/**
|
|
56
|
+
* Get page data object using Project Provider.
|
|
57
|
+
*
|
|
58
|
+
* @param pageId - page id.
|
|
59
|
+
* @returns Promise to page data.
|
|
60
|
+
*/
|
|
61
|
+
readPageData(pageId: string): Promise<PageData | undefined>;
|
|
62
|
+
/**
|
|
63
|
+
* Update content of the passed page.
|
|
64
|
+
*
|
|
65
|
+
* @param pageData Page data.
|
|
66
|
+
* @returns Result of export operation.
|
|
67
|
+
*/
|
|
68
|
+
writePage(pageData: PageData): Promise<ExportResults | undefined>;
|
|
69
|
+
/**
|
|
70
|
+
* Writes the application data.
|
|
71
|
+
*
|
|
72
|
+
* @param appData - The AppData object to write
|
|
73
|
+
* @returns A promise that resolves to ExportResults or undefined
|
|
74
|
+
*/
|
|
75
|
+
writeApp(appData: AppData): Promise<ExportResults | undefined>;
|
|
76
|
+
/**
|
|
77
|
+
* Writes FPM (Flexible Programming Model) data.
|
|
78
|
+
*
|
|
79
|
+
* @param params - The GenerateCustomExtensionParams object
|
|
80
|
+
* @returns A promise that resolves to an array of strings
|
|
81
|
+
*/
|
|
82
|
+
writeFPM(params: GenerateCustomExtensionParams): Promise<string[]>;
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=sapuxFtfsFileIO.d.ts.map
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SapuxFtfsFileIO = void 0;
|
|
4
|
+
const src_1 = require("@sap/ux-specification/dist/types/src");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
const project_1 = require("./project");
|
|
7
|
+
/**
|
|
8
|
+
* Class for handling file I/O operations for page editor.
|
|
9
|
+
* Mainly it uses specification to import(manifest->config/schema) or export(config->manifest).
|
|
10
|
+
*/
|
|
11
|
+
class SapuxFtfsFileIO {
|
|
12
|
+
appAccess;
|
|
13
|
+
/**
|
|
14
|
+
* Creates an instance of SapuxFtfsFileIO.
|
|
15
|
+
*
|
|
16
|
+
* @param appAccess - The application access object
|
|
17
|
+
*/
|
|
18
|
+
constructor(appAccess) {
|
|
19
|
+
this.appAccess = appAccess;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Retrieves the Specification object.
|
|
23
|
+
*
|
|
24
|
+
* @returns A promise that resolves to a Specification object
|
|
25
|
+
*/
|
|
26
|
+
async getSpecification() {
|
|
27
|
+
return this.appAccess.getSpecification();
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Extracts the application ID from the manifest.
|
|
31
|
+
*
|
|
32
|
+
* @param manifest - The Manifest object
|
|
33
|
+
* @returns The application ID as a string
|
|
34
|
+
*/
|
|
35
|
+
getAppId(manifest) {
|
|
36
|
+
return manifest['sap.app']?.id ?? '';
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Retrieves virtual files for the project.
|
|
40
|
+
*
|
|
41
|
+
* @returns A promise that resolves to an array of File objects
|
|
42
|
+
*/
|
|
43
|
+
async getVirtualFiles() {
|
|
44
|
+
const manifest = await (0, project_1.getManifest)(this.appAccess);
|
|
45
|
+
if (!manifest) {
|
|
46
|
+
return [];
|
|
47
|
+
}
|
|
48
|
+
const specification = await this.getSpecification();
|
|
49
|
+
const annotationData = await (0, project_1.readAnnotationFiles)(this.appAccess);
|
|
50
|
+
// Import project using specification API
|
|
51
|
+
return specification.importProject({
|
|
52
|
+
manifest: manifest,
|
|
53
|
+
annotations: annotationData
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Reads the application data.
|
|
58
|
+
*
|
|
59
|
+
* @param files - Optional array of File objects
|
|
60
|
+
* @returns A promise that resolves to an AppData object
|
|
61
|
+
*/
|
|
62
|
+
async readApp(files) {
|
|
63
|
+
files ??= await this.getVirtualFiles();
|
|
64
|
+
const appJson = files.find((file) => file.dataSourceUri === src_1.FileName.App);
|
|
65
|
+
const appConfig = JSON.parse(appJson?.fileContent ?? '{}');
|
|
66
|
+
const schemaPath = (0, path_1.join)('.schemas', (0, path_1.basename)((0, path_1.join)(appConfig?.$schema ?? '')));
|
|
67
|
+
const schemaFile = files.find((file) => (0, path_1.join)(file.dataSourceUri) === schemaPath);
|
|
68
|
+
if (schemaFile) {
|
|
69
|
+
const schema = JSON.parse(schemaFile.fileContent);
|
|
70
|
+
if (schema.properties?.settings) {
|
|
71
|
+
schema.properties.settings.isViewNode = true;
|
|
72
|
+
}
|
|
73
|
+
schemaFile.fileContent = JSON.stringify(schema);
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
config: appConfig,
|
|
77
|
+
schema: schemaFile?.fileContent ?? '{}'
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Get page data object using Project Provider.
|
|
82
|
+
*
|
|
83
|
+
* @param pageId - page id.
|
|
84
|
+
* @returns Promise to page data.
|
|
85
|
+
*/
|
|
86
|
+
async readPageData(pageId) {
|
|
87
|
+
try {
|
|
88
|
+
const files = await this.getVirtualFiles();
|
|
89
|
+
const pagePath = (0, path_1.join)(src_1.DirName.Pages, `${pageId}.json`);
|
|
90
|
+
const pageFile = files.find((file) => (0, path_1.join)(file.dataSourceUri) === pagePath);
|
|
91
|
+
const pageConfig = pageFile?.fileContent ? JSON.parse(pageFile.fileContent) : undefined;
|
|
92
|
+
const schemaPath = (0, path_1.join)('.schemas', (0, path_1.basename)((0, path_1.join)(pageConfig?.$schema ?? '')));
|
|
93
|
+
const schema = files.find((file) => (0, path_1.join)(file.dataSourceUri) === schemaPath);
|
|
94
|
+
if (pageConfig && schema) {
|
|
95
|
+
const application = await this.readApp(files);
|
|
96
|
+
const page = application.config.pages?.[pageId];
|
|
97
|
+
if (page) {
|
|
98
|
+
const pageType = page.pageType;
|
|
99
|
+
return {
|
|
100
|
+
pageId,
|
|
101
|
+
pageType: pageType ?? src_1.PageTypeV4.ListReport,
|
|
102
|
+
config: pageConfig,
|
|
103
|
+
page: page,
|
|
104
|
+
schema: schema.fileContent,
|
|
105
|
+
entitySet: page.entitySet,
|
|
106
|
+
entityType: 'entityType' in page && typeof page.entityType === 'string' ? page.entityType : undefined,
|
|
107
|
+
contextPath: page.contextPath
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
console.log(String(error));
|
|
114
|
+
}
|
|
115
|
+
return undefined;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Update content of the passed page.
|
|
119
|
+
*
|
|
120
|
+
* @param pageData Page data.
|
|
121
|
+
* @returns Result of export operation.
|
|
122
|
+
*/
|
|
123
|
+
async writePage(pageData) {
|
|
124
|
+
const manifest = await (0, project_1.getManifest)(this.appAccess);
|
|
125
|
+
if (!manifest) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
const specification = await this.getSpecification();
|
|
129
|
+
const schemaType = pageData.pageType === src_1.PageTypeV4.ObjectPage ? src_1.SchemaType.ObjectPage : src_1.SchemaType.ListReport;
|
|
130
|
+
const params = {
|
|
131
|
+
[schemaType]: {
|
|
132
|
+
appId: this.getAppId(manifest),
|
|
133
|
+
jsonSchema: JSON.parse(pageData.schema),
|
|
134
|
+
manifest,
|
|
135
|
+
page: {
|
|
136
|
+
...pageData.page,
|
|
137
|
+
name: pageData.pageId,
|
|
138
|
+
config: pageData.config
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
const result = specification.exportConfig({
|
|
143
|
+
v4: params
|
|
144
|
+
});
|
|
145
|
+
if (result.manifestChangeIndicator === 'Updated') {
|
|
146
|
+
await this.appAccess.updateManifestJSON(result.manifest);
|
|
147
|
+
}
|
|
148
|
+
return result;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Writes the application data.
|
|
152
|
+
*
|
|
153
|
+
* @param appData - The AppData object to write
|
|
154
|
+
* @returns A promise that resolves to ExportResults or undefined
|
|
155
|
+
*/
|
|
156
|
+
async writeApp(appData) {
|
|
157
|
+
const { config, schema } = appData;
|
|
158
|
+
const manifest = await (0, project_1.getManifest)(this.appAccess);
|
|
159
|
+
if (!manifest) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const specification = await this.getSpecification();
|
|
163
|
+
const params = {
|
|
164
|
+
[src_1.SchemaType.Application]: {
|
|
165
|
+
application: config,
|
|
166
|
+
manifest,
|
|
167
|
+
jsonSchema: JSON.parse(schema)
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
const result = specification.exportConfig({
|
|
171
|
+
v4: params
|
|
172
|
+
});
|
|
173
|
+
await this.appAccess.updateManifestJSON(result.manifest);
|
|
174
|
+
return result;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Writes FPM (Flexible Programming Model) data.
|
|
178
|
+
*
|
|
179
|
+
* @param params - The GenerateCustomExtensionParams object
|
|
180
|
+
* @returns A promise that resolves to an array of strings
|
|
181
|
+
*/
|
|
182
|
+
async writeFPM(params) {
|
|
183
|
+
if (params.data) {
|
|
184
|
+
params.data.minUI5Version = await (0, project_1.getUI5Version)(this.appAccess);
|
|
185
|
+
}
|
|
186
|
+
const specification = await this.getSpecification();
|
|
187
|
+
const fsEditor = (await specification.generateCustomExtension(params));
|
|
188
|
+
await fsEditor.commit(() => {
|
|
189
|
+
//empty callback, do nothing.
|
|
190
|
+
});
|
|
191
|
+
return Object.keys(fsEditor.dump());
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
exports.SapuxFtfsFileIO = SapuxFtfsFileIO;
|
|
195
|
+
//# sourceMappingURL=sapuxFtfsFileIO.js.map
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Sets up and manages an MCP (Model Context Protocol) server that provides Fiori-related tools.
|
|
4
|
+
*/
|
|
5
|
+
export declare class FioriFunctionalityServer {
|
|
6
|
+
private readonly server;
|
|
7
|
+
/**
|
|
8
|
+
* Initializes a new instance of the FioriFunctionalityServer.
|
|
9
|
+
* Sets up the MCP server with Fiori functionality tools and error handling.
|
|
10
|
+
*/
|
|
11
|
+
constructor();
|
|
12
|
+
/**
|
|
13
|
+
* Sets up error handling for the server.
|
|
14
|
+
* Logs MCP errors and handles the SIGINT signal for graceful shutdown.
|
|
15
|
+
*/
|
|
16
|
+
private setupErrorHandling;
|
|
17
|
+
/**
|
|
18
|
+
* Sets up handlers for various MCP tools.
|
|
19
|
+
* Configures handlers for listing tools, and calling specific Fiori functionality tools.
|
|
20
|
+
*/
|
|
21
|
+
private setupToolHandlers;
|
|
22
|
+
/**
|
|
23
|
+
* Converts the result of a tool execution to the CallToolResult format.
|
|
24
|
+
*
|
|
25
|
+
* @param result - The result to be converted.
|
|
26
|
+
* @returns The converted result in CallToolResult format.
|
|
27
|
+
*/
|
|
28
|
+
private convertResultToCallToolResult;
|
|
29
|
+
/**
|
|
30
|
+
* Starts the FioriFunctionalityServer.
|
|
31
|
+
* Connects the server to a StdioServerTransport and begins listening for requests.
|
|
32
|
+
*/
|
|
33
|
+
run(): Promise<void>;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=server.d.ts.map
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.FioriFunctionalityServer = void 0;
|
|
8
|
+
const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
|
|
9
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
10
|
+
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
|
|
11
|
+
const package_json_1 = __importDefault(require("../package.json"));
|
|
12
|
+
const tools_1 = require("./tools");
|
|
13
|
+
/**
|
|
14
|
+
* Sets up and manages an MCP (Model Context Protocol) server that provides Fiori-related tools.
|
|
15
|
+
*/
|
|
16
|
+
class FioriFunctionalityServer {
|
|
17
|
+
server;
|
|
18
|
+
/**
|
|
19
|
+
* Initializes a new instance of the FioriFunctionalityServer.
|
|
20
|
+
* Sets up the MCP server with Fiori functionality tools and error handling.
|
|
21
|
+
*/
|
|
22
|
+
constructor() {
|
|
23
|
+
this.server = new index_js_1.Server({
|
|
24
|
+
name: 'fiori-mcp',
|
|
25
|
+
version: package_json_1.default.version
|
|
26
|
+
}, {
|
|
27
|
+
capabilities: {
|
|
28
|
+
tools: {}
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
this.setupToolHandlers();
|
|
32
|
+
this.setupErrorHandling();
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Sets up error handling for the server.
|
|
36
|
+
* Logs MCP errors and handles the SIGINT signal for graceful shutdown.
|
|
37
|
+
*/
|
|
38
|
+
setupErrorHandling() {
|
|
39
|
+
this.server.onerror = (error) => console.error('[MCP Error]', error);
|
|
40
|
+
process.on('SIGINT', async () => {
|
|
41
|
+
await this.server.close();
|
|
42
|
+
process.exit(0);
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Sets up handlers for various MCP tools.
|
|
47
|
+
* Configures handlers for listing tools, and calling specific Fiori functionality tools.
|
|
48
|
+
*/
|
|
49
|
+
setupToolHandlers() {
|
|
50
|
+
this.server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => {
|
|
51
|
+
return {
|
|
52
|
+
tools: tools_1.tools
|
|
53
|
+
};
|
|
54
|
+
});
|
|
55
|
+
this.server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
|
|
56
|
+
const { name, arguments: args } = request.params;
|
|
57
|
+
try {
|
|
58
|
+
let result;
|
|
59
|
+
switch (name) {
|
|
60
|
+
case 'list-fiori-apps':
|
|
61
|
+
result = await (0, tools_1.listFioriApps)(args);
|
|
62
|
+
return this.convertResultToCallToolResult(result);
|
|
63
|
+
case 'list-functionality':
|
|
64
|
+
result = await (0, tools_1.listFunctionalities)(args);
|
|
65
|
+
return this.convertResultToCallToolResult(result);
|
|
66
|
+
case 'get-functionality-details':
|
|
67
|
+
result = await (0, tools_1.getFunctionalityDetails)(args);
|
|
68
|
+
return this.convertResultToCallToolResult(result);
|
|
69
|
+
case 'execute-functionality':
|
|
70
|
+
result = await (0, tools_1.executeFunctionality)(args);
|
|
71
|
+
return this.convertResultToCallToolResult(result);
|
|
72
|
+
default:
|
|
73
|
+
throw new Error(`Unknown tool: ${name}. Try one of: list-fiori-apps, list-functionality, get-functionality-details, execute-functionality.`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
78
|
+
return {
|
|
79
|
+
content: [
|
|
80
|
+
{
|
|
81
|
+
type: 'text',
|
|
82
|
+
text: `Error: ${errorMessage}`
|
|
83
|
+
}
|
|
84
|
+
]
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Converts the result of a tool execution to the CallToolResult format.
|
|
91
|
+
*
|
|
92
|
+
* @param result - The result to be converted.
|
|
93
|
+
* @returns The converted result in CallToolResult format.
|
|
94
|
+
*/
|
|
95
|
+
convertResultToCallToolResult(result) {
|
|
96
|
+
const convertedResult = {
|
|
97
|
+
content: [
|
|
98
|
+
{
|
|
99
|
+
type: 'text',
|
|
100
|
+
text: JSON.stringify(result)
|
|
101
|
+
}
|
|
102
|
+
]
|
|
103
|
+
};
|
|
104
|
+
if (!Array.isArray(result)) {
|
|
105
|
+
convertedResult.structuredContent = result;
|
|
106
|
+
}
|
|
107
|
+
return convertedResult;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Starts the FioriFunctionalityServer.
|
|
111
|
+
* Connects the server to a StdioServerTransport and begins listening for requests.
|
|
112
|
+
*/
|
|
113
|
+
async run() {
|
|
114
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
115
|
+
await this.server.connect(transport);
|
|
116
|
+
console.error('Fiori Functionality MCP Server running on stdio');
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
exports.FioriFunctionalityServer = FioriFunctionalityServer;
|
|
120
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ExecuteFunctionalitiesInput, ExecuteFunctionalityOutput } from '../types';
|
|
2
|
+
import { PageEditorApi } from '../page-editor-api';
|
|
3
|
+
/**
|
|
4
|
+
* Executes a functionality based on the provided parameters.
|
|
5
|
+
*
|
|
6
|
+
* @param params - Input parameters for executing the functionality
|
|
7
|
+
* @returns A promise that resolves to the execution output
|
|
8
|
+
* @throws Error if required parameters are missing
|
|
9
|
+
*/
|
|
10
|
+
export declare function executeFunctionality(params: ExecuteFunctionalitiesInput): Promise<ExecuteFunctionalityOutput>;
|
|
11
|
+
/**
|
|
12
|
+
* Retrieves the PageEditorApi instance for the given application path and page name.
|
|
13
|
+
*
|
|
14
|
+
* @param appPath - Path to the application
|
|
15
|
+
* @param pageName - Optional name of the page
|
|
16
|
+
* @returns A promise that resolves to a PageEditorApi instance or undefined
|
|
17
|
+
*/
|
|
18
|
+
export declare function getEditorApi(appPath: string, pageName?: string): Promise<PageEditorApi | undefined>;
|
|
19
|
+
//# sourceMappingURL=execute-functionality.d.ts.map
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.executeFunctionality = executeFunctionality;
|
|
4
|
+
exports.getEditorApi = getEditorApi;
|
|
5
|
+
const get_functionality_details_1 = require("./get-functionality-details");
|
|
6
|
+
const page_editor_api_1 = require("../page-editor-api");
|
|
7
|
+
const functionalities_1 = require("./functionalities");
|
|
8
|
+
const utils_1 = require("./utils");
|
|
9
|
+
/**
|
|
10
|
+
* Executes a functionality based on the provided parameters.
|
|
11
|
+
*
|
|
12
|
+
* @param params - Input parameters for executing the functionality
|
|
13
|
+
* @returns A promise that resolves to the execution output
|
|
14
|
+
* @throws Error if required parameters are missing
|
|
15
|
+
*/
|
|
16
|
+
async function executeFunctionality(params) {
|
|
17
|
+
const { functionalityId, parameters, appPath } = params;
|
|
18
|
+
if (!functionalityId) {
|
|
19
|
+
throw new Error('functionalityId parameter is required');
|
|
20
|
+
}
|
|
21
|
+
if (!appPath) {
|
|
22
|
+
throw new Error('appPath parameter is required');
|
|
23
|
+
}
|
|
24
|
+
// Custom/external functionalities
|
|
25
|
+
const externalFunctionality = typeof functionalityId === 'string' ? functionalities_1.FUNCTIONALITIES_HANDLERS.get(functionalityId) : undefined;
|
|
26
|
+
if (externalFunctionality) {
|
|
27
|
+
return externalFunctionality.executeFunctionality(params);
|
|
28
|
+
}
|
|
29
|
+
// Get functionality details to validate parameters
|
|
30
|
+
const functionality = await (0, get_functionality_details_1.getFunctionalityDetails)({
|
|
31
|
+
appPath,
|
|
32
|
+
functionalityId
|
|
33
|
+
});
|
|
34
|
+
// Validate required parameters
|
|
35
|
+
const missingParams = functionality.parameters
|
|
36
|
+
.filter((param) => param.required && !(param.id in parameters))
|
|
37
|
+
.map((param) => param.name);
|
|
38
|
+
if (missingParams.length > 0) {
|
|
39
|
+
throw new Error(`Missing required parameters: ${missingParams.join(', ')}`);
|
|
40
|
+
}
|
|
41
|
+
const changes = await generateChanges(functionality, functionalityId, parameters, appPath, functionality.pageName);
|
|
42
|
+
let executionResult;
|
|
43
|
+
if (changes.length) {
|
|
44
|
+
// Mock execution - in a real implementation, this would modify the actual files
|
|
45
|
+
executionResult = {
|
|
46
|
+
functionalityId,
|
|
47
|
+
status: 'success',
|
|
48
|
+
message: `Successfully executed '${functionality.name}'`,
|
|
49
|
+
parameters,
|
|
50
|
+
appPath,
|
|
51
|
+
changes,
|
|
52
|
+
timestamp: new Date().toISOString()
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
// No changes register
|
|
57
|
+
executionResult = {
|
|
58
|
+
functionalityId,
|
|
59
|
+
status: 'skipped',
|
|
60
|
+
message: `Execution of '${functionality.name}' did not trigger any change in files`,
|
|
61
|
+
parameters,
|
|
62
|
+
appPath,
|
|
63
|
+
changes,
|
|
64
|
+
timestamp: new Date().toISOString()
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
return executionResult;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Generates changes based on the functionality and parameters.
|
|
71
|
+
*
|
|
72
|
+
* @param functionality - Details of the functionality to be executed
|
|
73
|
+
* @param functionalityId - ID of the functionality
|
|
74
|
+
* @param parametersValue - Values for the parameters
|
|
75
|
+
* @param appPath - Path to the application
|
|
76
|
+
* @param pageName - Optional name of the page
|
|
77
|
+
* @returns A promise that resolves to an array of change descriptions
|
|
78
|
+
*/
|
|
79
|
+
async function generateChanges(functionality, functionalityId, parametersValue, appPath, pageName) {
|
|
80
|
+
const changes = [];
|
|
81
|
+
const editor = await getEditorApi(appPath, pageName);
|
|
82
|
+
if (!editor) {
|
|
83
|
+
return [];
|
|
84
|
+
}
|
|
85
|
+
const { propertyPath } = (0, get_functionality_details_1.resolveFunctionality)(functionalityId);
|
|
86
|
+
const changedParameterInfo = findParameterById(functionality, propertyPath[propertyPath.length - 1]);
|
|
87
|
+
let changed = false;
|
|
88
|
+
if (!changedParameterInfo && typeof parametersValue === 'object') {
|
|
89
|
+
// Parameters most likely in node parameters - edge case
|
|
90
|
+
for (const parameterValue in parametersValue) {
|
|
91
|
+
const paramPropertyPath = [...propertyPath, parameterValue];
|
|
92
|
+
const parameterInfo = findParameterById(functionality, parameterValue);
|
|
93
|
+
if (parameterInfo) {
|
|
94
|
+
await editor.changeProperty(paramPropertyPath, resolveParameterValue(paramPropertyPath, parametersValue, parameterInfo));
|
|
95
|
+
changed = true;
|
|
96
|
+
if (changes.length === 0) {
|
|
97
|
+
changes.push('Modified webapp/manifest.json');
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (!changed) {
|
|
103
|
+
// Common way to change property - AI passes precise property id and parameters
|
|
104
|
+
await editor.changeProperty(propertyPath, resolveParameterValue(propertyPath, parametersValue, changedParameterInfo));
|
|
105
|
+
// problem -> result?.manifestChangeIndicator does not return changed indicator when we change fcl
|
|
106
|
+
changes.push('Modified webapp/manifest.json');
|
|
107
|
+
}
|
|
108
|
+
return changes;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Retrieves the PageEditorApi instance for the given application path and page name.
|
|
112
|
+
*
|
|
113
|
+
* @param appPath - Path to the application
|
|
114
|
+
* @param pageName - Optional name of the page
|
|
115
|
+
* @returns A promise that resolves to a PageEditorApi instance or undefined
|
|
116
|
+
*/
|
|
117
|
+
async function getEditorApi(appPath, pageName) {
|
|
118
|
+
const project = await (0, utils_1.resolveApplication)(appPath);
|
|
119
|
+
if (project?.applicationAccess) {
|
|
120
|
+
return new page_editor_api_1.PageEditorApi(project.applicationAccess, pageName);
|
|
121
|
+
}
|
|
122
|
+
return undefined;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Currently resolved values through params passed differently time to time by AI.
|
|
126
|
+
* This method tries to resolve value before applying/saving it.
|
|
127
|
+
*
|
|
128
|
+
* @param propertyPath - Path to the property
|
|
129
|
+
* @param parametersValue - Object containing parameter values
|
|
130
|
+
* @param parameterInfo - Optional information about the parameter
|
|
131
|
+
* @returns The resolved parameter value
|
|
132
|
+
*/
|
|
133
|
+
function resolveParameterValue(propertyPath, parametersValue, parameterInfo) {
|
|
134
|
+
const propertyName = propertyPath[propertyPath.length - 1];
|
|
135
|
+
if (parameterInfo?.type === 'object') {
|
|
136
|
+
let value = parametersValue;
|
|
137
|
+
if (propertyName in parametersValue) {
|
|
138
|
+
// Change property is part of parameters object
|
|
139
|
+
value = parametersValue[propertyName];
|
|
140
|
+
}
|
|
141
|
+
if (value === null || (typeof value === 'object' && !Array.isArray(value) && Object.keys(value).length === 0)) {
|
|
142
|
+
// AI fails to pass undefined value, it is more stablew with null - currently workaround is to convert it to 'undefined'
|
|
143
|
+
// So far there is no valid property with value null - such transformation seems ok
|
|
144
|
+
value = undefined;
|
|
145
|
+
}
|
|
146
|
+
// Whole object is received as parameters
|
|
147
|
+
return value;
|
|
148
|
+
}
|
|
149
|
+
let value;
|
|
150
|
+
if (propertyName in parametersValue) {
|
|
151
|
+
// Change property is part of parameters object
|
|
152
|
+
value = parametersValue[propertyName];
|
|
153
|
+
}
|
|
154
|
+
else if ('value' in parametersValue) {
|
|
155
|
+
// Seems generic approach from AI - property named 'value' contains new value
|
|
156
|
+
value = parametersValue.value;
|
|
157
|
+
}
|
|
158
|
+
if (value === null) {
|
|
159
|
+
// AI fails to pass undefined value, it is more stablew with null - currently workaround is to convert it to 'undefined'
|
|
160
|
+
// So far there is no valid property with value null - such transformation seems ok
|
|
161
|
+
value = undefined;
|
|
162
|
+
}
|
|
163
|
+
return value;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Finds a parameter in the functionality details by its ID.
|
|
167
|
+
*
|
|
168
|
+
* @param functionality - Details of the functionality
|
|
169
|
+
* @param id - ID of the parameter to find
|
|
170
|
+
* @returns The found Parameter object or undefined if not found
|
|
171
|
+
*/
|
|
172
|
+
function findParameterById(functionality, id) {
|
|
173
|
+
return functionality.parameters.find((parameter) => parameter.id === id);
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=execute-functionality.js.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { FunctionalityHandlers, GetFunctionalityDetailsOutput } from '../../../types';
|
|
2
|
+
export declare const CREATE_CONTROLLER_EXTENSION_FUNCTIONALITY: GetFunctionalityDetailsOutput;
|
|
3
|
+
export declare const createControllerExtensionHandlers: FunctionalityHandlers;
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|