@sap-ux/odata-service-inquirer 2.4.23 → 2.5.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.
|
@@ -4,6 +4,13 @@ import type { ListChoiceOptions } from 'inquirer';
|
|
|
4
4
|
export type EntityAnswer = {
|
|
5
5
|
entitySetName: string;
|
|
6
6
|
entitySetType: string;
|
|
7
|
+
/**
|
|
8
|
+
* Represents a parameter used along with the main entity to query data.
|
|
9
|
+
* When this parameter is set, the prompt for selecting navigation properties is skipped
|
|
10
|
+
* This property is populated only if the metadata entity set includes a `Common.ResultContext` annotation,
|
|
11
|
+
* indicating that the entity set requires additional parameters for querying.
|
|
12
|
+
*/
|
|
13
|
+
mainEntityParameterName?: string;
|
|
7
14
|
};
|
|
8
15
|
export type NavigationEntityAnswer = {
|
|
9
16
|
navigationPropertyName: string;
|
|
@@ -11,6 +11,46 @@ const edmx_parser_1 = require("@sap-ux/edmx-parser");
|
|
|
11
11
|
const odata_service_writer_1 = require("@sap-ux/odata-service-writer");
|
|
12
12
|
const i18n_1 = require("../../i18n");
|
|
13
13
|
const logger_helper_1 = __importDefault(require("../logger-helper"));
|
|
14
|
+
/**
|
|
15
|
+
* Finds the navigation property name that links a parameterised entity set to its target entity set.
|
|
16
|
+
*
|
|
17
|
+
* This function checks if the given entity set has the `Common.ResultContext` annotation, indicating
|
|
18
|
+
* that it is a parameterised entity. It then searches for a navigation property that:
|
|
19
|
+
* - Points to a target entity (`containsTarget === true`).
|
|
20
|
+
* - Has a partner navigation property named `Parameters` (linking back to the parameters entity).
|
|
21
|
+
*
|
|
22
|
+
* If such a navigation property is found, its name is returned and skips navigation entity selection prompt
|
|
23
|
+
* Otherwise, `null` is returned.
|
|
24
|
+
*
|
|
25
|
+
* @param entitySet - The entity set to search for navigation properties.
|
|
26
|
+
* @param entityTypes - The list of entity types to search for matching navigation properties.
|
|
27
|
+
* @returns The name of the matching navigation property, or `null` if no match is found.
|
|
28
|
+
*/
|
|
29
|
+
function getNavigationPropertyForParameterisedEntity(entitySet, entityTypes) {
|
|
30
|
+
// Check if the entity type has the Common.ResultContext annotation
|
|
31
|
+
const hasResultContextAnnotation = Boolean(entitySet?.entityType?.annotations?.Common?.ResultContext);
|
|
32
|
+
if (!hasResultContextAnnotation) {
|
|
33
|
+
// If the entity set is not parameterised, no parametrised navigation is expected
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
// Get all navigation properties of the parameterised entity type
|
|
37
|
+
const navigationProperties = entitySet?.entityType?.navigationProperties ?? [];
|
|
38
|
+
// Find the first navigation property that meets the criteria.
|
|
39
|
+
for (const navigationProperty of navigationProperties) {
|
|
40
|
+
if (navigationProperty.containsTarget === true && // Points to a target entity
|
|
41
|
+
navigationProperty.partner // The partner navigation property name is defined
|
|
42
|
+
) {
|
|
43
|
+
const isMatchingEntitySet = entityTypes?.filter((entityType) => entityType.fullyQualifiedName === navigationProperty.targetTypeName);
|
|
44
|
+
// Check if the target type name matches the provided entity type name
|
|
45
|
+
if (isMatchingEntitySet) {
|
|
46
|
+
// Return the navigation property name
|
|
47
|
+
return navigationProperty.name;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// If no matching navigation property is found, return undefined
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
14
54
|
/**
|
|
15
55
|
* Returns the entity choice options for use in a list inquirer prompt.
|
|
16
56
|
*
|
|
@@ -50,11 +90,15 @@ function getEntityChoices(edmx, { entitySetFilter, defaultMainEntityName } = {})
|
|
|
50
90
|
entitySets = convertedMetadata.entitySets;
|
|
51
91
|
}
|
|
52
92
|
entitySets.forEach((entitySet, index) => {
|
|
93
|
+
const mainEntityParameterName = getNavigationPropertyForParameterisedEntity(entitySet, convertedMetadata?.entityTypes);
|
|
53
94
|
const choice = {
|
|
54
95
|
name: entitySet.name,
|
|
55
96
|
value: {
|
|
56
97
|
entitySetName: entitySet.name,
|
|
57
|
-
entitySetType: entitySet.entityTypeName // Fully qualified entity type name
|
|
98
|
+
entitySetType: entitySet.entityTypeName, // Fully qualified entity type name
|
|
99
|
+
...(mainEntityParameterName && {
|
|
100
|
+
mainEntityParameterName
|
|
101
|
+
}) // parameterised navigation property name
|
|
58
102
|
}
|
|
59
103
|
};
|
|
60
104
|
choices.push(choice);
|
|
@@ -88,13 +88,20 @@ function getEntitySelectionQuestions(metadata, templateType, isCapService = fals
|
|
|
88
88
|
source: (prevAnswers, input) => (0, inquirer_common_1.searchChoices)(input, entityChoices.choices),
|
|
89
89
|
default: entityChoices.defaultMainEntityIndex ?? entityChoices.draftRootIndex ?? 0,
|
|
90
90
|
validate: () => validateEntityChoices(entityChoices.choices, templateType, odataVersion, isCapService),
|
|
91
|
-
additionalMessages: () => {
|
|
91
|
+
additionalMessages: (answers) => {
|
|
92
92
|
if (promptOptions?.defaultMainEntityName && entityChoices.defaultMainEntityIndex === undefined) {
|
|
93
93
|
return {
|
|
94
94
|
message: (0, i18n_1.t)('prompts.mainEntitySelection.defaultEntityNameNotFoundWarning'),
|
|
95
95
|
severity: yeoman_ui_types_1.Severity.warning
|
|
96
96
|
};
|
|
97
97
|
}
|
|
98
|
+
if (answers.mainEntity?.mainEntityParameterName) {
|
|
99
|
+
// display a warning if the main entity has a mainEntityParameterName
|
|
100
|
+
return {
|
|
101
|
+
message: (0, i18n_1.t)('prompts.mainEntitySelection.mainEntityParameterFoundInfo'),
|
|
102
|
+
severity: yeoman_ui_types_1.Severity.information
|
|
103
|
+
};
|
|
104
|
+
}
|
|
98
105
|
}
|
|
99
106
|
});
|
|
100
107
|
const convertedMetadata = entityChoices.convertedMetadata;
|
|
@@ -103,7 +110,8 @@ function getEntitySelectionQuestions(metadata, templateType, isCapService = fals
|
|
|
103
110
|
let navigationEntityChoices;
|
|
104
111
|
entityQuestions.push({
|
|
105
112
|
when: (answers) => {
|
|
106
|
-
if
|
|
113
|
+
// Skip navigation entity selection if the selected main entity has mainEntityParameterName.
|
|
114
|
+
if (answers.mainEntity && !answers.mainEntity.mainEntityParameterName) {
|
|
107
115
|
navigationEntityChoices = (0, entity_helper_1.getNavigationEntityChoices)(convertedMetadata, odataVersion, answers.mainEntity.entitySetName);
|
|
108
116
|
return navigationEntityChoices.length > 0;
|
|
109
117
|
}
|
|
@@ -123,6 +123,7 @@
|
|
|
123
123
|
"mainEntitySelection": {
|
|
124
124
|
"message": "Main entity",
|
|
125
125
|
"defaultEntityNameNotFoundWarning": "The supplied entity cannot be found in the service. Please choose from the list above.",
|
|
126
|
+
"mainEntityParameterFoundInfo": "The selected entity '{{entityName}}' requires a parameter which is set by the application filters. Navigation entities are not supported.",
|
|
126
127
|
"noDraftEnabledEntitiesError": "The CAP service you have chosen does not have any entities that are draft enabled. In order to generate a V4 Fiori application using this floor plan for a CAP project, the entity selected must be draft enabled.",
|
|
127
128
|
"noEntitiesError": "$t(errors.noRelevantEntities)",
|
|
128
129
|
"noEntitiesAlpV4Error": "The OData V4 service you have provided is not suitable for use in an Analytical List Page application. The service must contain aggregate based entities for this template."
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sap-ux/odata-service-inquirer",
|
|
3
3
|
"description": "Prompts module that can prompt users for inputs required for odata service writing",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.5.1",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "https://github.com/SAP/open-ux-tools.git",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"i18next": "23.5.1",
|
|
29
29
|
"inquirer-autocomplete-prompt": "2.0.1",
|
|
30
30
|
"os-name": "4.0.1",
|
|
31
|
-
"@sap-ux/axios-extension": "1.
|
|
31
|
+
"@sap-ux/axios-extension": "1.22.0",
|
|
32
32
|
"@sap-ux/btp-utils": "1.1.0",
|
|
33
33
|
"@sap-ux/fiori-generator-shared": "0.12.8",
|
|
34
34
|
"@sap-ux/guided-answers-helper": "0.3.0",
|
|
@@ -48,11 +48,11 @@
|
|
|
48
48
|
"@types/lodash": "4.14.202",
|
|
49
49
|
"jest-extended": "3.2.4",
|
|
50
50
|
"@sap-ux/fiori-generator-shared": "0.12.8",
|
|
51
|
-
"@sap-ux/fiori-elements-writer": "2.
|
|
52
|
-
"@sap-ux/fiori-freestyle-writer": "2.4.
|
|
51
|
+
"@sap-ux/fiori-elements-writer": "2.5.2",
|
|
52
|
+
"@sap-ux/fiori-freestyle-writer": "2.4.13",
|
|
53
53
|
"@sap-ux/feature-toggle": "0.3.0",
|
|
54
54
|
"@sap-ux/odata-service-writer": "0.27.5",
|
|
55
|
-
"@sap-ux/cap-config-writer": "0.10.
|
|
55
|
+
"@sap-ux/cap-config-writer": "0.10.9"
|
|
56
56
|
},
|
|
57
57
|
"engines": {
|
|
58
58
|
"node": ">=20.x"
|