@sap-ux/generator-adp 0.2.0 → 0.2.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/generators/app/extension-project/index.d.ts +24 -0
- package/generators/app/extension-project/index.js +73 -0
- package/generators/app/index.d.ts +4 -0
- package/generators/app/index.js +38 -6
- package/generators/app/questions/attributes.js +2 -3
- package/generators/app/questions/configuration.d.ts +28 -0
- package/generators/app/questions/configuration.js +89 -4
- package/generators/app/questions/helper/conditions.d.ts +21 -1
- package/generators/app/questions/helper/conditions.js +37 -1
- package/generators/app/questions/helper/message.d.ts +9 -0
- package/generators/app/questions/helper/message.js +18 -0
- package/generators/app/questions/helper/validators.d.ts +10 -0
- package/generators/app/questions/helper/validators.js +22 -1
- package/generators/app/types.d.ts +31 -1
- package/generators/app/types.js +3 -0
- package/generators/translations/generator-adp.i18n.json +13 -1
- package/package.json +5 -5
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type AttributesAnswers, type ConfigAnswers, type SystemLookup } from '@sap-ux/adp-tooling';
|
|
2
|
+
import type { ExtensionProjectData } from '../types';
|
|
3
|
+
export declare const EXTENSIBILITY_GENERATOR_NS = "@bas-dev/generator-extensibility-sub/generators/app";
|
|
4
|
+
/**
|
|
5
|
+
* Prepares data required for generating an extension project.
|
|
6
|
+
*
|
|
7
|
+
* @param {ConfigAnswers} configAnswers - The configuration answers including system, user, and app selection.
|
|
8
|
+
* @param {AttributesAnswers} attributeAnswers - The basic project attributes like name, namespace, version.
|
|
9
|
+
* @param {SystemLookup} systemLookup - The lookup service for system destination info.
|
|
10
|
+
* @returns {Promise<ExtensionProjectData>} A promise resolving to the prepared extension project data object.
|
|
11
|
+
*/
|
|
12
|
+
export declare function getExtensionProjectData(configAnswers: ConfigAnswers, attributeAnswers: AttributesAnswers, systemLookup: SystemLookup): Promise<ExtensionProjectData>;
|
|
13
|
+
/**
|
|
14
|
+
* Attempts to resolve the path to a specific node module generator from the NODE_PATH environment variable.
|
|
15
|
+
* This is particularly used in the prompt for extension projects within SAP Business Application Studio (BAS)
|
|
16
|
+
* when an application is not supported by the adaptation project. It functions by resolving the path to the
|
|
17
|
+
* generator which is then utilized with `this.composeWith()` of the Yeoman generator. If the path to the generator
|
|
18
|
+
* is found, it returns the path, allowing the extension project to continue. If no path is found, it indicates that
|
|
19
|
+
* the Extensibility Generator is not installed in the development space, preventing the user from proceeding.
|
|
20
|
+
*
|
|
21
|
+
* @returns {string | undefined} The resolved path to the generator module if found, or undefined if not found.
|
|
22
|
+
*/
|
|
23
|
+
export declare function resolveNodeModuleGenerator(): string | undefined;
|
|
24
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveNodeModuleGenerator = exports.getExtensionProjectData = exports.EXTENSIBILITY_GENERATOR_NS = void 0;
|
|
4
|
+
const path_1 = require("path");
|
|
5
|
+
const adp_tooling_1 = require("@sap-ux/adp-tooling");
|
|
6
|
+
const i18n_1 = require("../../utils/i18n");
|
|
7
|
+
exports.EXTENSIBILITY_GENERATOR_NS = '@bas-dev/generator-extensibility-sub/generators/app';
|
|
8
|
+
/**
|
|
9
|
+
* Prepares data required for generating an extension project.
|
|
10
|
+
*
|
|
11
|
+
* @param {ConfigAnswers} configAnswers - The configuration answers including system, user, and app selection.
|
|
12
|
+
* @param {AttributesAnswers} attributeAnswers - The basic project attributes like name, namespace, version.
|
|
13
|
+
* @param {SystemLookup} systemLookup - The lookup service for system destination info.
|
|
14
|
+
* @returns {Promise<ExtensionProjectData>} A promise resolving to the prepared extension project data object.
|
|
15
|
+
*/
|
|
16
|
+
async function getExtensionProjectData(configAnswers, attributeAnswers, systemLookup) {
|
|
17
|
+
const { application, system, username, password } = configAnswers;
|
|
18
|
+
if (!application) {
|
|
19
|
+
throw new Error((0, i18n_1.t)('error.appParameterMissing'));
|
|
20
|
+
}
|
|
21
|
+
const destinationInfo = await systemLookup.getSystemByName(system);
|
|
22
|
+
if (!destinationInfo) {
|
|
23
|
+
throw new Error((0, i18n_1.t)('error.destinationInfoMissing'));
|
|
24
|
+
}
|
|
25
|
+
const { projectName, namespace, ui5Version } = attributeAnswers;
|
|
26
|
+
return {
|
|
27
|
+
username,
|
|
28
|
+
password,
|
|
29
|
+
destination: {
|
|
30
|
+
name: destinationInfo.Name,
|
|
31
|
+
basUsage: destinationInfo.WebIDEUsage,
|
|
32
|
+
host: destinationInfo.Host,
|
|
33
|
+
sapClient: destinationInfo['sap-client']
|
|
34
|
+
},
|
|
35
|
+
applicationNS: namespace,
|
|
36
|
+
applicationName: projectName,
|
|
37
|
+
userUI5Ver: (0, adp_tooling_1.getFormattedVersion)(ui5Version),
|
|
38
|
+
BSPUrl: application.bspUrl,
|
|
39
|
+
namespace: application.id
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
exports.getExtensionProjectData = getExtensionProjectData;
|
|
43
|
+
/**
|
|
44
|
+
* Attempts to resolve the path to a specific node module generator from the NODE_PATH environment variable.
|
|
45
|
+
* This is particularly used in the prompt for extension projects within SAP Business Application Studio (BAS)
|
|
46
|
+
* when an application is not supported by the adaptation project. It functions by resolving the path to the
|
|
47
|
+
* generator which is then utilized with `this.composeWith()` of the Yeoman generator. If the path to the generator
|
|
48
|
+
* is found, it returns the path, allowing the extension project to continue. If no path is found, it indicates that
|
|
49
|
+
* the Extensibility Generator is not installed in the development space, preventing the user from proceeding.
|
|
50
|
+
*
|
|
51
|
+
* @returns {string | undefined} The resolved path to the generator module if found, or undefined if not found.
|
|
52
|
+
*/
|
|
53
|
+
function resolveNodeModuleGenerator() {
|
|
54
|
+
const nodePath = process.env['NODE_PATH'];
|
|
55
|
+
const nodePaths = nodePath?.split(':') ?? [];
|
|
56
|
+
let generator;
|
|
57
|
+
for (const path of nodePaths) {
|
|
58
|
+
try {
|
|
59
|
+
generator = require.resolve((0, path_1.resolve)(path, exports.EXTENSIBILITY_GENERATOR_NS));
|
|
60
|
+
}
|
|
61
|
+
catch (e) {
|
|
62
|
+
/**
|
|
63
|
+
* We don't care if there's an error while resolving the module, continue with the next node_module path
|
|
64
|
+
*/
|
|
65
|
+
}
|
|
66
|
+
if (generator !== undefined) {
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return generator;
|
|
71
|
+
}
|
|
72
|
+
exports.resolveNodeModuleGenerator = resolveNodeModuleGenerator;
|
|
73
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -71,6 +71,10 @@ export default class extends Generator {
|
|
|
71
71
|
writing(): Promise<void>;
|
|
72
72
|
install(): Promise<void>;
|
|
73
73
|
end(): void;
|
|
74
|
+
/**
|
|
75
|
+
* Generates an extension project if the application is not supported by Adaptation Project.
|
|
76
|
+
*/
|
|
77
|
+
private _generateExtensionProject;
|
|
74
78
|
/**
|
|
75
79
|
* Combines the target folder and project name.
|
|
76
80
|
*
|
package/generators/app/index.js
CHANGED
|
@@ -10,16 +10,17 @@ const adp_tooling_1 = require("@sap-ux/adp-tooling");
|
|
|
10
10
|
const feature_toggle_1 = require("@sap-ux/feature-toggle");
|
|
11
11
|
const fiori_generator_shared_1 = require("@sap-ux/fiori-generator-shared");
|
|
12
12
|
const logger_1 = require("@sap-ux/logger");
|
|
13
|
-
const
|
|
14
|
-
const deps_1 = require("../utils/deps");
|
|
13
|
+
const layer_1 = require("./layer");
|
|
15
14
|
const i18n_1 = require("../utils/i18n");
|
|
15
|
+
const telemetryEvents_1 = require("../telemetryEvents");
|
|
16
16
|
const logger_2 = __importDefault(require("../utils/logger"));
|
|
17
|
-
const parse_json_input_1 = require("../utils/parse-json-input");
|
|
18
|
-
const layer_1 = require("./layer");
|
|
19
17
|
const attributes_1 = require("./questions/attributes");
|
|
20
18
|
const configuration_1 = require("./questions/configuration");
|
|
21
|
-
const default_values_1 = require("./questions/helper/default-values");
|
|
22
19
|
const validators_1 = require("./questions/helper/validators");
|
|
20
|
+
const deps_1 = require("../utils/deps");
|
|
21
|
+
const parse_json_input_1 = require("../utils/parse-json-input");
|
|
22
|
+
const extension_project_1 = require("./extension-project");
|
|
23
|
+
const default_values_1 = require("./questions/helper/default-values");
|
|
23
24
|
/**
|
|
24
25
|
* Generator for creating an Adaptation Project.
|
|
25
26
|
*
|
|
@@ -143,7 +144,8 @@ class default_1 extends yeoman_generator_1.default {
|
|
|
143
144
|
const defaultFolder = (0, fiori_generator_shared_1.getDefaultTargetFolder)(this.options.vscode) ?? process.cwd();
|
|
144
145
|
const options = {
|
|
145
146
|
targetFolder: { default: defaultFolder },
|
|
146
|
-
ui5ValidationCli: { hide: !isCLI }
|
|
147
|
+
ui5ValidationCli: { hide: !isCLI },
|
|
148
|
+
enableTypeScript: { hide: !!this.configAnswers.shouldCreateExtProject }
|
|
147
149
|
};
|
|
148
150
|
const attributesQuestions = (0, attributes_1.getPrompts)(this.destinationPath(), promptConfig, options);
|
|
149
151
|
this.attributeAnswers = await this.prompt(attributesQuestions);
|
|
@@ -154,6 +156,10 @@ class default_1 extends yeoman_generator_1.default {
|
|
|
154
156
|
await this._initFromJson();
|
|
155
157
|
}
|
|
156
158
|
try {
|
|
159
|
+
if (this.configAnswers.shouldCreateExtProject) {
|
|
160
|
+
await this._generateExtensionProject();
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
157
163
|
const provider = this.jsonInput ? this.abapProvider : this.prompter.provider;
|
|
158
164
|
const publicVersions = this.jsonInput ? this.publicVersions : this.prompter.ui5.publicVersions;
|
|
159
165
|
const packageJson = (0, deps_1.getPackageInfo)();
|
|
@@ -161,6 +167,7 @@ class default_1 extends yeoman_generator_1.default {
|
|
|
161
167
|
provider,
|
|
162
168
|
configAnswers: this.configAnswers,
|
|
163
169
|
attributeAnswers: this.attributeAnswers,
|
|
170
|
+
systemVersion: this.prompter?.ui5?.systemVersion,
|
|
164
171
|
publicVersions,
|
|
165
172
|
layer: this.layer,
|
|
166
173
|
packageJson,
|
|
@@ -193,6 +200,31 @@ class default_1 extends yeoman_generator_1.default {
|
|
|
193
200
|
this.logger.error((0, i18n_1.t)('error.telemetry', { error }));
|
|
194
201
|
});
|
|
195
202
|
}
|
|
203
|
+
try {
|
|
204
|
+
this.vscode?.commands?.executeCommand?.('sap.ux.application.info', { fsPath: this._getProjectPath() });
|
|
205
|
+
}
|
|
206
|
+
catch (e) {
|
|
207
|
+
this.appWizard.showError(e.message, yeoman_ui_types_1.MessageType.notification);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Generates an extension project if the application is not supported by Adaptation Project.
|
|
212
|
+
*/
|
|
213
|
+
async _generateExtensionProject() {
|
|
214
|
+
try {
|
|
215
|
+
const data = await (0, extension_project_1.getExtensionProjectData)(this.configAnswers, this.attributeAnswers, this.systemLookup);
|
|
216
|
+
const generator = (0, extension_project_1.resolveNodeModuleGenerator)();
|
|
217
|
+
this.composeWith(generator, {
|
|
218
|
+
arguments: [JSON.stringify(data)],
|
|
219
|
+
appWizard: this.appWizard
|
|
220
|
+
});
|
|
221
|
+
this.logger.info(`'@bas-dev/generator-extensibility-sub' was called.`);
|
|
222
|
+
}
|
|
223
|
+
catch (e) {
|
|
224
|
+
this.logger.info((0, i18n_1.t)('error.creatingExtensionProjectError'));
|
|
225
|
+
this.logger.error(e.message);
|
|
226
|
+
this.appWizard.showError(e.message, yeoman_ui_types_1.MessageType.notification);
|
|
227
|
+
}
|
|
196
228
|
}
|
|
197
229
|
/**
|
|
198
230
|
* Combines the target folder and project name.
|
|
@@ -181,16 +181,15 @@ function getUi5VersionValidationPromptForCli() {
|
|
|
181
181
|
/**
|
|
182
182
|
* Creates the TypeScript enablement confirm prompt.
|
|
183
183
|
*
|
|
184
|
-
* @param {EnableTypeScriptPromptOptions} [
|
|
184
|
+
* @param {EnableTypeScriptPromptOptions} [_] - Optional prompt options to control visibility.
|
|
185
185
|
* @returns {AttributesQuestion} The prompt configuration for TypeScript confirmation.
|
|
186
186
|
*/
|
|
187
|
-
function getEnableTypeScriptPrompt(
|
|
187
|
+
function getEnableTypeScriptPrompt(_) {
|
|
188
188
|
return {
|
|
189
189
|
type: 'confirm',
|
|
190
190
|
name: types_1.attributePromptNames.enableTypeScript,
|
|
191
191
|
message: 'Enable TypeScript',
|
|
192
192
|
default: false,
|
|
193
|
-
when: options?.hide ?? true,
|
|
194
193
|
guiOptions: {
|
|
195
194
|
breadcrumb: true
|
|
196
195
|
}
|
|
@@ -109,6 +109,12 @@ export declare class ConfigPrompter {
|
|
|
109
109
|
* @returns {boolean} True if views are sync-loaded.
|
|
110
110
|
*/
|
|
111
111
|
get hasSyncViews(): boolean;
|
|
112
|
+
/**
|
|
113
|
+
* Indicates whether the application is supported by Adaptation Project.
|
|
114
|
+
*
|
|
115
|
+
* @returns {boolean} True if the application is supported.
|
|
116
|
+
*/
|
|
117
|
+
get isAppSupported(): boolean;
|
|
112
118
|
/**
|
|
113
119
|
* Creates an instance of ConfigPrompter.
|
|
114
120
|
*
|
|
@@ -165,6 +171,28 @@ export declare class ConfigPrompter {
|
|
|
165
171
|
* @returns Dummy prompt that runs in the CLI only.
|
|
166
172
|
*/
|
|
167
173
|
private getApplicationValidationPromptForCli;
|
|
174
|
+
/**
|
|
175
|
+
* Creates an input prompt for entering the Fiori ID.
|
|
176
|
+
*
|
|
177
|
+
* @param {FioriIdPromptOptions} _ - Optional configuration for Fiori ID prompt.
|
|
178
|
+
* @returns {InputQuestion<ConfigAnswers>} An input prompt for the Fiori ID.
|
|
179
|
+
*/
|
|
180
|
+
private getFioriIdPrompt;
|
|
181
|
+
/**
|
|
182
|
+
* Generates an input prompt for entering the Application Component Hierarchy code for a project.
|
|
183
|
+
*
|
|
184
|
+
* @param {AchPromptOptions} _ - Optional configuration for ACH prompt.
|
|
185
|
+
* @returns {InputQuestion<ConfigAnswers>} An input prompt for Application Component Hierarchy code.
|
|
186
|
+
*/
|
|
187
|
+
private getAchPrompt;
|
|
188
|
+
/**
|
|
189
|
+
* Generates a confirmation prompt to decide whether to create an extension project based on the application's
|
|
190
|
+
* sync capabilities and support status.
|
|
191
|
+
*
|
|
192
|
+
* @param {ShouldCreateExtProjectPromptOptions} _ - Optional configuration for the confirm extension project prompt.
|
|
193
|
+
* @returns The confirm extension project prompt as a {@link ConfigQuestion}.
|
|
194
|
+
*/
|
|
195
|
+
private getShouldCreateExtProjectPrompt;
|
|
168
196
|
/**
|
|
169
197
|
* Validates the selected application.
|
|
170
198
|
*
|
|
@@ -4,11 +4,14 @@ exports.ConfigPrompter = void 0;
|
|
|
4
4
|
const adp_tooling_1 = require("@sap-ux/adp-tooling");
|
|
5
5
|
const project_input_validator_1 = require("@sap-ux/project-input-validator");
|
|
6
6
|
const axios_extension_1 = require("@sap-ux/axios-extension");
|
|
7
|
+
const btp_utils_1 = require("@sap-ux/btp-utils");
|
|
7
8
|
const i18n_1 = require("../../utils/i18n");
|
|
8
9
|
const types_1 = require("../types");
|
|
10
|
+
const message_1 = require("./helper/message");
|
|
9
11
|
const choices_1 = require("./helper/choices");
|
|
10
|
-
const
|
|
12
|
+
const validators_1 = require("./helper/validators");
|
|
11
13
|
const additional_messages_1 = require("./helper/additional-messages");
|
|
14
|
+
const conditions_1 = require("./helper/conditions");
|
|
12
15
|
/**
|
|
13
16
|
* A stateful prompter class that creates configuration questions.
|
|
14
17
|
* It exposes a single public method {@link getPrompts} to retrieve the configuration questions.
|
|
@@ -124,6 +127,14 @@ class ConfigPrompter {
|
|
|
124
127
|
get hasSyncViews() {
|
|
125
128
|
return this.containsSyncViews;
|
|
126
129
|
}
|
|
130
|
+
/**
|
|
131
|
+
* Indicates whether the application is supported by Adaptation Project.
|
|
132
|
+
*
|
|
133
|
+
* @returns {boolean} True if the application is supported.
|
|
134
|
+
*/
|
|
135
|
+
get isAppSupported() {
|
|
136
|
+
return this.isApplicationSupported;
|
|
137
|
+
}
|
|
127
138
|
/**
|
|
128
139
|
* Creates an instance of ConfigPrompter.
|
|
129
140
|
*
|
|
@@ -150,7 +161,10 @@ class ConfigPrompter {
|
|
|
150
161
|
[types_1.configPromptNames.username]: this.getUsernamePrompt(promptOptions?.[types_1.configPromptNames.username]),
|
|
151
162
|
[types_1.configPromptNames.password]: this.getPasswordPrompt(promptOptions?.[types_1.configPromptNames.password]),
|
|
152
163
|
[types_1.configPromptNames.application]: this.getApplicationListPrompt(promptOptions?.[types_1.configPromptNames.application]),
|
|
153
|
-
[types_1.configPromptNames.appValidationCli]: this.getApplicationValidationPromptForCli()
|
|
164
|
+
[types_1.configPromptNames.appValidationCli]: this.getApplicationValidationPromptForCli(),
|
|
165
|
+
[types_1.configPromptNames.fioriId]: this.getFioriIdPrompt(),
|
|
166
|
+
[types_1.configPromptNames.ach]: this.getAchPrompt(),
|
|
167
|
+
[types_1.configPromptNames.shouldCreateExtProject]: this.getShouldCreateExtProjectPrompt(promptOptions?.[types_1.configPromptNames.shouldCreateExtProject])
|
|
154
168
|
};
|
|
155
169
|
const questions = Object.entries(keyedPrompts)
|
|
156
170
|
.filter(([promptName, _]) => {
|
|
@@ -296,6 +310,68 @@ class ConfigPrompter {
|
|
|
296
310
|
}
|
|
297
311
|
};
|
|
298
312
|
}
|
|
313
|
+
/**
|
|
314
|
+
* Creates an input prompt for entering the Fiori ID.
|
|
315
|
+
*
|
|
316
|
+
* @param {FioriIdPromptOptions} _ - Optional configuration for Fiori ID prompt.
|
|
317
|
+
* @returns {InputQuestion<ConfigAnswers>} An input prompt for the Fiori ID.
|
|
318
|
+
*/
|
|
319
|
+
getFioriIdPrompt(_) {
|
|
320
|
+
return {
|
|
321
|
+
type: 'input',
|
|
322
|
+
name: 'fioriId',
|
|
323
|
+
message: (0, i18n_1.t)('prompts.fioriIdLabel'),
|
|
324
|
+
guiOptions: {
|
|
325
|
+
hint: (0, i18n_1.t)('prompts.fioriIdHint'),
|
|
326
|
+
breadcrumb: true
|
|
327
|
+
},
|
|
328
|
+
when: (answers) => (0, conditions_1.showInternalQuestions)(answers, this.isCustomerBase, this.isApplicationSupported),
|
|
329
|
+
default: () => (0, adp_tooling_1.getFioriId)(this.appManifest),
|
|
330
|
+
store: false
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Generates an input prompt for entering the Application Component Hierarchy code for a project.
|
|
335
|
+
*
|
|
336
|
+
* @param {AchPromptOptions} _ - Optional configuration for ACH prompt.
|
|
337
|
+
* @returns {InputQuestion<ConfigAnswers>} An input prompt for Application Component Hierarchy code.
|
|
338
|
+
*/
|
|
339
|
+
getAchPrompt(_) {
|
|
340
|
+
return {
|
|
341
|
+
type: 'input',
|
|
342
|
+
name: 'ach',
|
|
343
|
+
message: (0, i18n_1.t)('prompts.achLabel'),
|
|
344
|
+
guiOptions: {
|
|
345
|
+
hint: (0, i18n_1.t)('prompts.achHint'),
|
|
346
|
+
breadcrumb: true,
|
|
347
|
+
mandatory: true
|
|
348
|
+
},
|
|
349
|
+
when: (answers) => (0, conditions_1.showInternalQuestions)(answers, this.isCustomerBase, this.isApplicationSupported),
|
|
350
|
+
default: () => (0, adp_tooling_1.getAch)(this.appManifest),
|
|
351
|
+
validate: (value) => (0, project_input_validator_1.validateAch)(value, this.isCustomerBase),
|
|
352
|
+
store: false
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Generates a confirmation prompt to decide whether to create an extension project based on the application's
|
|
357
|
+
* sync capabilities and support status.
|
|
358
|
+
*
|
|
359
|
+
* @param {ShouldCreateExtProjectPromptOptions} _ - Optional configuration for the confirm extension project prompt.
|
|
360
|
+
* @returns The confirm extension project prompt as a {@link ConfigQuestion}.
|
|
361
|
+
*/
|
|
362
|
+
getShouldCreateExtProjectPrompt(_) {
|
|
363
|
+
return {
|
|
364
|
+
type: 'confirm',
|
|
365
|
+
name: types_1.configPromptNames.shouldCreateExtProject,
|
|
366
|
+
message: () => (0, message_1.getExtProjectMessage)(this.isApplicationSupported, this.containsSyncViews),
|
|
367
|
+
default: false,
|
|
368
|
+
guiOptions: {
|
|
369
|
+
applyDefaultWhenDirty: true
|
|
370
|
+
},
|
|
371
|
+
when: (answers) => (0, conditions_1.showExtensionProjectQuestion)(answers, this.flexUISystem, this.isCloudProject, this.isApplicationSupported, this.containsSyncViews),
|
|
372
|
+
validate: (value) => (0, validators_1.validateExtensibilityGenerator)(value, this.isApplicationSupported, this.containsSyncViews)
|
|
373
|
+
};
|
|
374
|
+
}
|
|
299
375
|
/**
|
|
300
376
|
* Validates the selected application.
|
|
301
377
|
*
|
|
@@ -308,7 +384,17 @@ class ConfigPrompter {
|
|
|
308
384
|
if (!app) {
|
|
309
385
|
return (0, i18n_1.t)('error.selectCannotBeEmptyError', { value: 'Application' });
|
|
310
386
|
}
|
|
311
|
-
|
|
387
|
+
const validationResult = await this.validateAppData(app);
|
|
388
|
+
if (!(0, btp_utils_1.isAppStudio)()) {
|
|
389
|
+
return validationResult;
|
|
390
|
+
}
|
|
391
|
+
if (validationResult === (0, i18n_1.t)('error.appDoesNotSupportManifest') ||
|
|
392
|
+
validationResult === (0, i18n_1.t)('error.appDoesNotSupportAdaptation')) {
|
|
393
|
+
this.logger.error(validationResult);
|
|
394
|
+
this.isApplicationSupported = false;
|
|
395
|
+
return true;
|
|
396
|
+
}
|
|
397
|
+
return validationResult;
|
|
312
398
|
}
|
|
313
399
|
/**
|
|
314
400
|
* Validates the password by setting up the provider and, if necessary,
|
|
@@ -398,7 +484,6 @@ class ConfigPrompter {
|
|
|
398
484
|
this.isApplicationSupported = true;
|
|
399
485
|
}
|
|
400
486
|
catch (e) {
|
|
401
|
-
this.isApplicationSupported = false;
|
|
402
487
|
this.logger.debug(`Application failed validation. Reason: ${e.message}`);
|
|
403
488
|
return e.message;
|
|
404
489
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ConfigAnswers } from '@sap-ux/adp-tooling';
|
|
1
|
+
import type { ConfigAnswers, FlexUISupportedSystem } from '@sap-ux/adp-tooling';
|
|
2
2
|
/**
|
|
3
3
|
* Determines if a credential question should be shown.
|
|
4
4
|
* In this simplified approach, we show credentials if a system is provided and the login was not successful.
|
|
@@ -18,4 +18,24 @@ export declare function showCredentialQuestion(answers: ConfigAnswers, isAuthReq
|
|
|
18
18
|
* @returns {boolean} True if the application question should be shown.
|
|
19
19
|
*/
|
|
20
20
|
export declare function showApplicationQuestion(answers: ConfigAnswers, appsLoaded: boolean, isAuthRequired: boolean, isLoginSuccessful: boolean): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Determines if an extension project is allowed based on the system and application conditions.
|
|
23
|
+
*
|
|
24
|
+
* @param {ConfigAnswers} answers - The user-provided answers containing application details.
|
|
25
|
+
* @param {FlexUISupportedSystem} flexUISystem - The system type info (e.g., onPremise/UIFlex).
|
|
26
|
+
* @param {boolean} isCloudProject - Whether the system is a cloud-based system.
|
|
27
|
+
* @param {boolean} isApplicationSupported - Whether the selected application is supported.
|
|
28
|
+
* @param {boolean} hasSyncViews - Whether synchronized views exist for the app.
|
|
29
|
+
* @returns {boolean | undefined} True if an extension project is allowed, otherwise false or undefined.
|
|
30
|
+
*/
|
|
31
|
+
export declare function showExtensionProjectQuestion(answers: ConfigAnswers, flexUISystem: FlexUISupportedSystem | undefined, isCloudProject: boolean | undefined, isApplicationSupported: boolean, hasSyncViews: boolean): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Determines if an internal question for ACH and FioriId will be shown based on the answers and specific conditions.
|
|
34
|
+
*
|
|
35
|
+
* @param {ConfigurationInfoAnswers} answers - The user-provided answers containing application details.
|
|
36
|
+
* @param {boolean} isCustomerBase - Indicates whether the adaptation layer is CUSTOMER_BASE.
|
|
37
|
+
* @param {boolean} isApplicationSupported - Whether the selected application is supported.
|
|
38
|
+
* @returns {boolean | undefined} True if an internal question for ACH and FioriId question will be shown, otherwise false.
|
|
39
|
+
*/
|
|
40
|
+
export declare function showInternalQuestions(answers: ConfigAnswers, isCustomerBase: boolean, isApplicationSupported: boolean): boolean;
|
|
21
41
|
//# sourceMappingURL=conditions.d.ts.map
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.showApplicationQuestion = exports.showCredentialQuestion = void 0;
|
|
3
|
+
exports.showInternalQuestions = exports.showExtensionProjectQuestion = exports.showApplicationQuestion = exports.showCredentialQuestion = void 0;
|
|
4
|
+
const btp_utils_1 = require("@sap-ux/btp-utils");
|
|
4
5
|
/**
|
|
5
6
|
* Determines if a credential question should be shown.
|
|
6
7
|
* In this simplified approach, we show credentials if a system is provided and the login was not successful.
|
|
@@ -26,4 +27,39 @@ function showApplicationQuestion(answers, appsLoaded, isAuthRequired, isLoginSuc
|
|
|
26
27
|
return !!answers.system && appsLoaded && (isAuthRequired ? isLoginSuccessful : true);
|
|
27
28
|
}
|
|
28
29
|
exports.showApplicationQuestion = showApplicationQuestion;
|
|
30
|
+
/**
|
|
31
|
+
* Determines if an extension project is allowed based on the system and application conditions.
|
|
32
|
+
*
|
|
33
|
+
* @param {ConfigAnswers} answers - The user-provided answers containing application details.
|
|
34
|
+
* @param {FlexUISupportedSystem} flexUISystem - The system type info (e.g., onPremise/UIFlex).
|
|
35
|
+
* @param {boolean} isCloudProject - Whether the system is a cloud-based system.
|
|
36
|
+
* @param {boolean} isApplicationSupported - Whether the selected application is supported.
|
|
37
|
+
* @param {boolean} hasSyncViews - Whether synchronized views exist for the app.
|
|
38
|
+
* @returns {boolean | undefined} True if an extension project is allowed, otherwise false or undefined.
|
|
39
|
+
*/
|
|
40
|
+
function showExtensionProjectQuestion(answers, flexUISystem, isCloudProject, isApplicationSupported, hasSyncViews) {
|
|
41
|
+
if (!answers.application) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
if (isCloudProject) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
const isOnPremiseAppStudio = !!flexUISystem?.isOnPremise && (0, btp_utils_1.isAppStudio)();
|
|
48
|
+
const nonFlexOrNonOnPremise = flexUISystem && (!flexUISystem?.isOnPremise || !flexUISystem?.isUIFlex);
|
|
49
|
+
return (isOnPremiseAppStudio &&
|
|
50
|
+
(!isApplicationSupported || (isApplicationSupported && (nonFlexOrNonOnPremise || hasSyncViews))));
|
|
51
|
+
}
|
|
52
|
+
exports.showExtensionProjectQuestion = showExtensionProjectQuestion;
|
|
53
|
+
/**
|
|
54
|
+
* Determines if an internal question for ACH and FioriId will be shown based on the answers and specific conditions.
|
|
55
|
+
*
|
|
56
|
+
* @param {ConfigurationInfoAnswers} answers - The user-provided answers containing application details.
|
|
57
|
+
* @param {boolean} isCustomerBase - Indicates whether the adaptation layer is CUSTOMER_BASE.
|
|
58
|
+
* @param {boolean} isApplicationSupported - Whether the selected application is supported.
|
|
59
|
+
* @returns {boolean | undefined} True if an internal question for ACH and FioriId question will be shown, otherwise false.
|
|
60
|
+
*/
|
|
61
|
+
function showInternalQuestions(answers, isCustomerBase, isApplicationSupported) {
|
|
62
|
+
return !!answers.system && answers.application && !isCustomerBase && isApplicationSupported;
|
|
63
|
+
}
|
|
64
|
+
exports.showInternalQuestions = showInternalQuestions;
|
|
29
65
|
//# sourceMappingURL=conditions.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a message for extension project prompt based on the provided parameters.
|
|
3
|
+
*
|
|
4
|
+
* @param {boolean} isApplicationSupported - Whether the selected application is supported.
|
|
5
|
+
* @param {boolean} hasSyncViews - Whether synchronized views exist for the app.
|
|
6
|
+
* @returns {string} A message for confirm extension project prompt.
|
|
7
|
+
*/
|
|
8
|
+
export declare const getExtProjectMessage: (isApplicationSupported: boolean, hasSyncViews: boolean) => string;
|
|
9
|
+
//# sourceMappingURL=message.d.ts.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getExtProjectMessage = void 0;
|
|
4
|
+
const i18n_1 = require("../../../utils/i18n");
|
|
5
|
+
/**
|
|
6
|
+
* Creates a message for extension project prompt based on the provided parameters.
|
|
7
|
+
*
|
|
8
|
+
* @param {boolean} isApplicationSupported - Whether the selected application is supported.
|
|
9
|
+
* @param {boolean} hasSyncViews - Whether synchronized views exist for the app.
|
|
10
|
+
* @returns {string} A message for confirm extension project prompt.
|
|
11
|
+
*/
|
|
12
|
+
const getExtProjectMessage = (isApplicationSupported, hasSyncViews) => {
|
|
13
|
+
return isApplicationSupported && hasSyncViews
|
|
14
|
+
? (0, i18n_1.t)('prompts.createExtProjectWithSyncViewsLabel')
|
|
15
|
+
: (0, i18n_1.t)('prompts.createExtProjectLabel');
|
|
16
|
+
};
|
|
17
|
+
exports.getExtProjectMessage = getExtProjectMessage;
|
|
18
|
+
//# sourceMappingURL=message.js.map
|
|
@@ -5,6 +5,16 @@ interface JsonInputParams {
|
|
|
5
5
|
namespace: string;
|
|
6
6
|
system: string;
|
|
7
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* Validates whether the extensibility sub-generator is available and sets it up if necessary.
|
|
10
|
+
* If the generator is not found, an error message is returned advising on the necessary action.
|
|
11
|
+
*
|
|
12
|
+
* @param {boolean} value - A confirm flag indicating whether user wants to continue creating an extension project.
|
|
13
|
+
* @param {boolean} isApplicationSupported - Whether the selected application is supported.
|
|
14
|
+
* @param {boolean} hasSyncViews - Whether synchronized views exist for the app.
|
|
15
|
+
* @returns {boolean | string} Returns true if app is supported and contains sync views, or an error message if not.
|
|
16
|
+
*/
|
|
17
|
+
export declare function validateExtensibilityGenerator(value: boolean, isApplicationSupported: boolean, hasSyncViews: boolean): boolean | string;
|
|
8
18
|
/**
|
|
9
19
|
* Validates the input parameters for an adaptation project configuration.
|
|
10
20
|
*
|
|
@@ -1,9 +1,30 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.validateJsonInput = void 0;
|
|
3
|
+
exports.validateJsonInput = exports.validateExtensibilityGenerator = void 0;
|
|
4
4
|
const project_input_validator_1 = require("@sap-ux/project-input-validator");
|
|
5
5
|
const i18n_1 = require("../../../utils/i18n");
|
|
6
6
|
const type_guards_1 = require("../../../utils/type-guards");
|
|
7
|
+
const extension_project_1 = require("../../extension-project");
|
|
8
|
+
/**
|
|
9
|
+
* Validates whether the extensibility sub-generator is available and sets it up if necessary.
|
|
10
|
+
* If the generator is not found, an error message is returned advising on the necessary action.
|
|
11
|
+
*
|
|
12
|
+
* @param {boolean} value - A confirm flag indicating whether user wants to continue creating an extension project.
|
|
13
|
+
* @param {boolean} isApplicationSupported - Whether the selected application is supported.
|
|
14
|
+
* @param {boolean} hasSyncViews - Whether synchronized views exist for the app.
|
|
15
|
+
* @returns {boolean | string} Returns true if app is supported and contains sync views, or an error message if not.
|
|
16
|
+
*/
|
|
17
|
+
function validateExtensibilityGenerator(value, isApplicationSupported, hasSyncViews) {
|
|
18
|
+
if (value) {
|
|
19
|
+
const generator = (0, extension_project_1.resolveNodeModuleGenerator)();
|
|
20
|
+
if (!generator) {
|
|
21
|
+
return (0, i18n_1.t)('error.extensibilityGenNotFound');
|
|
22
|
+
}
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
return isApplicationSupported && hasSyncViews ? true : (0, i18n_1.t)('prompts.createExtProjectContinueLabel');
|
|
26
|
+
}
|
|
27
|
+
exports.validateExtensibilityGenerator = validateExtensibilityGenerator;
|
|
7
28
|
/**
|
|
8
29
|
* Validates the input parameters for an adaptation project configuration.
|
|
9
30
|
*
|
|
@@ -34,7 +34,10 @@ export declare enum configPromptNames {
|
|
|
34
34
|
username = "username",
|
|
35
35
|
password = "password",
|
|
36
36
|
application = "application",
|
|
37
|
-
appValidationCli = "appValidationCli"
|
|
37
|
+
appValidationCli = "appValidationCli",
|
|
38
|
+
fioriId = "fioriId",
|
|
39
|
+
ach = "ach",
|
|
40
|
+
shouldCreateExtProject = "shouldCreateExtProject"
|
|
38
41
|
}
|
|
39
42
|
/**
|
|
40
43
|
* The question type specific to configuration prompts.
|
|
@@ -60,6 +63,15 @@ export interface ApplicationPromptOptions {
|
|
|
60
63
|
default?: string;
|
|
61
64
|
hide?: boolean;
|
|
62
65
|
}
|
|
66
|
+
export interface FioriIdPromptOptions {
|
|
67
|
+
hide?: boolean;
|
|
68
|
+
}
|
|
69
|
+
export interface AchPromptOptions {
|
|
70
|
+
hide?: boolean;
|
|
71
|
+
}
|
|
72
|
+
export interface ShouldCreateExtProjectPromptOptions {
|
|
73
|
+
hide?: boolean;
|
|
74
|
+
}
|
|
63
75
|
/**
|
|
64
76
|
* Options for the configuration inquirer & the prompts.
|
|
65
77
|
*/
|
|
@@ -70,6 +82,9 @@ export type ConfigPromptOptions = Partial<{
|
|
|
70
82
|
[configPromptNames.password]: PasswordPromptOptions;
|
|
71
83
|
[configPromptNames.application]: ApplicationPromptOptions;
|
|
72
84
|
[configPromptNames.appValidationCli]: CliValidationPromptOptions;
|
|
85
|
+
[configPromptNames.fioriId]: FioriIdPromptOptions;
|
|
86
|
+
[configPromptNames.ach]: AchPromptOptions;
|
|
87
|
+
[configPromptNames.shouldCreateExtProject]: ShouldCreateExtProjectPromptOptions;
|
|
73
88
|
}>;
|
|
74
89
|
export declare enum attributePromptNames {
|
|
75
90
|
projectName = "projectName",
|
|
@@ -110,6 +125,21 @@ export type AttributePromptOptions = Partial<{
|
|
|
110
125
|
[attributePromptNames.ui5ValidationCli]: CliValidationPromptOptions;
|
|
111
126
|
[attributePromptNames.enableTypeScript]: EnableTypeScriptPromptOptions;
|
|
112
127
|
}>;
|
|
128
|
+
export interface ExtensionProjectData {
|
|
129
|
+
destination: {
|
|
130
|
+
name: string;
|
|
131
|
+
basUsage: string | undefined;
|
|
132
|
+
host: string | undefined;
|
|
133
|
+
sapClient: string | undefined;
|
|
134
|
+
};
|
|
135
|
+
username: string;
|
|
136
|
+
password: string;
|
|
137
|
+
applicationNS: string;
|
|
138
|
+
applicationName: string;
|
|
139
|
+
userUI5Ver: string;
|
|
140
|
+
BSPUrl: string;
|
|
141
|
+
namespace: string;
|
|
142
|
+
}
|
|
113
143
|
/**
|
|
114
144
|
* An interface representing the json input used to store the complete adaptation project
|
|
115
145
|
* generator configurations. The json is passed as an CLI argument.
|
package/generators/app/types.js
CHANGED
|
@@ -12,6 +12,9 @@ var configPromptNames;
|
|
|
12
12
|
configPromptNames["password"] = "password";
|
|
13
13
|
configPromptNames["application"] = "application";
|
|
14
14
|
configPromptNames["appValidationCli"] = "appValidationCli";
|
|
15
|
+
configPromptNames["fioriId"] = "fioriId";
|
|
16
|
+
configPromptNames["ach"] = "ach";
|
|
17
|
+
configPromptNames["shouldCreateExtProject"] = "shouldCreateExtProject";
|
|
15
18
|
})(configPromptNames || (exports.configPromptNames = configPromptNames = {}));
|
|
16
19
|
var attributePromptNames;
|
|
17
20
|
(function (attributePromptNames) {
|
|
@@ -14,6 +14,13 @@
|
|
|
14
14
|
"passwordTooltip": "Enter the password for the back-end system.",
|
|
15
15
|
"applicationListLabel": "Application",
|
|
16
16
|
"applicationListTooltip": "Select the application for which you want to create an app variant.",
|
|
17
|
+
"fioriIdLabel": "Fiori ID",
|
|
18
|
+
"fioriIdHint": "This is an one-time, semantic identifier for the app variant. The Fiori ID will be shown in the 'About' section of the app for ease of identification and will also be available in the Fiori Apps Reference Library.",
|
|
19
|
+
"achLabel": "Application Component Hierarchy",
|
|
20
|
+
"achHint": "The purpose of ACH components is to enable the support organization to indicate which BCP/ticket component might be responsible for a particular issue.",
|
|
21
|
+
"createExtProjectLabel": "The selected application is not supported by the SAPUI5 Adaptation Project. For more information, see SAPUI5 Adaptation Project documentation. Do you want to create an extension project instead?",
|
|
22
|
+
"createExtProjectWithSyncViewsLabel": "Do you want to create an extension project instead? An extension project gives you the ability to create controller extensions for synchronous and asynchronous views.",
|
|
23
|
+
"createExtProjectContinueLabel": "Please select whether you want to continue.",
|
|
17
24
|
"projectTypeLabel": "Project Type",
|
|
18
25
|
"projectNameLabel": "Project Name",
|
|
19
26
|
"projectNameTooltip": "Enter the project name for your app variant.",
|
|
@@ -44,7 +51,12 @@
|
|
|
44
51
|
"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.",
|
|
45
52
|
"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.",
|
|
46
53
|
"manifestCouldNotBeValidated": "The manifest.json file of the selected application could not be validated. Please select a different application.",
|
|
47
|
-
"appDoesNotSupportAdaptation": "The application
|
|
54
|
+
"appDoesNotSupportAdaptation": "The selected application does not support flexibility. The SAPUI5 Adaptation Project is only available for applications that support flexibility. Please select a different application.",
|
|
55
|
+
"appDoesNotSupportManifest": "The selected application is not supported by the adaptation project. Please select a different application. For more information, see SAPUI5 Adaptation Project documentation.",
|
|
56
|
+
"extensibilityGenNotFound": "Extensibility Project generator plugin was not found in your dev space, and is required for this action. To proceed, please install the <SAPUI5 Layout Editor & Extensibility> extension.",
|
|
57
|
+
"creatingExtensionProjectError": "Creating the extension project failed. To see the error, view the logs.",
|
|
58
|
+
"appParameterMissing": "Could not create an extension project because the application parameters are missing. Please select a different application.",
|
|
59
|
+
"destinationInfoMissing": "Could not create an extension project because the destination info is missing. Please select a different system.",
|
|
48
60
|
"systemNotFound": "System not found or not supported: {{system}}. Please check the system exists.",
|
|
49
61
|
"applicationNotFound": "Application not found or not supported: {{appName}}. Please check the application exists."
|
|
50
62
|
}
|
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.2.
|
|
5
|
+
"version": "0.2.1",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "https://github.com/SAP/open-ux-tools.git",
|
|
@@ -29,16 +29,16 @@
|
|
|
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.
|
|
33
|
-
"@sap-ux/btp-utils": "1.0.3",
|
|
32
|
+
"@sap-ux/adp-tooling": "0.13.43",
|
|
34
33
|
"@sap-ux/axios-extension": "1.20.2",
|
|
35
|
-
"@sap-ux/
|
|
34
|
+
"@sap-ux/btp-utils": "1.0.3",
|
|
36
35
|
"@sap-ux/feature-toggle": "0.2.3",
|
|
36
|
+
"@sap-ux/inquirer-common": "0.6.42",
|
|
37
37
|
"@sap-ux/logger": "0.6.0",
|
|
38
38
|
"@sap-ux/project-access": "1.29.22",
|
|
39
39
|
"@sap-ux/store": "1.0.0",
|
|
40
40
|
"@sap-ux/system-access": "0.5.38",
|
|
41
|
-
"@sap-ux/project-input-validator": "0.5.
|
|
41
|
+
"@sap-ux/project-input-validator": "0.5.6",
|
|
42
42
|
"@sap-ux/fiori-generator-shared": "0.11.3"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|