@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,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
|