@sap-ux/odata-service-inquirer 2.4.23 → 2.5.0

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 (answers.mainEntity) {
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.23",
4
+ "version": "2.5.0",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/SAP/open-ux-tools.git",
@@ -48,7 +48,7 @@
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.4.19",
51
+ "@sap-ux/fiori-elements-writer": "2.5.0",
52
52
  "@sap-ux/fiori-freestyle-writer": "2.4.11",
53
53
  "@sap-ux/feature-toggle": "0.3.0",
54
54
  "@sap-ux/odata-service-writer": "0.27.5",