@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.
Files changed (181) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +99 -0
  3. package/dist/constant.d.ts +5 -0
  4. package/dist/constant.js +8 -0
  5. package/dist/index.d.ts +3 -0
  6. package/dist/index.js +7 -0
  7. package/dist/page-editor-api/api.d.ts +48 -0
  8. package/dist/page-editor-api/api.js +93 -0
  9. package/dist/page-editor-api/index.d.ts +5 -0
  10. package/dist/page-editor-api/index.js +24 -0
  11. package/dist/page-editor-api/json-helper.d.ts +11 -0
  12. package/dist/page-editor-api/json-helper.js +64 -0
  13. package/dist/page-editor-api/parser/annotations.d.ts +9 -0
  14. package/dist/page-editor-api/parser/annotations.js +13 -0
  15. package/dist/page-editor-api/parser/index.d.ts +3 -0
  16. package/dist/page-editor-api/parser/index.js +19 -0
  17. package/dist/page-editor-api/parser/model/AggregationValidator.d.ts +64 -0
  18. package/dist/page-editor-api/parser/model/AggregationValidator.js +209 -0
  19. package/dist/page-editor-api/parser/model/ArrayAggregation.d.ts +49 -0
  20. package/dist/page-editor-api/parser/model/ArrayAggregation.js +122 -0
  21. package/dist/page-editor-api/parser/model/ObjectAggregation.d.ts +374 -0
  22. package/dist/page-editor-api/parser/model/ObjectAggregation.js +802 -0
  23. package/dist/page-editor-api/parser/model/PageEditModel.d.ts +223 -0
  24. package/dist/page-editor-api/parser/model/PageEditModel.js +954 -0
  25. package/dist/page-editor-api/parser/model/PageEditProperty.d.ts +38 -0
  26. package/dist/page-editor-api/parser/model/PageEditProperty.js +49 -0
  27. package/dist/page-editor-api/parser/model/RootAggregation.d.ts +24 -0
  28. package/dist/page-editor-api/parser/model/RootAggregation.js +54 -0
  29. package/dist/page-editor-api/parser/model/actions/ActionAggregation.d.ts +34 -0
  30. package/dist/page-editor-api/parser/model/actions/ActionAggregation.js +92 -0
  31. package/dist/page-editor-api/parser/model/actions/ActionsAggregation.d.ts +96 -0
  32. package/dist/page-editor-api/parser/model/actions/ActionsAggregation.js +252 -0
  33. package/dist/page-editor-api/parser/model/actions/index.d.ts +3 -0
  34. package/dist/page-editor-api/parser/model/actions/index.js +19 -0
  35. package/dist/page-editor-api/parser/model/additionalObjects/AdditionalObjectAggregation.d.ts +17 -0
  36. package/dist/page-editor-api/parser/model/additionalObjects/AdditionalObjectAggregation.js +26 -0
  37. package/dist/page-editor-api/parser/model/additionalObjects/AdditionalObjectsAggregation.d.ts +46 -0
  38. package/dist/page-editor-api/parser/model/additionalObjects/AdditionalObjectsAggregation.js +66 -0
  39. package/dist/page-editor-api/parser/model/additionalObjects/index.d.ts +3 -0
  40. package/dist/page-editor-api/parser/model/additionalObjects/index.js +19 -0
  41. package/dist/page-editor-api/parser/model/chart/ChartAggregation.d.ts +41 -0
  42. package/dist/page-editor-api/parser/model/chart/ChartAggregation.js +94 -0
  43. package/dist/page-editor-api/parser/model/chart/index.d.ts +2 -0
  44. package/dist/page-editor-api/parser/model/chart/index.js +18 -0
  45. package/dist/page-editor-api/parser/model/fields/ConnectedFieldsAggregation.d.ts +9 -0
  46. package/dist/page-editor-api/parser/model/fields/ConnectedFieldsAggregation.js +13 -0
  47. package/dist/page-editor-api/parser/model/fields/FieldAggregation.d.ts +25 -0
  48. package/dist/page-editor-api/parser/model/fields/FieldAggregation.js +42 -0
  49. package/dist/page-editor-api/parser/model/fields/FieldsAggregation.d.ts +22 -0
  50. package/dist/page-editor-api/parser/model/fields/FieldsAggregation.js +34 -0
  51. package/dist/page-editor-api/parser/model/fields/index.d.ts +4 -0
  52. package/dist/page-editor-api/parser/model/fields/index.js +20 -0
  53. package/dist/page-editor-api/parser/model/filter-fields/FilterFieldAggregation.d.ts +39 -0
  54. package/dist/page-editor-api/parser/model/filter-fields/FilterFieldAggregation.js +94 -0
  55. package/dist/page-editor-api/parser/model/filter-fields/FilterFieldsAggregation.d.ts +36 -0
  56. package/dist/page-editor-api/parser/model/filter-fields/FilterFieldsAggregation.js +59 -0
  57. package/dist/page-editor-api/parser/model/filter-fields/index.d.ts +3 -0
  58. package/dist/page-editor-api/parser/model/filter-fields/index.js +19 -0
  59. package/dist/page-editor-api/parser/model/index.d.ts +19 -0
  60. package/dist/page-editor-api/parser/model/index.js +35 -0
  61. package/dist/page-editor-api/parser/model/macros/MacrosRoot.d.ts +48 -0
  62. package/dist/page-editor-api/parser/model/macros/MacrosRoot.js +114 -0
  63. package/dist/page-editor-api/parser/model/macros/index.d.ts +2 -0
  64. package/dist/page-editor-api/parser/model/macros/index.js +18 -0
  65. package/dist/page-editor-api/parser/model/sections/HeaderSectionsAggregation.d.ts +31 -0
  66. package/dist/page-editor-api/parser/model/sections/HeaderSectionsAggregation.js +82 -0
  67. package/dist/page-editor-api/parser/model/sections/SectionAggregation.d.ts +78 -0
  68. package/dist/page-editor-api/parser/model/sections/SectionAggregation.js +131 -0
  69. package/dist/page-editor-api/parser/model/sections/SectionsAggregation.d.ts +135 -0
  70. package/dist/page-editor-api/parser/model/sections/SectionsAggregation.js +402 -0
  71. package/dist/page-editor-api/parser/model/sections/SectionsObjectAggregation.d.ts +50 -0
  72. package/dist/page-editor-api/parser/model/sections/SectionsObjectAggregation.js +119 -0
  73. package/dist/page-editor-api/parser/model/sections/SubSectionsAggregation.d.ts +39 -0
  74. package/dist/page-editor-api/parser/model/sections/SubSectionsAggregation.js +70 -0
  75. package/dist/page-editor-api/parser/model/sections/index.d.ts +6 -0
  76. package/dist/page-editor-api/parser/model/sections/index.js +22 -0
  77. package/dist/page-editor-api/parser/model/table/ColumnAggregation.d.ts +89 -0
  78. package/dist/page-editor-api/parser/model/table/ColumnAggregation.js +175 -0
  79. package/dist/page-editor-api/parser/model/table/ColumnsAggregation.d.ts +113 -0
  80. package/dist/page-editor-api/parser/model/table/ColumnsAggregation.js +293 -0
  81. package/dist/page-editor-api/parser/model/table/TableAggregation.d.ts +13 -0
  82. package/dist/page-editor-api/parser/model/table/TableAggregation.js +21 -0
  83. package/dist/page-editor-api/parser/model/table/ToolbarAggregation.d.ts +15 -0
  84. package/dist/page-editor-api/parser/model/table/ToolbarAggregation.js +22 -0
  85. package/dist/page-editor-api/parser/model/table/index.d.ts +5 -0
  86. package/dist/page-editor-api/parser/model/table/index.js +21 -0
  87. package/dist/page-editor-api/parser/model/table/utils.d.ts +12 -0
  88. package/dist/page-editor-api/parser/model/table/utils.js +44 -0
  89. package/dist/page-editor-api/parser/model/types/annotations.d.ts +63 -0
  90. package/dist/page-editor-api/parser/model/types/annotations.js +29 -0
  91. package/dist/page-editor-api/parser/model/types/common.d.ts +13 -0
  92. package/dist/page-editor-api/parser/model/types/common.js +3 -0
  93. package/dist/page-editor-api/parser/model/types/index.d.ts +220 -0
  94. package/dist/page-editor-api/parser/model/types/index.js +149 -0
  95. package/dist/page-editor-api/parser/model/utils/annotations.d.ts +38 -0
  96. package/dist/page-editor-api/parser/model/utils/annotations.js +120 -0
  97. package/dist/page-editor-api/parser/model/utils/i18n.d.ts +33 -0
  98. package/dist/page-editor-api/parser/model/utils/i18n.js +69 -0
  99. package/dist/page-editor-api/parser/model/utils/index.d.ts +6 -0
  100. package/dist/page-editor-api/parser/model/utils/index.js +22 -0
  101. package/dist/page-editor-api/parser/model/utils/object.d.ts +25 -0
  102. package/dist/page-editor-api/parser/model/utils/object.js +68 -0
  103. package/dist/page-editor-api/parser/model/utils/sort.d.ts +31 -0
  104. package/dist/page-editor-api/parser/model/utils/sort.js +18 -0
  105. package/dist/page-editor-api/parser/model/utils/utils.d.ts +94 -0
  106. package/dist/page-editor-api/parser/model/utils/utils.js +267 -0
  107. package/dist/page-editor-api/parser/model/views/ViewAggregation.d.ts +62 -0
  108. package/dist/page-editor-api/parser/model/views/ViewAggregation.js +112 -0
  109. package/dist/page-editor-api/parser/model/views/ViewsAggregation.d.ts +54 -0
  110. package/dist/page-editor-api/parser/model/views/ViewsAggregation.js +141 -0
  111. package/dist/page-editor-api/parser/model/views/index.d.ts +3 -0
  112. package/dist/page-editor-api/parser/model/views/index.js +19 -0
  113. package/dist/page-editor-api/parser/model/visual-filters/VisualFilterAggregation.d.ts +11 -0
  114. package/dist/page-editor-api/parser/model/visual-filters/VisualFilterAggregation.js +15 -0
  115. package/dist/page-editor-api/parser/model/visual-filters/VisualFiltersAggregation.d.ts +11 -0
  116. package/dist/page-editor-api/parser/model/visual-filters/VisualFiltersAggregation.js +15 -0
  117. package/dist/page-editor-api/parser/model/visual-filters/index.d.ts +3 -0
  118. package/dist/page-editor-api/parser/model/visual-filters/index.js +19 -0
  119. package/dist/page-editor-api/parser/tree.d.ts +135 -0
  120. package/dist/page-editor-api/parser/tree.js +464 -0
  121. package/dist/page-editor-api/project.d.ts +40 -0
  122. package/dist/page-editor-api/project.js +124 -0
  123. package/dist/page-editor-api/sapuxFtfsFileIO.d.ts +84 -0
  124. package/dist/page-editor-api/sapuxFtfsFileIO.js +195 -0
  125. package/dist/server.d.ts +35 -0
  126. package/dist/server.js +120 -0
  127. package/dist/tools/execute-functionality.d.ts +19 -0
  128. package/dist/tools/execute-functionality.js +175 -0
  129. package/dist/tools/functionalities/controller-extension/index.d.ts +4 -0
  130. package/dist/tools/functionalities/controller-extension/index.js +136 -0
  131. package/dist/tools/functionalities/functionalities.d.ts +4 -0
  132. package/dist/tools/functionalities/functionalities.js +19 -0
  133. package/dist/tools/functionalities/generate-fiori-ui-app/command.d.ts +9 -0
  134. package/dist/tools/functionalities/generate-fiori-ui-app/command.js +158 -0
  135. package/dist/tools/functionalities/generate-fiori-ui-app/generate-fiori-ui-app.d.ts +4 -0
  136. package/dist/tools/functionalities/generate-fiori-ui-app/generate-fiori-ui-app.js +240 -0
  137. package/dist/tools/functionalities/generate-fiori-ui-app/index.d.ts +2 -0
  138. package/dist/tools/functionalities/generate-fiori-ui-app/index.js +7 -0
  139. package/dist/tools/functionalities/index.d.ts +2 -0
  140. package/dist/tools/functionalities/index.js +18 -0
  141. package/dist/tools/functionalities/page/add-page.d.ts +5 -0
  142. package/dist/tools/functionalities/page/add-page.js +89 -0
  143. package/dist/tools/functionalities/page/application.d.ts +212 -0
  144. package/dist/tools/functionalities/page/application.js +616 -0
  145. package/dist/tools/functionalities/page/delete-page.d.ts +4 -0
  146. package/dist/tools/functionalities/page/delete-page.js +71 -0
  147. package/dist/tools/functionalities/page/index.d.ts +3 -0
  148. package/dist/tools/functionalities/page/index.js +10 -0
  149. package/dist/tools/functionalities/page/service.d.ts +82 -0
  150. package/dist/tools/functionalities/page/service.js +114 -0
  151. package/dist/tools/functionalities/page/serviceStore.d.ts +17 -0
  152. package/dist/tools/functionalities/page/serviceStore.js +34 -0
  153. package/dist/tools/functionalities/page/types.d.ts +42 -0
  154. package/dist/tools/functionalities/page/types.js +11 -0
  155. package/dist/tools/functionalities/page/utils.d.ts +12 -0
  156. package/dist/tools/functionalities/page/utils.js +63 -0
  157. package/dist/tools/get-functionality-details.d.ts +24 -0
  158. package/dist/tools/get-functionality-details.js +142 -0
  159. package/dist/tools/index.d.ts +7 -0
  160. package/dist/tools/index.js +55 -0
  161. package/dist/tools/input-schema/execute-functionality.json +28 -0
  162. package/dist/tools/input-schema/get-functionality-details.json +24 -0
  163. package/dist/tools/input-schema/index.d.ts +5 -0
  164. package/dist/tools/input-schema/index.js +15 -0
  165. package/dist/tools/input-schema/list-fiori-apps.json +12 -0
  166. package/dist/tools/input-schema/list-functionality.json +10 -0
  167. package/dist/tools/list-fiori-apps.d.ts +10 -0
  168. package/dist/tools/list-fiori-apps.js +33 -0
  169. package/dist/tools/list-functionalities.d.ts +10 -0
  170. package/dist/tools/list-functionalities.js +145 -0
  171. package/dist/tools/output-schema/execute-functionality.json +39 -0
  172. package/dist/tools/output-schema/get-functionality-details.json +142 -0
  173. package/dist/tools/output-schema/index.d.ts +5 -0
  174. package/dist/tools/output-schema/index.js +15 -0
  175. package/dist/tools/output-schema/list-fiori-apps.json +41 -0
  176. package/dist/tools/output-schema/list-functionality.json +37 -0
  177. package/dist/tools/utils.d.ts +16 -0
  178. package/dist/tools/utils.js +74 -0
  179. package/dist/types.d.ts +170 -0
  180. package/dist/types.js +3 -0
  181. 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
@@ -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