@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,464 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BOOLEAN_DISPLAY_FALSE = exports.BOOLEAN_DISPLAY_TRUE = void 0;
4
+ exports.getNodeId = getNodeId;
5
+ exports.getGenericBase = getGenericBase;
6
+ exports.getPropertyData = getPropertyData;
7
+ exports.traverseTree = traverseTree;
8
+ exports.getTree = getTree;
9
+ exports.findNodeByAnnotationNodeId = findNodeByAnnotationNodeId;
10
+ exports.findByPath = findByPath;
11
+ const src_1 = require("@sap/ux-specification/dist/types/src");
12
+ const model_1 = require("./model");
13
+ exports.BOOLEAN_DISPLAY_TRUE = 'True';
14
+ exports.BOOLEAN_DISPLAY_FALSE = 'False';
15
+ const NOT_ALLOWED_IN_FOOTER_AGGREGATION_NAMES = [model_1.DATA_FIELD_FOR_INTENT_BASED_NAVIGATION, model_1.DATA_FIELD_FOR_ACTION_GROUP];
16
+ /**
17
+ * Method returns dom id for node.
18
+ *
19
+ * @param path Node path.
20
+ * @returns Outline node id.
21
+ */
22
+ function getNodeId(path) {
23
+ return `outline-node${path.replace(/\//g, '-')}`;
24
+ }
25
+ /**
26
+ * Creates a generic `TreeNodeProperty` object from a property or aggregation.
27
+ *
28
+ * @param name - The name of the property.
29
+ * @param displayName - The display name of the property.
30
+ * @param property - The source property or aggregation.
31
+ * @param schemaPath - The schema path for the property.
32
+ * @returns The generated tree node property.
33
+ */
34
+ function getGenericBase(name, displayName, property, schemaPath) {
35
+ return {
36
+ schemaPath,
37
+ artifactType: property.artifactType,
38
+ description: property.description ?? '',
39
+ name,
40
+ displayName,
41
+ // Default
42
+ type: 'string',
43
+ value: property.value
44
+ };
45
+ }
46
+ /**
47
+ * Method checks if passed value is a valid number.
48
+ *
49
+ * @param value Value as unknown type.
50
+ * @returns Is nummber value.
51
+ */
52
+ const isNumber = (value) => {
53
+ return !isNaN(value) && !isNaN(value - 0);
54
+ };
55
+ /**
56
+ * Method returns options for passed enum entries.
57
+ *
58
+ * @param entries Enum entries.
59
+ * @returns Array of options.
60
+ */
61
+ const getEnumOptions = (entries) => {
62
+ const options = [];
63
+ // Empty value for deletion
64
+ options.push({
65
+ key: '',
66
+ text: ''
67
+ });
68
+ for (const option of entries) {
69
+ let optionDisplay = option;
70
+ if (typeof option === 'boolean') {
71
+ // For boolean type display appropriate string entry
72
+ optionDisplay = option ? exports.BOOLEAN_DISPLAY_TRUE : exports.BOOLEAN_DISPLAY_FALSE;
73
+ options.push({
74
+ key: option,
75
+ text: optionDisplay
76
+ });
77
+ }
78
+ else if (typeof option === 'string') {
79
+ if (isNumber(parseFloat(option))) {
80
+ options.push({
81
+ key: parseFloat(option),
82
+ text: option?.toString()
83
+ });
84
+ }
85
+ else {
86
+ options.push({
87
+ key: option,
88
+ text: option
89
+ });
90
+ }
91
+ }
92
+ else if (typeof option === 'number' && isNumber(option)) {
93
+ options.push({
94
+ key: option,
95
+ text: option?.toString()
96
+ });
97
+ }
98
+ }
99
+ return options;
100
+ };
101
+ /**
102
+ * Updates a string property definition based on its JSON Schema.
103
+ *
104
+ * @param property The tree node property being updated.
105
+ * @param schema The JSON Schema definition for the property.
106
+ */
107
+ function updateStringProperty(property, schema) {
108
+ if (schema.enum || schema.oneOf) {
109
+ let options = [];
110
+ if (schema.enum) {
111
+ options = getEnumOptions(schema.enum);
112
+ }
113
+ else if (schema.oneOf) {
114
+ options = schema.oneOf.map((entry) => {
115
+ const text = entry.const;
116
+ return {
117
+ key: entry.const,
118
+ text
119
+ };
120
+ });
121
+ // Empty value for deletion
122
+ options.unshift({
123
+ key: '',
124
+ text: '',
125
+ reset: true
126
+ });
127
+ }
128
+ property.options = options;
129
+ }
130
+ }
131
+ /**
132
+ * Generates a `TreeNodeProperty` with type-specific configurations based on a `SettingOption`.
133
+ *
134
+ * @param name - The name of the property.
135
+ * @param displayName - The display name of the property.
136
+ * @param property - The source property.
137
+ * @param schemaPath - The schema path for the property.
138
+ * @returns The configured tree node property, or `undefined` if unhandled.
139
+ */
140
+ function getPropertyData(name, displayName, property, schemaPath) {
141
+ const type = property.schema.type;
142
+ const propertyInstance = getGenericBase(name, displayName, property, schemaPath);
143
+ switch (type) {
144
+ case 'string':
145
+ propertyInstance.type = 'string';
146
+ updateStringProperty(propertyInstance, property.schema);
147
+ break;
148
+ case 'number': {
149
+ propertyInstance.type = 'number';
150
+ break;
151
+ }
152
+ case 'boolean': {
153
+ propertyInstance.type = 'boolean';
154
+ propertyInstance.options = [
155
+ {
156
+ key: undefined,
157
+ text: ''
158
+ },
159
+ {
160
+ key: true,
161
+ text: 'True'
162
+ },
163
+ {
164
+ key: false,
165
+ text: 'False'
166
+ }
167
+ ];
168
+ break;
169
+ }
170
+ default: {
171
+ if (property.schema.enum) {
172
+ getEnumOptions(property.schema.enum);
173
+ }
174
+ else {
175
+ console.warn('Unhandled property', property);
176
+ }
177
+ break;
178
+ }
179
+ }
180
+ return propertyInstance;
181
+ }
182
+ /**
183
+ * Recursively collects properties from an aggregation and its child aggregations,
184
+ * converting them into `TreeNodeProperty` objects.
185
+ *
186
+ * @param aggregation - The root aggregation to extract properties from.
187
+ * @param breadCrumbs - The chain of parent aggregations leading to this aggregation (used for recursive context).
188
+ * @returns A flat list of properties and nested object properties derived from the aggregation.
189
+ */
190
+ function getProperties(aggregation, breadCrumbs = []) {
191
+ const properties = [];
192
+ // Standard properties on same level as visible aggregation
193
+ const names = Object.keys(aggregation.properties);
194
+ if (names.length) {
195
+ names.forEach((name) => {
196
+ const property = aggregation.properties[name];
197
+ const schemaPath = aggregation.path.concat(name);
198
+ const genericProperty = getPropertyData(name, property.name, property, schemaPath);
199
+ if (genericProperty) {
200
+ properties.push(genericProperty);
201
+ }
202
+ });
203
+ }
204
+ // Complex properties which is on deeper level
205
+ for (const name in aggregation.aggregations) {
206
+ const childAggregation = aggregation.aggregations[name];
207
+ if (childAggregation.isViewNode) {
208
+ continue;
209
+ }
210
+ const objectProperty = getGenericBase(name, childAggregation.name ?? name, childAggregation, childAggregation.path);
211
+ objectProperty.type = 'object';
212
+ const subProperties = getProperties(childAggregation, [...breadCrumbs, aggregation]);
213
+ if (subProperties.length) {
214
+ objectProperty.properties = subProperties;
215
+ }
216
+ properties.push(objectProperty);
217
+ }
218
+ return properties;
219
+ }
220
+ /**
221
+ * Recursive method goes through aggregation tree and creates tree node.
222
+ *
223
+ * @param aggregation Start Aggregation.
224
+ * @param traverseNodeData Traverse data contains traverse context information.
225
+ * @returns Outline tree node.
226
+ */
227
+ function traverseTree(aggregation, traverseNodeData) {
228
+ const { text, level, model } = traverseNodeData;
229
+ let { path } = traverseNodeData;
230
+ const children = [];
231
+ const aggregationKeys = aggregation.getAggregationKeys(true);
232
+ // Apply received filter to nodes
233
+ const id = getNodeId(aggregation === model.root ? 'root-node' : `${path}-node`);
234
+ if (aggregation.virtual && model.pageType === src_1.PageTypeV4.FPMCustomPage) {
235
+ // Root virtual node should be ignored during path resolution
236
+ // Macros within Custom Page does not have separate property in config.json,
237
+ // in result to match ids between outline and properties panel - id path should be reset
238
+ path = '';
239
+ }
240
+ for (const name of aggregationKeys) {
241
+ const aggregationPath = path + '/' + name;
242
+ const childAggregation = aggregation.aggregations[name];
243
+ // external/app I18n bundle is not supported currently
244
+ // const appI18n = getAppI18nBundle();
245
+ // const i18nBundle = getRelevantI18nBundle(childAggregation, appI18n.bundles, appI18n.projectType);
246
+ // const displayText = childAggregation.getDisplayName(i18nBundle);
247
+ const displayText = childAggregation.getDisplayName();
248
+ const node = traverseTree(childAggregation, {
249
+ ...traverseNodeData,
250
+ level: level + 1,
251
+ path: aggregationPath,
252
+ text: displayText
253
+ });
254
+ children.push(node);
255
+ }
256
+ let annotationNodeId = aggregation.annotationNodeId;
257
+ if (!annotationNodeId && (aggregation instanceof model_1.RootAggregation || aggregation instanceof model_1.ViewsAggregation)) {
258
+ annotationNodeId = [];
259
+ }
260
+ return {
261
+ id: id,
262
+ path: aggregation.path.map((subPath) => subPath),
263
+ children,
264
+ text: text,
265
+ additionalText: aggregation.additionalText,
266
+ moveProps: getMovable(model, aggregation),
267
+ title: aggregation.getTechnicalName(),
268
+ properties: getProperties(aggregation),
269
+ annotationNodeId,
270
+ type: getNodeType(aggregation),
271
+ value: aggregation.value
272
+ };
273
+ }
274
+ /**
275
+ * Method returns node's movable props.
276
+ *
277
+ * @param model Edit model.
278
+ * @param aggregation Aggregation object.
279
+ * @returns Movable props.
280
+ */
281
+ function getMovable(model, aggregation) {
282
+ // Custom extensions are movable, but annotation nodes depends if annotation support feature is enabled
283
+ if (model.root !== aggregation) {
284
+ const isMovable = true;
285
+ const moveProps = {
286
+ movable: aggregation.sortableItem === model_1.SortingOptions.Enabled && isMovable,
287
+ allowedParents: getAllowedParentPaths(model.root, aggregation),
288
+ allowedChildTypes: aggregation.sortableList && aggregation.sortableCollection
289
+ ? [aggregation.sortableCollection]
290
+ : undefined,
291
+ type: aggregation.sortableCollection
292
+ };
293
+ if (aggregation.sortableItem === model_1.SortingOptions.Excluded) {
294
+ moveProps.dropRestricted = true;
295
+ }
296
+ return moveProps;
297
+ }
298
+ return undefined;
299
+ }
300
+ /**
301
+ * Method returns array of node paths, which are allowed to drop/move in.
302
+ *
303
+ * @param root Root aggregation.
304
+ * @param aggregation Target aggregation to get alowed parents.
305
+ * @returns Array of diagnostic messages for passed aggregation.
306
+ */
307
+ function getAllowedParentPaths(root, aggregation) {
308
+ let result;
309
+ if (aggregation.custom) {
310
+ const allowedDropRange = aggregation.parent?.getAllowedDropRange(aggregation);
311
+ result = [];
312
+ if (aggregation.parent && allowedDropRange) {
313
+ result.push({
314
+ path: aggregation.parent.path,
315
+ allowedRanges: allowedDropRange
316
+ });
317
+ }
318
+ }
319
+ else if (aggregation.dropUINodes) {
320
+ let allowedParents = root.findAllowedDropAggregations(aggregation);
321
+ if (NOT_ALLOWED_IN_FOOTER_AGGREGATION_NAMES.some((aggName) => aggregation.name?.startsWith(aggName))) {
322
+ // restrict moving navigation node to footer - special case
323
+ allowedParents = allowedParents.filter((allowedParent) => !(0, model_1.isArrayEqual)(allowedParent.path, ['footer', 'actions']));
324
+ }
325
+ result = allowedParents.map((allowedParent) => ({
326
+ path: allowedParent.path,
327
+ allowedRanges: allowedParent.range
328
+ }));
329
+ }
330
+ return result;
331
+ }
332
+ /**
333
+ * Determines the aggregation node type for a given `ObjectAggregation`.
334
+ *
335
+ * @param aggregation - The aggregation instance to evaluate.
336
+ * @returns The corresponding node type, or `undefined` if not recognized.
337
+ */
338
+ function getNodeType(aggregation) {
339
+ let type;
340
+ if (aggregation.custom) {
341
+ if (aggregation instanceof model_1.ActionAggregation) {
342
+ type = model_1.AggregationNodeType.customAction;
343
+ }
344
+ else if (aggregation instanceof model_1.ColumnAggregation) {
345
+ type = model_1.AggregationNodeType.customColumn;
346
+ }
347
+ else if (aggregation instanceof model_1.FilterFieldAggregation) {
348
+ type = model_1.AggregationNodeType.customFilterField;
349
+ }
350
+ else if (aggregation instanceof model_1.SectionAggregation) {
351
+ type = model_1.AggregationNodeType.customSection;
352
+ }
353
+ }
354
+ else if (aggregation.path.length === 0) {
355
+ type = model_1.AggregationNodeType.rootNode;
356
+ }
357
+ else if (aggregation instanceof model_1.ViewsAggregation) {
358
+ type = model_1.AggregationNodeType.views;
359
+ }
360
+ return type;
361
+ }
362
+ /**
363
+ * Method creates tree for passed edit model.
364
+ *
365
+ * @param schema Page or application schema.
366
+ * @param data Configuration file mapped to schema.
367
+ * @param pageType Page type. If pageType is not passed, then considered as application.
368
+ * @param annotation Page annotations.
369
+ * @returns Outline tree.
370
+ */
371
+ function getTree(schema, data, pageType, annotation) {
372
+ const model = new model_1.PageEditModel('Root', pageType, data, schema, annotation ?? {
373
+ dynamicNodes: {},
374
+ nodes: []
375
+ });
376
+ const node = traverseTree(model.root, {
377
+ level: 0,
378
+ path: '',
379
+ text: model.name,
380
+ model
381
+ });
382
+ // Update root node
383
+ node.root = true;
384
+ return node;
385
+ }
386
+ /**
387
+ * Method finds node by passed annotation nodeId.
388
+ *
389
+ * @param tree Nodes tree to lookup.
390
+ * @param nodeId Annotation node id.
391
+ * @returns Found node information.
392
+ */
393
+ function findNodeByAnnotationNodeId(tree, nodeId) {
394
+ for (const node of tree) {
395
+ if ((0, model_1.isArrayEqual)(node.annotationNodeId, nodeId)) {
396
+ // If the current node is the target, return it and its parent as null
397
+ return node;
398
+ }
399
+ else if (node.children) {
400
+ // If the current node has children, search for the target in each child
401
+ const foundNode = findNodeByAnnotationNodeId(node.children, nodeId);
402
+ if (foundNode) {
403
+ // If the target is found in a child, return the child as the node and the current node as the parent
404
+ return foundNode;
405
+ }
406
+ }
407
+ }
408
+ // If the target is not found
409
+ return undefined;
410
+ }
411
+ /**
412
+ * Finds a node or property in a tree by its property path.
413
+ *
414
+ * @param tree - The tree of nodes to search.
415
+ * @param propertyPath - The path of the property to find.
416
+ * @returns The matching node or property if found, otherwise `undefined`.
417
+ */
418
+ function findByPath(tree, propertyPath) {
419
+ for (const node of tree) {
420
+ // Check if the node itself matches
421
+ if ((0, model_1.isArrayEqual)(node.path, propertyPath)) {
422
+ return { node };
423
+ }
424
+ // Check direct properties of the node
425
+ for (const property of node.properties) {
426
+ if ((0, model_1.isArrayEqual)(property.schemaPath, propertyPath)) {
427
+ return { property };
428
+ }
429
+ // Recursively search in nested properties
430
+ const result = searchProperty(property, propertyPath);
431
+ if (result) {
432
+ return { node, property: result };
433
+ }
434
+ }
435
+ // Recursively search in children nodes
436
+ const result = node.children ? findByPath(node.children, propertyPath) : undefined;
437
+ if (result) {
438
+ return result;
439
+ }
440
+ }
441
+ return undefined;
442
+ }
443
+ /**
444
+ * Recursively searches nested properties of a `TreeNodeProperty` for a matching schema path.
445
+ *
446
+ * @param property - The property to search within.
447
+ * @param propertyPath - The schema path to match.
448
+ * @returns The matching nested property if found, otherwise `undefined`.
449
+ */
450
+ function searchProperty(property, propertyPath) {
451
+ if (property.properties) {
452
+ for (const child of property.properties) {
453
+ if ((0, model_1.isArrayEqual)(child.schemaPath, propertyPath)) {
454
+ return child;
455
+ }
456
+ const result = searchProperty(child, propertyPath);
457
+ if (result) {
458
+ return result;
459
+ }
460
+ }
461
+ }
462
+ return undefined;
463
+ }
464
+ //# sourceMappingURL=tree.js.map
@@ -0,0 +1,40 @@
1
+ import type { ApplicationAccess, Manifest } from '@sap-ux/project-access';
2
+ import type { FileData } from '@sap/ux-specification/dist/types/src';
3
+ /**
4
+ * Method returns main service of the application.
5
+ *
6
+ * @param appAccess Application access.
7
+ * @returns main service name
8
+ */
9
+ export declare function getMainService(appAccess: ApplicationAccess): string;
10
+ /**
11
+ * Retrieves the service name for the application.
12
+ *
13
+ * @param appAccess - The application access object
14
+ * @returns A promise that resolves to the service name
15
+ */
16
+ export declare function getServiceName(appAccess: ApplicationAccess): Promise<string>;
17
+ /**
18
+ * Reads annotation files for the application.
19
+ *
20
+ * @param appAccess - The application access object
21
+ * @returns A promise that resolves to an array of FileData objects
22
+ */
23
+ export declare function readAnnotationFiles(appAccess: ApplicationAccess): Promise<FileData[]>;
24
+ /**
25
+ * Retrieves the manifest file for the application.
26
+ *
27
+ * @param appAccess - The application access object
28
+ * @returns A promise that resolves to the Manifest object or undefined if not found
29
+ */
30
+ export declare function getManifest(appAccess: ApplicationAccess): Promise<Manifest | undefined>;
31
+ /**
32
+ * Returns the project's ui5version.
33
+ * It reads the vesion from minUI5Version in the manifest.json.
34
+ * If the minUI5Version is not a number, then 'latest' is returned as default value in case of exceptions.
35
+ *
36
+ * @param appAccess - application access object.
37
+ * @returns Resolved UI5 version for passed application.
38
+ */
39
+ export declare function getUI5Version(appAccess: ApplicationAccess): Promise<string>;
40
+ //# sourceMappingURL=project.d.ts.map
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getMainService = getMainService;
4
+ exports.getServiceName = getServiceName;
5
+ exports.readAnnotationFiles = readAnnotationFiles;
6
+ exports.getManifest = getManifest;
7
+ exports.getUI5Version = getUI5Version;
8
+ const project_access_1 = require("@sap-ux/project-access");
9
+ const fs_1 = require("fs");
10
+ const promises_1 = require("fs/promises");
11
+ const path_1 = require("path");
12
+ /**
13
+ * Method returns main service of the application.
14
+ *
15
+ * @param appAccess Application access.
16
+ * @returns main service name
17
+ */
18
+ function getMainService(appAccess) {
19
+ const appId = appAccess.getAppId();
20
+ const project = appAccess.project;
21
+ let mainService;
22
+ if (appId === undefined) {
23
+ const appIds = Object.keys(project.apps);
24
+ mainService = project.apps[appIds[0]].mainService;
25
+ }
26
+ else {
27
+ const app = project.apps[appId];
28
+ if (!app) {
29
+ throw new Error('ERROR_INVALID_APP_ID');
30
+ }
31
+ mainService = app.mainService;
32
+ }
33
+ return mainService ?? 'mainService';
34
+ }
35
+ /**
36
+ * Retrieves the service name for the application.
37
+ *
38
+ * @param appAccess - The application access object
39
+ * @returns A promise that resolves to the service name
40
+ */
41
+ async function getServiceName(appAccess) {
42
+ let serviceName = getMainService(appAccess);
43
+ if (appAccess.projectType === 'CAPJava' || appAccess.projectType === 'CAPNodejs') {
44
+ // get CDS service name
45
+ serviceName = await (0, project_access_1.getCapServiceName)(appAccess.project.root, appAccess.app?.services?.[serviceName].uri ?? '');
46
+ }
47
+ return serviceName;
48
+ }
49
+ /**
50
+ * Reads annotation files for the application.
51
+ *
52
+ * @param appAccess - The application access object
53
+ * @returns A promise that resolves to an array of FileData objects
54
+ */
55
+ async function readAnnotationFiles(appAccess) {
56
+ const annotationData = [];
57
+ const mainServiceName = getMainService(appAccess);
58
+ const mainService = appAccess.app?.services?.[mainServiceName];
59
+ if (!mainService) {
60
+ return [];
61
+ }
62
+ if (mainService.uri && (appAccess.projectType === 'CAPJava' || appAccess.projectType === 'CAPNodejs')) {
63
+ const serviceUri = mainService?.uri ?? '';
64
+ if (serviceUri) {
65
+ const edmx = await (0, project_access_1.readCapServiceMetadataEdmx)(appAccess.root, serviceUri);
66
+ annotationData.push({
67
+ fileContent: edmx,
68
+ dataSourceUri: serviceUri
69
+ });
70
+ }
71
+ }
72
+ else {
73
+ if (mainService.local) {
74
+ const serviceFile = await (0, promises_1.readFile)(mainService.local);
75
+ annotationData.push({
76
+ dataSourceUri: mainService.local,
77
+ fileContent: serviceFile.toString()
78
+ });
79
+ }
80
+ const { annotations = [] } = mainService;
81
+ for (const annotation of annotations) {
82
+ if (annotation.local) {
83
+ const annotationFile = await (0, promises_1.readFile)(annotation.local);
84
+ annotationData.push({
85
+ dataSourceUri: annotation.local,
86
+ fileContent: annotationFile.toString()
87
+ });
88
+ }
89
+ }
90
+ }
91
+ return annotationData;
92
+ }
93
+ /**
94
+ * Retrieves the manifest file for the application.
95
+ *
96
+ * @param appAccess - The application access object
97
+ * @returns A promise that resolves to the Manifest object or undefined if not found
98
+ */
99
+ async function getManifest(appAccess) {
100
+ const absoluteWebappPath = await (0, project_access_1.getWebappPath)(appAccess.app.appRoot);
101
+ const manifest = (0, path_1.join)(absoluteWebappPath, project_access_1.FileName.Manifest);
102
+ if (!(0, fs_1.existsSync)(manifest)) {
103
+ return undefined;
104
+ }
105
+ const file = await (0, promises_1.readFile)(manifest);
106
+ return JSON.parse(file.toString());
107
+ }
108
+ /**
109
+ * Returns the project's ui5version.
110
+ * It reads the vesion from minUI5Version in the manifest.json.
111
+ * If the minUI5Version is not a number, then 'latest' is returned as default value in case of exceptions.
112
+ *
113
+ * @param appAccess - application access object.
114
+ * @returns Resolved UI5 version for passed application.
115
+ */
116
+ async function getUI5Version(appAccess) {
117
+ const manifest = await getManifest(appAccess);
118
+ let ui5Version = manifest ? (0, project_access_1.getMinimumUI5Version)(manifest) : undefined;
119
+ if (ui5Version !== undefined && isNaN(parseFloat(ui5Version))) {
120
+ ui5Version = 'latest';
121
+ }
122
+ return ui5Version ?? 'latest';
123
+ }
124
+ //# sourceMappingURL=project.js.map