@sap-ux/generator-adp 0.1.1 → 0.1.3

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.
@@ -35,9 +35,13 @@ export default class extends Generator {
35
35
  */
36
36
  private targetFolder;
37
37
  /**
38
- * EndpointsManager instance for managing system endpoints.
38
+ * SystemLookup instance for managing system endpoints.
39
39
  */
40
- private targetSystems;
40
+ private systemLookup;
41
+ /**
42
+ * Instance of the configuration prompter class.
43
+ */
44
+ private prompter;
41
45
  /**
42
46
  * Creates an instance of the generator.
43
47
  *
@@ -13,11 +13,9 @@ const layer_1 = require("./layer");
13
13
  const i18n_1 = require("../utils/i18n");
14
14
  const telemetryEvents_1 = require("../telemetryEvents");
15
15
  const logger_2 = __importDefault(require("../utils/logger"));
16
- const deps_1 = require("../utils/deps");
17
16
  const configuration_1 = require("./questions/configuration");
17
+ const deps_1 = require("../utils/deps");
18
18
  const default_values_1 = require("./questions/helper/default-values");
19
- const fs_1 = require("fs");
20
- const path_1 = require("path");
21
19
  /**
22
20
  * Generator for creating an Adaptation Project.
23
21
  *
@@ -53,9 +51,13 @@ class default_1 extends yeoman_generator_1.default {
53
51
  */
54
52
  targetFolder;
55
53
  /**
56
- * EndpointsManager instance for managing system endpoints.
54
+ * SystemLookup instance for managing system endpoints.
57
55
  */
58
- targetSystems;
56
+ systemLookup;
57
+ /**
58
+ * Instance of the configuration prompter class.
59
+ */
60
+ prompter;
59
61
  /**
60
62
  * Creates an instance of the generator.
61
63
  *
@@ -77,7 +79,7 @@ class default_1 extends yeoman_generator_1.default {
77
79
  const pages = [{ name: (0, i18n_1.t)('yuiNavSteps.configurationName'), description: (0, i18n_1.t)('yuiNavSteps.configurationDescr') }];
78
80
  this.prompts.splice(0, 0, pages);
79
81
  this.layer = await (0, layer_1.getFlexLayer)();
80
- this.targetSystems = new adp_tooling_1.TargetSystems(this.toolsLogger);
82
+ this.systemLookup = new adp_tooling_1.SystemLookup(this.toolsLogger);
81
83
  await fiori_generator_shared_1.TelemetryHelper.initTelemetrySettings({
82
84
  consumerModule: {
83
85
  name: '@sap/generator-fiori:generator-adp',
@@ -88,21 +90,24 @@ class default_1 extends yeoman_generator_1.default {
88
90
  });
89
91
  }
90
92
  async prompting() {
91
- const prompter = new configuration_1.ConfigPrompter(this.targetSystems, this.layer, this.toolsLogger);
92
- const configQuestions = prompter.getPrompts();
93
+ this.prompter = new configuration_1.ConfigPrompter(this.systemLookup, this.layer, this.toolsLogger);
94
+ const isCLI = (0, fiori_generator_shared_1.getHostEnvironment)() === fiori_generator_shared_1.hostEnvironment.cli;
95
+ const configQuestions = this.prompter.getPrompts({
96
+ appValidationCli: { hide: !isCLI },
97
+ systemValidationCli: { hide: !isCLI }
98
+ });
93
99
  this.configAnswers = await this.prompt(configQuestions);
94
100
  this.logger.info(`System: ${this.configAnswers.system}`);
95
101
  this.logger.info(`Application: ${JSON.stringify(this.configAnswers.application, null, 2)}`);
96
102
  }
97
103
  async writing() {
98
104
  try {
99
- const provider = await (0, adp_tooling_1.getConfiguredProvider)(this.configAnswers, this.toolsLogger);
100
105
  const projectName = (0, default_values_1.getDefaultProjectName)(this.destinationPath());
101
106
  const namespace = (0, default_values_1.generateValidNamespace)(projectName, this.layer);
102
107
  this.targetFolder = this.destinationPath(projectName);
103
- const packageJson = JSON.parse((0, fs_1.readFileSync)((0, path_1.join)(__dirname, '../../package.json'), 'utf-8'));
108
+ const packageJson = (0, deps_1.getPackageInfo)();
104
109
  const config = await (0, adp_tooling_1.getConfig)({
105
- provider,
110
+ provider: this.prompter.provider,
106
111
  configAnswers: this.configAnswers,
107
112
  layer: this.layer,
108
113
  defaults: { namespace },
@@ -1,6 +1,8 @@
1
- import type { ToolsLogger } from '@sap-ux/logger';
2
- import type { TargetSystems } from '@sap-ux/adp-tooling';
3
1
  import { FlexLayer } from '@sap-ux/adp-tooling';
2
+ import type { ToolsLogger } from '@sap-ux/logger';
3
+ import type { Manifest } from '@sap-ux/project-access';
4
+ import { type AbapServiceProvider } from '@sap-ux/axios-extension';
5
+ import type { SystemLookup } from '@sap-ux/adp-tooling';
4
6
  import type { ConfigPromptOptions, ConfigQuestion } from '../types';
5
7
  /**
6
8
  * A stateful prompter class that creates configuration questions.
@@ -8,7 +10,7 @@ import type { ConfigPromptOptions, ConfigQuestion } from '../types';
8
10
  * It exposes a single public method {@link getPrompts} to retrieve the configuration questions.
9
11
  */
10
12
  export declare class ConfigPrompter {
11
- private readonly targetSystems;
13
+ private readonly systemLookup;
12
14
  private readonly logger;
13
15
  /**
14
16
  * Indicates if the current layer is based on a customer base.
@@ -18,6 +20,10 @@ export declare class ConfigPrompter {
18
20
  * Instance of AbapServiceProvider.
19
21
  */
20
22
  private abapProvider;
23
+ /**
24
+ * Application manifest.
25
+ */
26
+ private appManifest;
21
27
  /**
22
28
  * Loaded target applications for a system.
23
29
  */
@@ -30,14 +36,64 @@ export declare class ConfigPrompter {
30
36
  * Flag indicating that system requires authentication in BAS or it does not exist in VS Code.
31
37
  */
32
38
  private isAuthRequired;
39
+ /**
40
+ * Cached UI flexibility information from the system.
41
+ */
42
+ private flexUISystem;
43
+ /**
44
+ * Flag indicating if the project is a cloud project.
45
+ */
46
+ private isCloudProject;
47
+ /**
48
+ * Flag indicating whether the selected application is supported.
49
+ */
50
+ private isApplicationSupported;
51
+ /**
52
+ * Indicates whether views are loaded synchronously.
53
+ */
54
+ private containsSyncViews;
55
+ /**
56
+ * Flag indicating if the application is an internal V4 application.
57
+ */
58
+ private isV4AppInternalMode;
59
+ /**
60
+ * Flag indicating that full adaptation-over-adaptation is supported.
61
+ */
62
+ private isSupported;
63
+ /**
64
+ * Flag indicating that only partial adaptation-over-adaptation is supported.
65
+ */
66
+ private isPartiallySupported;
67
+ /**
68
+ * UI5 version manager for handling version-related validations.
69
+ */
70
+ private readonly ui5Info;
71
+ /**
72
+ * Returns the configured abap provider instance.
73
+ *
74
+ * @returns Configured instance of AbapServiceProvider.
75
+ */
76
+ get provider(): AbapServiceProvider;
77
+ /**
78
+ * Returns the loaded application manifest.
79
+ *
80
+ * @returns Application manifest.
81
+ */
82
+ get manifest(): Manifest;
83
+ /**
84
+ * Indicates whether the application loads views synchronously.
85
+ *
86
+ * @returns {boolean} True if views are sync-loaded.
87
+ */
88
+ get hasSyncViews(): boolean;
33
89
  /**
34
90
  * Creates an instance of ConfigPrompter.
35
91
  *
36
- * @param {TargetSystems} targetSystems - The target system class to retrieve system endpoints.
92
+ * @param {SystemLookup} systemLookup - The source system class to retrieve system endpoints.
37
93
  * @param {FlexLayer} layer - The FlexLayer used to determine the base (customer or otherwise).
38
94
  * @param {ToolsLogger} logger - Instance of the logger.
39
95
  */
40
- constructor(targetSystems: TargetSystems, layer: FlexLayer, logger: ToolsLogger);
96
+ constructor(systemLookup: SystemLookup, layer: FlexLayer, logger: ToolsLogger);
41
97
  /**
42
98
  * Retrieves an array of configuration questions based on provided options.
43
99
  * This is the only public method for retrieving prompts.
@@ -56,7 +112,6 @@ export declare class ConfigPrompter {
56
112
  /**
57
113
  * Only used in the CLI context when prompt is of type `list` because the validation does not run on CLI for the system list prompt.
58
114
  *
59
- * @param {CliValidationPromptOptions} options - System validation CLI options (i.e "hide").
60
115
  * @returns Dummy prompt that runs in the CLI only.
61
116
  */
62
117
  private getSystemValidationPromptForCli;
@@ -84,17 +139,18 @@ export declare class ConfigPrompter {
84
139
  /**
85
140
  * Only used in the CLI context when prompt is of type `list` because the validation does not run on CLI for the application list prompt.
86
141
  *
87
- * @param {CliValidationPromptOptions} options - System validation CLI options (i.e "hide").
88
142
  * @returns Dummy prompt that runs in the CLI only.
89
143
  */
90
144
  private getApplicationValidationPromptForCli;
91
145
  /**
92
146
  * Validates the selected application.
93
147
  *
94
- * @param {string} app - The selected application.
95
- * @returns An error message if validation fails, or true if the selection is valid.
148
+ * Checks if the application is provided and then evaluates support based on its manifest.
149
+ *
150
+ * @param {SourceApplication} app - The selected application.
151
+ * @returns A promise that resolves to true if valid, or an error message string if validation fails.
96
152
  */
97
- private validateApplicationSelection;
153
+ private validateAppPrompt;
98
154
  /**
99
155
  * Validates the password by setting up the provider and, if necessary,
100
156
  * loading the available applications.
@@ -114,16 +170,58 @@ export declare class ConfigPrompter {
114
170
  */
115
171
  private validateSystem;
116
172
  /**
117
- * Fetches system information from the provider's layered repository.
173
+ * Validates the selected application to ensure it is supported.
174
+ *
175
+ * @param {Application} app - The application to validate.
176
+ * @returns {Promise<boolean | string>} True if the application is valid, otherwise an error message.
177
+ */
178
+ private validateAppData;
179
+ /**
180
+ * Evaluate if the application version supports certain features.
181
+ *
182
+ * @param {Application} application - The application data.
183
+ */
184
+ private evaluateAppSupport;
185
+ /**
186
+ * Fetches system data including cloud project and UI flexibility information.
118
187
  *
119
- * @returns {SystemInfo} System into containing system supported adaptation project types and translations.
188
+ * @returns A promise that resolves when system data is fetched.
120
189
  */
121
- private getSystemInfo;
190
+ private getSystemData;
191
+ /**
192
+ * Handles the fetching and validation of system data.
193
+ *
194
+ * @returns {Promise<boolean | string>} True if successful, or an error message if an error occurs.
195
+ */
196
+ private handleSystemDataValidation;
197
+ /**
198
+ * Validates the UI5 system version based on the provided value or fetches all relevant versions if no value is provided.
199
+ * Updates the internal state with the fetched versions and the detection status.
200
+ *
201
+ * @returns {Promise<void>} Resolves after checking system ui5 version.
202
+ */
203
+ private validateSystemVersion;
122
204
  /**
123
205
  * Handles errors that occur while fetching system information, setting default values and rethrowing if necessary.
124
206
  *
125
207
  * @param {Error} error - The error encountered during the system info fetch.
126
208
  */
127
209
  private handleSystemError;
210
+ /**
211
+ * Validates the selected application for adaptation projects, checking for specific support flags
212
+ * and validating the application manifest.
213
+ *
214
+ * @returns {void} Returns when validation is complete.
215
+ */
216
+ private validateManifest;
217
+ /**
218
+ * Sets the support flags for given application.
219
+ *
220
+ * @param {SourceApplication} application - The application to validate.
221
+ * @param {boolean} isFullSupport - Flag to check for full AdpOverAdp support.
222
+ * @param {boolean} isPartialSupport - Flag to check for partial AdpOverAdp support.
223
+ * @returns {void} Returns when flags are set.
224
+ */
225
+ private setSupportFlags;
128
226
  }
129
227
  //# sourceMappingURL=configuration.d.ts.map
@@ -1,21 +1,21 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ConfigPrompter = void 0;
4
- const axios_extension_1 = require("@sap-ux/axios-extension");
5
- const project_input_validator_1 = require("@sap-ux/project-input-validator");
6
4
  const adp_tooling_1 = require("@sap-ux/adp-tooling");
5
+ const project_input_validator_1 = require("@sap-ux/project-input-validator");
6
+ const axios_extension_1 = require("@sap-ux/axios-extension");
7
7
  const i18n_1 = require("../../utils/i18n");
8
8
  const types_1 = require("../types");
9
9
  const choices_1 = require("./helper/choices");
10
10
  const conditions_1 = require("./helper/conditions");
11
- const fiori_generator_shared_1 = require("@sap-ux/fiori-generator-shared");
11
+ const additional_messages_1 = require("./helper/additional-messages");
12
12
  /**
13
13
  * A stateful prompter class that creates configuration questions.
14
14
  * This class accepts the needed dependencies and keeps track of state (e.g. the ApplicationManager instance).
15
15
  * It exposes a single public method {@link getPrompts} to retrieve the configuration questions.
16
16
  */
17
17
  class ConfigPrompter {
18
- targetSystems;
18
+ systemLookup;
19
19
  logger;
20
20
  /**
21
21
  * Indicates if the current layer is based on a customer base.
@@ -25,6 +25,10 @@ class ConfigPrompter {
25
25
  * Instance of AbapServiceProvider.
26
26
  */
27
27
  abapProvider;
28
+ /**
29
+ * Application manifest.
30
+ */
31
+ appManifest;
28
32
  /**
29
33
  * Loaded target applications for a system.
30
34
  */
@@ -37,17 +41,74 @@ class ConfigPrompter {
37
41
  * Flag indicating that system requires authentication in BAS or it does not exist in VS Code.
38
42
  */
39
43
  isAuthRequired;
44
+ /**
45
+ * Cached UI flexibility information from the system.
46
+ */
47
+ flexUISystem;
48
+ /**
49
+ * Flag indicating if the project is a cloud project.
50
+ */
51
+ isCloudProject;
52
+ /**
53
+ * Flag indicating whether the selected application is supported.
54
+ */
55
+ isApplicationSupported;
56
+ /**
57
+ * Indicates whether views are loaded synchronously.
58
+ */
59
+ containsSyncViews = false;
60
+ /**
61
+ * Flag indicating if the application is an internal V4 application.
62
+ */
63
+ isV4AppInternalMode = false;
64
+ /**
65
+ * Flag indicating that full adaptation-over-adaptation is supported.
66
+ */
67
+ isSupported = false;
68
+ /**
69
+ * Flag indicating that only partial adaptation-over-adaptation is supported.
70
+ */
71
+ isPartiallySupported = false;
72
+ /**
73
+ * UI5 version manager for handling version-related validations.
74
+ */
75
+ ui5Info;
76
+ /**
77
+ * Returns the configured abap provider instance.
78
+ *
79
+ * @returns Configured instance of AbapServiceProvider.
80
+ */
81
+ get provider() {
82
+ return this.abapProvider;
83
+ }
84
+ /**
85
+ * Returns the loaded application manifest.
86
+ *
87
+ * @returns Application manifest.
88
+ */
89
+ get manifest() {
90
+ return this.manifest;
91
+ }
92
+ /**
93
+ * Indicates whether the application loads views synchronously.
94
+ *
95
+ * @returns {boolean} True if views are sync-loaded.
96
+ */
97
+ get hasSyncViews() {
98
+ return this.containsSyncViews;
99
+ }
40
100
  /**
41
101
  * Creates an instance of ConfigPrompter.
42
102
  *
43
- * @param {TargetSystems} targetSystems - The target system class to retrieve system endpoints.
103
+ * @param {SystemLookup} systemLookup - The source system class to retrieve system endpoints.
44
104
  * @param {FlexLayer} layer - The FlexLayer used to determine the base (customer or otherwise).
45
105
  * @param {ToolsLogger} logger - Instance of the logger.
46
106
  */
47
- constructor(targetSystems, layer, logger) {
48
- this.targetSystems = targetSystems;
107
+ constructor(systemLookup, layer, logger) {
108
+ this.systemLookup = systemLookup;
49
109
  this.logger = logger;
50
110
  this.isCustomerBase = layer === "CUSTOMER_BASE" /* FlexLayer.CUSTOMER_BASE */;
111
+ this.ui5Info = adp_tooling_1.UI5VersionInfo.getInstance(layer);
51
112
  }
52
113
  /**
53
114
  * Retrieves an array of configuration questions based on provided options.
@@ -57,14 +118,13 @@ class ConfigPrompter {
57
118
  * @returns An array of configuration questions.
58
119
  */
59
120
  getPrompts(promptOptions) {
60
- const isCLI = (0, fiori_generator_shared_1.getHostEnvironment)() === fiori_generator_shared_1.hostEnvironment.cli;
61
121
  const keyedPrompts = {
62
122
  [types_1.configPromptNames.system]: this.getSystemListPrompt(promptOptions?.[types_1.configPromptNames.system]),
63
- [types_1.configPromptNames.systemValidationCli]: this.getSystemValidationPromptForCli({ hide: !isCLI }),
123
+ [types_1.configPromptNames.systemValidationCli]: this.getSystemValidationPromptForCli(),
64
124
  [types_1.configPromptNames.username]: this.getUsernamePrompt(promptOptions?.[types_1.configPromptNames.username]),
65
125
  [types_1.configPromptNames.password]: this.getPasswordPrompt(promptOptions?.[types_1.configPromptNames.password]),
66
126
  [types_1.configPromptNames.application]: this.getApplicationListPrompt(promptOptions?.[types_1.configPromptNames.application]),
67
- [types_1.configPromptNames.appValidationCli]: this.getApplicationValidationPromptForCli({ hide: !isCLI })
127
+ [types_1.configPromptNames.appValidationCli]: this.getApplicationValidationPromptForCli()
68
128
  };
69
129
  const questions = Object.entries(keyedPrompts)
70
130
  .filter(([promptName, _]) => {
@@ -86,7 +146,7 @@ class ConfigPrompter {
86
146
  name: types_1.configPromptNames.system,
87
147
  message: (0, i18n_1.t)('prompts.systemLabel'),
88
148
  choices: async () => {
89
- const systems = await this.targetSystems.getSystems();
149
+ const systems = await this.systemLookup.getSystems();
90
150
  return (0, adp_tooling_1.getEndpointNames)(systems);
91
151
  },
92
152
  guiOptions: {
@@ -95,20 +155,20 @@ class ConfigPrompter {
95
155
  hint: (0, i18n_1.t)('prompts.systemTooltip')
96
156
  },
97
157
  default: '',
98
- validate: async (value, answers) => await this.validateSystem(value, answers)
158
+ validate: async (value, answers) => await this.validateSystem(value, answers),
159
+ additionalMessages: () => (0, additional_messages_1.getSystemAdditionalMessages)(this.flexUISystem, !!this.isCloudProject)
99
160
  };
100
161
  }
101
162
  /**
102
163
  * Only used in the CLI context when prompt is of type `list` because the validation does not run on CLI for the system list prompt.
103
164
  *
104
- * @param {CliValidationPromptOptions} options - System validation CLI options (i.e "hide").
105
165
  * @returns Dummy prompt that runs in the CLI only.
106
166
  */
107
- getSystemValidationPromptForCli(options) {
167
+ getSystemValidationPromptForCli() {
108
168
  return {
109
169
  name: types_1.configPromptNames.systemValidationCli,
110
170
  when: async (answers) => {
111
- if (options.hide || !answers.system) {
171
+ if (!answers.system) {
112
172
  return false;
113
173
  }
114
174
  const result = await this.validateSystem(answers.system, answers);
@@ -180,24 +240,29 @@ class ConfigPrompter {
180
240
  },
181
241
  choices: () => (0, choices_1.getApplicationChoices)(this.targetApps),
182
242
  default: options?.default,
183
- validate: (value) => this.validateApplicationSelection(value),
184
- when: (answers) => (0, conditions_1.showApplicationQuestion)(answers, !!this.targetApps?.length, this.isAuthRequired, this.isLoginSuccessful)
243
+ validate: async (value) => await this.validateAppPrompt(value),
244
+ when: (answers) => (0, conditions_1.showApplicationQuestion)(answers, !!this.targetApps?.length, this.isAuthRequired, this.isLoginSuccessful),
245
+ additionalMessages: (app) => (0, additional_messages_1.getAppAdditionalMessages)(app, {
246
+ hasSyncViews: this.containsSyncViews,
247
+ isV4AppInternalMode: this.isV4AppInternalMode,
248
+ isSupported: this.isSupported && !this.isPartiallySupported,
249
+ isPartiallySupported: this.isPartiallySupported
250
+ }, this.isApplicationSupported)
185
251
  };
186
252
  }
187
253
  /**
188
254
  * Only used in the CLI context when prompt is of type `list` because the validation does not run on CLI for the application list prompt.
189
255
  *
190
- * @param {CliValidationPromptOptions} options - System validation CLI options (i.e "hide").
191
256
  * @returns Dummy prompt that runs in the CLI only.
192
257
  */
193
- getApplicationValidationPromptForCli(options) {
258
+ getApplicationValidationPromptForCli() {
194
259
  return {
195
260
  name: types_1.configPromptNames.appValidationCli,
196
261
  when: async (answers) => {
197
- if (options.hide || !answers.application) {
262
+ if (!answers.application) {
198
263
  return false;
199
264
  }
200
- const result = this.validateApplicationSelection(answers.application);
265
+ const result = await this.validateAppPrompt(answers.application);
201
266
  if (typeof result === 'string') {
202
267
  throw new Error(result);
203
268
  }
@@ -208,14 +273,16 @@ class ConfigPrompter {
208
273
  /**
209
274
  * Validates the selected application.
210
275
  *
211
- * @param {string} app - The selected application.
212
- * @returns An error message if validation fails, or true if the selection is valid.
276
+ * Checks if the application is provided and then evaluates support based on its manifest.
277
+ *
278
+ * @param {SourceApplication} app - The selected application.
279
+ * @returns A promise that resolves to true if valid, or an error message string if validation fails.
213
280
  */
214
- validateApplicationSelection(app) {
281
+ async validateAppPrompt(app) {
215
282
  if (!app) {
216
283
  return (0, i18n_1.t)('error.selectCannotBeEmptyError', { value: 'Application' });
217
284
  }
218
- return true;
285
+ return this.validateAppData(app);
219
286
  }
220
287
  /**
221
288
  * Validates the password by setting up the provider and, if necessary,
@@ -238,7 +305,7 @@ class ConfigPrompter {
238
305
  };
239
306
  try {
240
307
  this.abapProvider = await (0, adp_tooling_1.getConfiguredProvider)(options, this.logger);
241
- await this.getSystemInfo();
308
+ await this.getSystemData();
242
309
  this.targetApps = await (0, adp_tooling_1.loadApps)(this.abapProvider, this.isCustomerBase);
243
310
  this.isLoginSuccessful = true;
244
311
  return true;
@@ -270,31 +337,104 @@ class ConfigPrompter {
270
337
  try {
271
338
  this.targetApps = [];
272
339
  this.abapProvider = await (0, adp_tooling_1.getConfiguredProvider)(options, this.logger);
273
- this.isAuthRequired = await this.targetSystems.getSystemRequiresAuth(system);
340
+ this.isAuthRequired = await this.systemLookup.getSystemRequiresAuth(system);
274
341
  if (!this.isAuthRequired) {
275
- await this.getSystemInfo();
342
+ const validationResult = await this.handleSystemDataValidation();
343
+ if (typeof validationResult === 'string') {
344
+ return validationResult;
345
+ }
276
346
  this.targetApps = await (0, adp_tooling_1.loadApps)(this.abapProvider, this.isCustomerBase);
277
347
  }
348
+ return true;
349
+ }
350
+ catch (e) {
351
+ return e.message;
352
+ }
353
+ }
354
+ /**
355
+ * Validates the selected application to ensure it is supported.
356
+ *
357
+ * @param {Application} app - The application to validate.
358
+ * @returns {Promise<boolean | string>} True if the application is valid, otherwise an error message.
359
+ */
360
+ async validateAppData(app) {
361
+ try {
362
+ const sourceManifest = new adp_tooling_1.SourceManifest(this.abapProvider, app.id, this.logger);
363
+ const isSupported = await (0, adp_tooling_1.isAppSupported)(this.abapProvider, app.id, this.logger);
364
+ if (isSupported) {
365
+ this.appManifest = await sourceManifest.getManifest();
366
+ this.validateManifest();
367
+ this.evaluateAppSupport(app);
368
+ }
369
+ this.isApplicationSupported = true;
278
370
  }
279
371
  catch (e) {
372
+ this.isApplicationSupported = false;
373
+ this.logger.debug(`Application failed validation. Reason: ${e.message}`);
280
374
  return e.message;
281
375
  }
282
376
  return true;
283
377
  }
284
378
  /**
285
- * Fetches system information from the provider's layered repository.
379
+ * Evaluate if the application version supports certain features.
380
+ *
381
+ * @param {Application} application - The application data.
382
+ */
383
+ evaluateAppSupport(application) {
384
+ const systemVersion = this.ui5Info.systemVersion;
385
+ const isFullSupport = this.ui5Info.isVersionDetected && !(0, adp_tooling_1.isFeatureSupportedVersion)('1.96.0', systemVersion);
386
+ const isPartialSupport = this.ui5Info.isVersionDetected && isFullSupport && (0, adp_tooling_1.isFeatureSupportedVersion)('1.90.0', systemVersion);
387
+ this.setSupportFlags(application, isFullSupport, isPartialSupport);
388
+ }
389
+ /**
390
+ * Fetches system data including cloud project and UI flexibility information.
286
391
  *
287
- * @returns {SystemInfo} System into containing system supported adaptation project types and translations.
392
+ * @returns A promise that resolves when system data is fetched.
288
393
  */
289
- async getSystemInfo() {
394
+ async getSystemData() {
290
395
  try {
291
- const lrep = this.abapProvider.getLayeredRepository();
292
- await lrep.getSystemInfo();
396
+ this.isCloudProject = await this.abapProvider.isAbapCloud();
397
+ this.flexUISystem = await (0, adp_tooling_1.getFlexUISupportedSystem)(this.abapProvider, this.isCustomerBase);
293
398
  }
294
399
  catch (e) {
295
400
  this.handleSystemError(e);
296
401
  }
297
402
  }
403
+ /**
404
+ * Handles the fetching and validation of system data.
405
+ *
406
+ * @returns {Promise<boolean | string>} True if successful, or an error message if an error occurs.
407
+ */
408
+ async handleSystemDataValidation() {
409
+ try {
410
+ await this.getSystemData();
411
+ await this.validateSystemVersion();
412
+ if (!this.isCustomerBase && this.isCloudProject) {
413
+ return (0, i18n_1.t)('error.cloudSystemsForInternalUsers');
414
+ }
415
+ return true;
416
+ }
417
+ catch (e) {
418
+ this.logger.debug(`Validating system failed. Reason: ${e.message}`);
419
+ return e.message;
420
+ }
421
+ }
422
+ /**
423
+ * Validates the UI5 system version based on the provided value or fetches all relevant versions if no value is provided.
424
+ * Updates the internal state with the fetched versions and the detection status.
425
+ *
426
+ * @returns {Promise<void>} Resolves after checking system ui5 version.
427
+ */
428
+ async validateSystemVersion() {
429
+ try {
430
+ const version = await (0, adp_tooling_1.getSystemUI5Version)(this.abapProvider);
431
+ await this.ui5Info.getRelevantVersions(version);
432
+ }
433
+ catch (e) {
434
+ this.logger.debug(`Could not fetch system version: ${e.message}`);
435
+ await this.ui5Info.getRelevantVersions();
436
+ }
437
+ }
298
438
  /**
299
439
  * Handles errors that occur while fetching system information, setting default values and rethrowing if necessary.
300
440
  *
@@ -306,8 +446,42 @@ class ConfigPrompter {
306
446
  if (error.response?.status === 401 || error.response?.status === 403) {
307
447
  throw new Error(`Authentication error: ${error.message}`);
308
448
  }
449
+ if (error.response?.status === 405 || error.response?.status === 404) {
450
+ // Handle the case where the API is not available and continue to standard onPremise flow
451
+ this.isCloudProject = false;
452
+ return;
453
+ }
309
454
  }
310
455
  }
456
+ /**
457
+ * Validates the selected application for adaptation projects, checking for specific support flags
458
+ * and validating the application manifest.
459
+ *
460
+ * @returns {void} Returns when validation is complete.
461
+ */
462
+ validateManifest() {
463
+ if (!this.appManifest) {
464
+ throw new Error((0, i18n_1.t)('error.manifestCouldNotBeValidated'));
465
+ }
466
+ const ui5 = this.appManifest?.['sap.ui5'];
467
+ if (ui5?.flexEnabled === false) {
468
+ throw new Error((0, i18n_1.t)('error.appDoesNotSupportAdaptation'));
469
+ }
470
+ }
471
+ /**
472
+ * Sets the support flags for given application.
473
+ *
474
+ * @param {SourceApplication} application - The application to validate.
475
+ * @param {boolean} isFullSupport - Flag to check for full AdpOverAdp support.
476
+ * @param {boolean} isPartialSupport - Flag to check for partial AdpOverAdp support.
477
+ * @returns {void} Returns when flags are set.
478
+ */
479
+ setSupportFlags(application, isFullSupport, isPartialSupport) {
480
+ this.isSupported = !(isFullSupport && application.fileType === 'appdescr_variant');
481
+ this.isPartiallySupported = isPartialSupport && application.fileType === 'appdescr_variant';
482
+ this.isV4AppInternalMode = (0, adp_tooling_1.isV4Application)(this.appManifest) && !this.isCustomerBase;
483
+ this.containsSyncViews = (0, adp_tooling_1.isSyncLoadedView)(this.appManifest?.['sap.ui5']);
484
+ }
311
485
  }
312
486
  exports.ConfigPrompter = ConfigPrompter;
313
487
  //# sourceMappingURL=configuration.js.map
@@ -0,0 +1,35 @@
1
+ import { Severity } from '@sap-devx/yeoman-ui-types';
2
+ import type { FlexUISupportedSystem, SourceApplication } from '@sap-ux/adp-tooling';
3
+ interface SupportFlags {
4
+ hasSyncViews: boolean;
5
+ isV4AppInternalMode: boolean;
6
+ isSupported: boolean;
7
+ isPartiallySupported: boolean;
8
+ }
9
+ /**
10
+ * Evaluates a system's deployment and flexibility capabilities to generate relevant messages based on the system's characteristics.
11
+ *
12
+ * @param {FlexUISupportedSystem | undefined} flexUISystem - An optional object containing flags indicating if the system
13
+ * is on-premise and whether UI Flex is enabled.
14
+ * @param isCloudProject
15
+ * @returns {{message: string, severity: Severity} | undefined} An object containing a message and its severity level.
16
+ */
17
+ export declare const getSystemAdditionalMessages: (flexUISystem: FlexUISupportedSystem | undefined, isCloudProject: boolean) => {
18
+ message: string;
19
+ severity: Severity;
20
+ } | undefined;
21
+ /**
22
+ * Provides an additional contextual message for the selected application, based on its compatibility,
23
+ * feature support, or sync-loading behavior.
24
+ *
25
+ * @param {SourceApplication} app - The selected application object.
26
+ * @param {SupportFlags} flags - Flags indicating support for sync views, Adp-over-Adp, and V4 internal apps.
27
+ * @param {boolean} isApplicationSupported - Indicates whether the application is supported at all.
28
+ * @returns {{ message: string; severity: Severity } | undefined} Message object or undefined if no message is applicable.
29
+ */
30
+ export declare const getAppAdditionalMessages: (app: SourceApplication, { hasSyncViews, isSupported, isPartiallySupported, isV4AppInternalMode }: SupportFlags, isApplicationSupported: boolean) => {
31
+ message: string;
32
+ severity: Severity;
33
+ } | undefined;
34
+ export {};
35
+ //# sourceMappingURL=additional-messages.d.ts.map
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getAppAdditionalMessages = exports.getSystemAdditionalMessages = void 0;
4
+ const yeoman_ui_types_1 = require("@sap-devx/yeoman-ui-types");
5
+ const axios_extension_1 = require("@sap-ux/axios-extension");
6
+ const i18n_1 = require("../../../utils/i18n");
7
+ /**
8
+ * Evaluates a system's deployment and flexibility capabilities to generate relevant messages based on the system's characteristics.
9
+ *
10
+ * @param {FlexUISupportedSystem | undefined} flexUISystem - An optional object containing flags indicating if the system
11
+ * is on-premise and whether UI Flex is enabled.
12
+ * @param isCloudProject
13
+ * @returns {{message: string, severity: Severity} | undefined} An object containing a message and its severity level.
14
+ */
15
+ const getSystemAdditionalMessages = (flexUISystem, isCloudProject) => {
16
+ const isOnPremise = flexUISystem?.isOnPremise;
17
+ const isUIFlex = flexUISystem?.isUIFlex;
18
+ if (isCloudProject) {
19
+ return {
20
+ message: `${(0, i18n_1.t)('prompts.projectTypeLabel')}: ${axios_extension_1.AdaptationProjectType.CLOUD_READY}`,
21
+ severity: yeoman_ui_types_1.Severity.information
22
+ };
23
+ }
24
+ if (!isOnPremise) {
25
+ if (!isUIFlex) {
26
+ return {
27
+ message: (0, i18n_1.t)('error.notDeployableNotFlexEnabledSystemError'),
28
+ severity: yeoman_ui_types_1.Severity.error
29
+ };
30
+ }
31
+ else {
32
+ return {
33
+ message: (0, i18n_1.t)('error.notDeployableSystemError'),
34
+ severity: yeoman_ui_types_1.Severity.error
35
+ };
36
+ }
37
+ }
38
+ if (isOnPremise && !isUIFlex) {
39
+ return {
40
+ message: (0, i18n_1.t)('error.notFlexEnabledError'),
41
+ severity: yeoman_ui_types_1.Severity.warning
42
+ };
43
+ }
44
+ return {
45
+ message: `${(0, i18n_1.t)('prompts.projectTypeLabel')}: ${axios_extension_1.AdaptationProjectType.ON_PREMISE}`,
46
+ severity: yeoman_ui_types_1.Severity.information
47
+ };
48
+ };
49
+ exports.getSystemAdditionalMessages = getSystemAdditionalMessages;
50
+ /**
51
+ * Provides an additional contextual message for the selected application, based on its compatibility,
52
+ * feature support, or sync-loading behavior.
53
+ *
54
+ * @param {SourceApplication} app - The selected application object.
55
+ * @param {SupportFlags} flags - Flags indicating support for sync views, Adp-over-Adp, and V4 internal apps.
56
+ * @param {boolean} isApplicationSupported - Indicates whether the application is supported at all.
57
+ * @returns {{ message: string; severity: Severity } | undefined} Message object or undefined if no message is applicable.
58
+ */
59
+ const getAppAdditionalMessages = (app, { hasSyncViews, isSupported, isPartiallySupported, isV4AppInternalMode }, isApplicationSupported) => {
60
+ if (!app) {
61
+ return undefined;
62
+ }
63
+ if (hasSyncViews && isApplicationSupported) {
64
+ return {
65
+ message: (0, i18n_1.t)('prompts.appInfoLabel'),
66
+ severity: yeoman_ui_types_1.Severity.information
67
+ };
68
+ }
69
+ if (!isSupported && !isPartiallySupported && isApplicationSupported) {
70
+ return {
71
+ message: (0, i18n_1.t)('prompts.notSupportedAdpOverAdpLabel'),
72
+ severity: yeoman_ui_types_1.Severity.warning
73
+ };
74
+ }
75
+ if (isPartiallySupported && isApplicationSupported) {
76
+ return {
77
+ message: (0, i18n_1.t)('prompts.isPartiallySupportedAdpOverAdpLabel'),
78
+ severity: yeoman_ui_types_1.Severity.warning
79
+ };
80
+ }
81
+ if (isV4AppInternalMode) {
82
+ return {
83
+ message: (0, i18n_1.t)('prompts.v4AppNotOfficialLabel'),
84
+ severity: yeoman_ui_types_1.Severity.warning
85
+ };
86
+ }
87
+ };
88
+ exports.getAppAdditionalMessages = getAppAdditionalMessages;
89
+ //# sourceMappingURL=additional-messages.js.map
@@ -1,15 +1,15 @@
1
- import type { TargetApplication } from '@sap-ux/adp-tooling';
1
+ import type { SourceApplication } from '@sap-ux/adp-tooling';
2
2
  interface Choice {
3
3
  name: string;
4
- value: TargetApplication;
4
+ value: SourceApplication;
5
5
  }
6
6
  /**
7
7
  * Creates a list of choices from a list of applications, formatted for display or selection in a UI.
8
8
  * Each choice consists of an application's title (or ID if no title), followed by its registration IDs and ACH, formatted for easy reading.
9
9
  *
10
- * @param {TargetApplication[]} apps - An array of applications to be transformed into display choices.
10
+ * @param {SourceApplication[]} apps - An array of applications to be transformed into display choices.
11
11
  * @returns {Choice[]} An array of objects each containing a value (the full application object) and a name (a formatted string).
12
12
  */
13
- export declare const getApplicationChoices: (apps: TargetApplication[]) => Choice[];
13
+ export declare const getApplicationChoices: (apps: SourceApplication[]) => Choice[];
14
14
  export {};
15
15
  //# sourceMappingURL=choices.d.ts.map
@@ -5,7 +5,7 @@ exports.getApplicationChoices = void 0;
5
5
  * Creates a list of choices from a list of applications, formatted for display or selection in a UI.
6
6
  * Each choice consists of an application's title (or ID if no title), followed by its registration IDs and ACH, formatted for easy reading.
7
7
  *
8
- * @param {TargetApplication[]} apps - An array of applications to be transformed into display choices.
8
+ * @param {SourceApplication[]} apps - An array of applications to be transformed into display choices.
9
9
  * @returns {Choice[]} An array of objects each containing a value (the full application object) and a name (a formatted string).
10
10
  */
11
11
  const getApplicationChoices = (apps) => {
@@ -11,12 +11,23 @@
11
11
  "passwordLabel": "Password",
12
12
  "passwordTooltip": "Enter the password for the back-end system.",
13
13
  "applicationListLabel": "Application",
14
- "applicationListTooltip": "Select the application for which you want to create an app variant."
14
+ "applicationListTooltip": "Select the application for which you want to create an app variant.",
15
+ "projectTypeLabel": "Project Type",
16
+ "appInfoLabel": "Synchronous views are detected for this application. Therefore, the controller extensions are not supported. Controller extension functionality on these views will be disabled.",
17
+ "notSupportedAdpOverAdpLabel": "You have selected 'Adaptation Project' as the base. The selected system has a SAPUI5 version lower than 1.90. Therefore, it does not support 'Adaptation Project' as а base for a new adaptation project. You will be able to create such а project, but after deployment it will not work until the SAPUI5 version of the system is updated.",
18
+ "isPartiallySupportedAdpOverAdpLabel": "You have selected 'Adaptation Project' as the base. The selected system has a SAPUI5 version lower than 1.96 and in order for your adaptation project based on adaptation project to work after deployment, you will need to apply SAP Note 756 SP0 on your system.",
19
+ "v4AppNotOfficialLabel": "You have selected an app based on SAP Fiori elements for OData V4. Note the following important information when you create adaptation changes: https://wiki.wdf.sap.corp/wiki/display/fioritech/Adaptation+Project+Support"
15
20
  },
16
21
  "error": {
17
22
  "selectCannotBeEmptyError": "{{value}} has to be selected.",
18
23
  "writingPhase": "An error occurred in the writing phase of the adaptation project generation. To see the error, view the logs.",
19
24
  "telemetry": "An error occurred when sending telemetry data: {{- error}}. To see the error, view the logs.",
20
- "updatingApp": "An error occurred when creating a new adaptation project. To see the error, view the logs."
25
+ "updatingApp": "An error occurred when creating a new adaptation project. To see the error, view the logs.",
26
+ "cloudSystemsForInternalUsers": "You have selected a system that does not support On-Premise adaptation projects. Please select a supported system.",
27
+ "notDeployableNotFlexEnabledSystemError": "The system that you have selected is not an ABAP On-Premise system. Adaptation projects are only supported on those systems. Please choose an ABAP On-Premise system which supports flexibility and DTA_FOLDER deployment.",
28
+ "notDeployableSystemError": "The system that you have selected is not an ABAP On-Premise system which supports DTA_FOLDER deployment. Adaptation projects are only supported on those systems. Please choose an ABAP On-Premise system which supports DTA_FOLDER deployment.",
29
+ "notFlexEnabledError": "The system that you have selected is not an ABAP On-Premise system which supports flexibility. Adaptation projects are only supported on those systems. Please choose an ABAP On-Premise system which supports flexibility. If you continue, you will only be able to create an extension project.",
30
+ "manifestCouldNotBeValidated": "The manifest.json file of the selected application could not be validated. Please select a different application.",
31
+ "appDoesNotSupportAdaptation": "The application that you have selected does not support flexibility. Adaptation projects are only supported with those applications. Please choose an application which supports flexibility."
21
32
  }
22
33
  }
@@ -1,3 +1,10 @@
1
+ import type { Package } from '@sap-ux/project-access';
2
+ /**
3
+ * Reads the package.json of the current package.
4
+ *
5
+ * @returns {Package} Package.json of the current package.
6
+ */
7
+ export declare function getPackageInfo(): Package;
1
8
  /**
2
9
  * Installs dependencies in the project directory.
3
10
  *
@@ -23,9 +23,20 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.installDependencies = void 0;
26
+ exports.installDependencies = exports.getPackageInfo = void 0;
27
+ const path_1 = require("path");
27
28
  const util = __importStar(require("util"));
29
+ const fs_1 = require("fs");
28
30
  const child_process_1 = require("child_process");
31
+ /**
32
+ * Reads the package.json of the current package.
33
+ *
34
+ * @returns {Package} Package.json of the current package.
35
+ */
36
+ function getPackageInfo() {
37
+ return JSON.parse((0, fs_1.readFileSync)((0, path_1.join)(__dirname, '../../package.json'), 'utf-8'));
38
+ }
39
+ exports.getPackageInfo = getPackageInfo;
29
40
  /**
30
41
  * Installs dependencies in the project directory.
31
42
  *
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@sap-ux/generator-adp",
3
3
  "displayName": "SAPUI5 Adaptation Project",
4
4
  "description": "Adaptation project allows you to create an app variant for an existing SAP Fiori elements-based or SAPUI5 freestyle application, without changing the original application.",
5
- "version": "0.1.1",
5
+ "version": "0.1.3",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "https://github.com/SAP/open-ux-tools.git",
@@ -29,7 +29,7 @@
29
29
  "i18next": "23.5.1",
30
30
  "yeoman-generator": "5.10.0",
31
31
  "uuid": "10.0.0",
32
- "@sap-ux/adp-tooling": "0.13.22",
32
+ "@sap-ux/adp-tooling": "0.13.24",
33
33
  "@sap-ux/axios-extension": "1.19.2",
34
34
  "@sap-ux/btp-utils": "1.0.2",
35
35
  "@sap-ux/feature-toggle": "0.2.3",