@sap-ux/fiori-app-sub-generator 0.15.21 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/generators/app/index.d.ts +1 -1
- package/generators/app/index.js +2 -4
- package/generators/app-headless/index.d.ts +2 -2
- package/generators/app-headless/index.js +17 -21
- package/generators/app-headless/resolve.js +11 -16
- package/generators/app-headless/transforms.d.ts +1 -1
- package/generators/app-headless/transforms.js +35 -38
- package/generators/fiori-app-generator/end.d.ts +1 -1
- package/generators/fiori-app-generator/end.js +23 -25
- package/generators/fiori-app-generator/fioriAppGenerator.d.ts +2 -2
- package/generators/fiori-app-generator/fioriAppGenerator.js +92 -99
- package/generators/fiori-app-generator/fioriAppGeneratorOptions.d.ts +1 -1
- package/generators/fiori-app-generator/fioriAppGeneratorOptions.js +1 -2
- package/generators/fiori-app-generator/index.d.ts +2 -2
- package/generators/fiori-app-generator/index.js +2 -18
- package/generators/fiori-app-generator/install.js +10 -13
- package/generators/fiori-app-generator/prompting.d.ts +1 -1
- package/generators/fiori-app-generator/prompting.js +60 -70
- package/generators/fiori-app-generator/subgenHelpers.d.ts +1 -1
- package/generators/fiori-app-generator/subgenHelpers.js +8 -12
- package/generators/fiori-app-generator/transforms.d.ts +2 -3
- package/generators/fiori-app-generator/transforms.js +63 -66
- package/generators/fiori-app-generator/writing.d.ts +1 -1
- package/generators/fiori-app-generator/writing.js +18 -22
- package/generators/index.d.ts +5 -5
- package/generators/index.js +5 -21
- package/generators/types/common.js +1 -2
- package/generators/types/constants.d.ts +1 -1
- package/generators/types/constants.js +59 -52
- package/generators/types/external.d.ts +5 -4
- package/generators/types/external.js +40 -45
- package/generators/types/index.d.ts +6 -6
- package/generators/types/index.js +6 -22
- package/generators/types/state.d.ts +2 -2
- package/generators/types/state.js +1 -2
- package/generators/types/telemetryEvents.js +1 -2
- package/generators/types/yeomanUiStepConfig.js +1 -2
- package/generators/utils/appWizardCache.d.ts +1 -1
- package/generators/utils/appWizardCache.js +9 -15
- package/generators/utils/command-runner.js +9 -13
- package/generators/utils/common.d.ts +3 -3
- package/generators/utils/common.js +64 -81
- package/generators/utils/eventHooks.js +6 -10
- package/generators/utils/i18n.js +15 -23
- package/generators/utils/index.d.ts +8 -8
- package/generators/utils/index.js +8 -24
- package/generators/utils/sapuxLayer.js +3 -6
- package/generators/utils/stepsHelper.d.ts +3 -4
- package/generators/utils/stepsHelper.js +10 -17
- package/generators/utils/telemetry.d.ts +1 -1
- package/generators/utils/telemetry.js +9 -12
- package/package.json +27 -25
|
@@ -1,22 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const fiori_generator_shared_1 = require("@sap-ux/fiori-generator-shared");
|
|
12
|
-
const odata_service_inquirer_1 = require("@sap-ux/odata-service-inquirer");
|
|
13
|
-
const telemetry_1 = require("@sap-ux/telemetry");
|
|
14
|
-
const ui5_application_inquirer_1 = require("@sap-ux/ui5-application-inquirer");
|
|
15
|
-
const ui5_info_1 = require("@sap-ux/ui5-info");
|
|
16
|
-
const merge_1 = __importDefault(require("lodash/merge"));
|
|
17
|
-
const node_path_1 = require("node:path");
|
|
18
|
-
const types_1 = require("../types");
|
|
19
|
-
const utils_1 = require("../utils");
|
|
1
|
+
import { isFeatureEnabled } from '@sap-ux/feature-toggle';
|
|
2
|
+
import { getHostEnvironment, hostEnvironment } from '@sap-ux/fiori-generator-shared';
|
|
3
|
+
import { DatasourceType, OdataVersion, promptNames as odataServiceInquirerPromptNames, prompt as promptOdataService } from '@sap-ux/odata-service-inquirer';
|
|
4
|
+
import { ClientFactory } from '@sap-ux/telemetry';
|
|
5
|
+
import { prompt as promptUI5App, promptNames as ui5AppInquirerPromptNames } from '@sap-ux/ui5-application-inquirer';
|
|
6
|
+
import { getSapSystemUI5Version, getUI5Versions, latestVersionString } from '@sap-ux/ui5-info';
|
|
7
|
+
import merge from 'lodash/merge.js';
|
|
8
|
+
import { join } from 'node:path';
|
|
9
|
+
import { Features, defaultPromptValues } from '../types/index.js';
|
|
10
|
+
import { getMinSupportedUI5Version, t, validateNextStep } from '../utils/index.js';
|
|
20
11
|
/**
|
|
21
12
|
* Validates the view name.
|
|
22
13
|
* The view name must be a valid identifier and must not be empty.
|
|
@@ -29,25 +20,25 @@ const utils_1 = require("../utils");
|
|
|
29
20
|
function validateViewName(name) {
|
|
30
21
|
// Validate input is not empty
|
|
31
22
|
if (!name) {
|
|
32
|
-
return
|
|
23
|
+
return t('prompts.viewName.validationMessages.viewNameRequired');
|
|
33
24
|
}
|
|
34
25
|
// Validate view names matches the allowed pattern
|
|
35
26
|
const regExp = /^[a-zA-Z]+[a-zA-Z0-9-_]{0,120}$/;
|
|
36
27
|
const result = regExp.test(name);
|
|
37
28
|
if (name.length > 120) {
|
|
38
|
-
return
|
|
29
|
+
return t('prompts.viewName.validationMessages.viewNameTooLong');
|
|
39
30
|
}
|
|
40
31
|
if (!result) {
|
|
41
|
-
return
|
|
32
|
+
return t('prompts.viewName.validationMessages.viewNameInvalid');
|
|
42
33
|
}
|
|
43
34
|
return true;
|
|
44
35
|
}
|
|
45
36
|
const viewNamePromptName = 'viewName';
|
|
46
|
-
const getViewQuestion = () => {
|
|
37
|
+
export const getViewQuestion = () => {
|
|
47
38
|
return {
|
|
48
39
|
type: 'input',
|
|
49
40
|
name: viewNamePromptName,
|
|
50
|
-
message:
|
|
41
|
+
message: t('prompts.viewName.message'),
|
|
51
42
|
guiOptions: {
|
|
52
43
|
breadcrumb: true
|
|
53
44
|
},
|
|
@@ -55,7 +46,6 @@ const getViewQuestion = () => {
|
|
|
55
46
|
validate: validateViewName
|
|
56
47
|
};
|
|
57
48
|
};
|
|
58
|
-
exports.getViewQuestion = getViewQuestion;
|
|
59
49
|
/**
|
|
60
50
|
* Creates the prompt options for UI5 application prompting and calls `prompt`.
|
|
61
51
|
* The answers to the questions are returned.
|
|
@@ -72,7 +62,7 @@ exports.getViewQuestion = getViewQuestion;
|
|
|
72
62
|
* @param adapter
|
|
73
63
|
* @returns
|
|
74
64
|
*/
|
|
75
|
-
async function promptUI5ApplicationAnswers({ service, projectName, targetFolder, promptSettings, floorplan, promptExtension, entityRelatedConfig }, yeomanUiStepConfig, adapter) {
|
|
65
|
+
export async function promptUI5ApplicationAnswers({ service, projectName, targetFolder, promptSettings, floorplan, promptExtension, entityRelatedConfig }, yeomanUiStepConfig, adapter) {
|
|
76
66
|
let inquirerAdapter;
|
|
77
67
|
// type `any` will be replaced when we can import ESM modules
|
|
78
68
|
if (adapter?.actualAdapter) {
|
|
@@ -91,13 +81,13 @@ async function promptUI5ApplicationAnswers({ service, projectName, targetFolder,
|
|
|
91
81
|
promptExtension,
|
|
92
82
|
entityRelatedConfig
|
|
93
83
|
});
|
|
94
|
-
const ui5AppAnswers = await (
|
|
84
|
+
const ui5AppAnswers = await promptUI5App(inquirerAdapter, promptOptions, service.capService?.cdsUi5PluginInfo, getHostEnvironment() !== hostEnvironment.cli);
|
|
95
85
|
// Get the (latest) version available from npm, instead of UI5 versions service in case of unpublished versions
|
|
96
|
-
const localUI5Version = (await
|
|
86
|
+
const localUI5Version = (await getUI5Versions({
|
|
97
87
|
minSupportedUI5Version: promptOptions.ui5Version?.minUI5Version,
|
|
98
88
|
onlyVersionNumbers: true,
|
|
99
89
|
onlyNpmVersion: true,
|
|
100
|
-
ui5SelectedVersion: ui5AppAnswers?.ui5Version ??
|
|
90
|
+
ui5SelectedVersion: ui5AppAnswers?.ui5Version ?? latestVersionString
|
|
101
91
|
}))[0]?.version;
|
|
102
92
|
return { ui5AppAnswers, localUI5Version };
|
|
103
93
|
}
|
|
@@ -110,7 +100,7 @@ async function promptUI5ApplicationAnswers({ service, projectName, targetFolder,
|
|
|
110
100
|
* @param connectedSystem
|
|
111
101
|
* @returns {Promise<Service>}
|
|
112
102
|
*/
|
|
113
|
-
async function promptOdataServiceAnswers(options, logger, adapter, connectedSystem) {
|
|
103
|
+
export async function promptOdataServiceAnswers(options, logger, adapter, connectedSystem) {
|
|
114
104
|
let inquirerAdapter;
|
|
115
105
|
// type `any` will be replaced when we can import ESM modules
|
|
116
106
|
if (adapter?.actualAdapter) {
|
|
@@ -120,7 +110,7 @@ async function promptOdataServiceAnswers(options, logger, adapter, connectedSyst
|
|
|
120
110
|
inquirerAdapter = adapter;
|
|
121
111
|
}
|
|
122
112
|
const promptOptions = createOdataServicePromptOptions(options);
|
|
123
|
-
const answers = await (
|
|
113
|
+
const answers = await promptOdataService(inquirerAdapter, promptOptions, logger, isFeatureEnabled(Features.enableGAIntegration), ClientFactory.getTelemetryClient(), getHostEnvironment() !== hostEnvironment.cli, connectedSystem);
|
|
124
114
|
const service = {
|
|
125
115
|
host: answers.origin,
|
|
126
116
|
client: answers.sapClient,
|
|
@@ -154,17 +144,17 @@ async function promptOdataServiceAnswers(options, logger, adapter, connectedSyst
|
|
|
154
144
|
* @param {Partial<EntityRelatedAnswers>} [ui5PromptOptions.entityRelatedConfig] - Entity-related configuration.
|
|
155
145
|
* @returns {Promise<UI5ApplicationPromptOptions>} prompt options that may be used to configure UI5 application prompting
|
|
156
146
|
*/
|
|
157
|
-
async function createUI5ApplicationPromptOptions(ui5PromptOptions) {
|
|
147
|
+
export async function createUI5ApplicationPromptOptions(ui5PromptOptions) {
|
|
158
148
|
const { service, appGenStepConfigList, floorplan, projectName, targetFolder, promptSettings, promptExtension: extensions, entityRelatedConfig } = ui5PromptOptions;
|
|
159
149
|
// prompt settings may be additionally provided e.g. set by adaptors
|
|
160
150
|
const ui5VersionPromptOptions = {
|
|
161
|
-
hide: promptSettings?.[
|
|
162
|
-
minUI5Version: promptSettings?.[
|
|
163
|
-
|
|
164
|
-
includeSeparators:
|
|
165
|
-
useAutocomplete:
|
|
151
|
+
hide: promptSettings?.[ui5AppInquirerPromptNames.ui5Version]?.hide ?? false,
|
|
152
|
+
minUI5Version: promptSettings?.[ui5AppInquirerPromptNames.ui5Version]?.minUI5Version ??
|
|
153
|
+
getMinSupportedUI5Version(service.version ?? OdataVersion.v2, floorplan, entityRelatedConfig),
|
|
154
|
+
includeSeparators: getHostEnvironment() !== hostEnvironment.cli,
|
|
155
|
+
useAutocomplete: getHostEnvironment() === hostEnvironment.cli
|
|
166
156
|
};
|
|
167
|
-
const systemVersion = service.host ? await
|
|
157
|
+
const systemVersion = service.host ? await getSapSystemUI5Version(service.host) : undefined;
|
|
168
158
|
if (systemVersion) {
|
|
169
159
|
ui5VersionPromptOptions.defaultChoice = {
|
|
170
160
|
name: `${systemVersion} (Source system version)`,
|
|
@@ -175,7 +165,7 @@ async function createUI5ApplicationPromptOptions(ui5PromptOptions) {
|
|
|
175
165
|
if (service.capService?.projectPath) {
|
|
176
166
|
// CAP override
|
|
177
167
|
defaultTargetFolderOption = {
|
|
178
|
-
default:
|
|
168
|
+
default: join(service.capService.projectPath, service.capService.appPath ?? '')
|
|
179
169
|
};
|
|
180
170
|
}
|
|
181
171
|
else {
|
|
@@ -187,46 +177,46 @@ async function createUI5ApplicationPromptOptions(ui5PromptOptions) {
|
|
|
187
177
|
}
|
|
188
178
|
// Add more prompt options as required
|
|
189
179
|
const preMergedPromptOpts = {
|
|
190
|
-
[
|
|
180
|
+
[ui5AppInquirerPromptNames.name]: {
|
|
191
181
|
defaultValue: projectName
|
|
192
182
|
},
|
|
193
|
-
[
|
|
194
|
-
[
|
|
195
|
-
[
|
|
183
|
+
[ui5AppInquirerPromptNames.targetFolder]: defaultTargetFolderOption,
|
|
184
|
+
[ui5AppInquirerPromptNames.ui5Version]: ui5VersionPromptOptions,
|
|
185
|
+
[ui5AppInquirerPromptNames.skipAnnotations]: {
|
|
196
186
|
hide: !service.capService
|
|
197
187
|
},
|
|
198
|
-
[
|
|
188
|
+
[ui5AppInquirerPromptNames.addDeployConfig]: {
|
|
199
189
|
validatorCallback: (addDeployConfigAnswer) => {
|
|
200
|
-
|
|
190
|
+
validateNextStep(addDeployConfigAnswer, t('steps.projectAttributesConfig.title'), appGenStepConfigList, t('steps.deployConfig.title'));
|
|
201
191
|
}
|
|
202
192
|
},
|
|
203
|
-
[
|
|
193
|
+
[ui5AppInquirerPromptNames.addFlpConfig]: {
|
|
204
194
|
validatorCallback: (addFlpConfigAnswer) => {
|
|
205
|
-
|
|
195
|
+
validateNextStep(addFlpConfigAnswer, t('steps.projectAttributesConfig.title'), appGenStepConfigList, t('steps.flpConfig.title'));
|
|
206
196
|
}
|
|
207
197
|
},
|
|
208
|
-
[
|
|
209
|
-
default:
|
|
198
|
+
[ui5AppInquirerPromptNames.enableTypeScript]: {
|
|
199
|
+
default: defaultPromptValues[ui5AppInquirerPromptNames.enableTypeScript]
|
|
210
200
|
},
|
|
211
|
-
[
|
|
201
|
+
[ui5AppInquirerPromptNames.enableVirtualEndpoints]: {
|
|
212
202
|
hide: service.capService?.capType === 'Java'
|
|
213
203
|
},
|
|
214
|
-
[
|
|
204
|
+
[ui5AppInquirerPromptNames.enableEslint]: {
|
|
215
205
|
hide: true,
|
|
216
206
|
default: true
|
|
217
207
|
}
|
|
218
208
|
};
|
|
219
|
-
const promptOptions = (
|
|
209
|
+
const promptOptions = merge(preMergedPromptOpts, promptSettings);
|
|
220
210
|
// Configure the prompts which should be hidden behind the advanced option switch
|
|
221
211
|
const advancedPrompts = [
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
212
|
+
ui5AppInquirerPromptNames.skipAnnotations,
|
|
213
|
+
ui5AppInquirerPromptNames.enableEslint,
|
|
214
|
+
ui5AppInquirerPromptNames.ui5Theme
|
|
225
215
|
];
|
|
226
216
|
advancedPrompts.forEach((advPromptKey) => {
|
|
227
217
|
const promptOpt = promptOptions[advPromptKey];
|
|
228
218
|
// Advanced options are hidden by default and so we must assign a default value or an answer may not be returned (since advanced options are not shown by default)
|
|
229
|
-
const defaultValue =
|
|
219
|
+
const defaultValue = defaultPromptValues[advPromptKey];
|
|
230
220
|
// We have a prompt option defined so update it with the advanced option
|
|
231
221
|
if (promptOpt) {
|
|
232
222
|
promptOpt.advancedOption = true;
|
|
@@ -269,48 +259,48 @@ async function createUI5ApplicationPromptOptions(ui5PromptOptions) {
|
|
|
269
259
|
*/
|
|
270
260
|
function createOdataServicePromptOptions(options) {
|
|
271
261
|
let defaultDatasourceSelection;
|
|
272
|
-
const isYUI =
|
|
262
|
+
const isYUI = getHostEnvironment() !== hostEnvironment.cli;
|
|
273
263
|
if (options.capService) {
|
|
274
|
-
defaultDatasourceSelection =
|
|
264
|
+
defaultDatasourceSelection = DatasourceType.capProject;
|
|
275
265
|
}
|
|
276
266
|
else if (options.promptOptions?.systemSelection?.defaultChoice) {
|
|
277
|
-
defaultDatasourceSelection =
|
|
267
|
+
defaultDatasourceSelection = DatasourceType.sapSystem;
|
|
278
268
|
}
|
|
279
269
|
return {
|
|
280
|
-
[
|
|
270
|
+
[odataServiceInquirerPromptNames.datasourceType]: {
|
|
281
271
|
default: defaultDatasourceSelection,
|
|
282
272
|
includeNone: !!options.allowNoDatasource,
|
|
283
273
|
...options.promptOptions?.datasourceType
|
|
284
274
|
},
|
|
285
|
-
[
|
|
275
|
+
[odataServiceInquirerPromptNames.metadataFilePath]: {
|
|
286
276
|
requiredOdataVersion: options.requiredOdataVersion,
|
|
287
277
|
...options.promptOptions?.metadataFilePath
|
|
288
278
|
},
|
|
289
|
-
[
|
|
279
|
+
[odataServiceInquirerPromptNames.capProject]: {
|
|
290
280
|
capSearchPaths: options.workspaceFolders ?? [],
|
|
291
281
|
defaultChoice: options.capService?.projectPath,
|
|
292
|
-
useAutoComplete:
|
|
282
|
+
useAutoComplete: getHostEnvironment() === hostEnvironment.cli,
|
|
293
283
|
...options.promptOptions?.capProject
|
|
294
284
|
},
|
|
295
|
-
[
|
|
285
|
+
[odataServiceInquirerPromptNames.capService]: {
|
|
296
286
|
defaultChoice: options.capService,
|
|
297
287
|
...options.promptOptions?.capService
|
|
298
288
|
},
|
|
299
|
-
[
|
|
289
|
+
[odataServiceInquirerPromptNames.serviceUrl]: {
|
|
300
290
|
requiredOdataVersion: options.requiredOdataVersion,
|
|
301
291
|
showCollaborativeDraftWarning: options.showCollabDraftWarning && isYUI,
|
|
302
292
|
...options.promptOptions?.serviceUrl
|
|
303
293
|
},
|
|
304
|
-
[
|
|
305
|
-
useAutoComplete:
|
|
294
|
+
[odataServiceInquirerPromptNames.serviceSelection]: {
|
|
295
|
+
useAutoComplete: getHostEnvironment() === hostEnvironment.cli,
|
|
306
296
|
requiredOdataVersion: options.requiredOdataVersion,
|
|
307
297
|
showCollaborativeDraftWarning: options.showCollabDraftWarning && isYUI,
|
|
308
298
|
...options.promptOptions?.serviceSelection
|
|
309
299
|
},
|
|
310
|
-
[
|
|
300
|
+
[odataServiceInquirerPromptNames.userSystemName]: {
|
|
311
301
|
...options.promptOptions?.userSystemName
|
|
312
302
|
},
|
|
313
|
-
[
|
|
303
|
+
[odataServiceInquirerPromptNames.systemSelection]: {
|
|
314
304
|
destinationFilters: {
|
|
315
305
|
odata_abap: true,
|
|
316
306
|
full_service_url: true,
|
|
@@ -320,7 +310,7 @@ function createOdataServicePromptOptions(options) {
|
|
|
320
310
|
includeCloudFoundryAbapEnvChoice: true,
|
|
321
311
|
...options.promptOptions?.systemSelection
|
|
322
312
|
},
|
|
323
|
-
[
|
|
313
|
+
[odataServiceInquirerPromptNames.valueHelpDownload]: {
|
|
324
314
|
hide: false,
|
|
325
315
|
...options.promptOptions?.valueHelpDownload
|
|
326
316
|
}
|
|
@@ -2,7 +2,7 @@ import type Generator from 'yeoman-generator';
|
|
|
2
2
|
import type { AppWizard } from '@sap-devx/yeoman-ui-types';
|
|
3
3
|
import type { ILogWrapper } from '@sap-ux/fiori-generator-shared';
|
|
4
4
|
import type { FLPConfigPromptOptions } from '@sap-ux/flp-config-sub-generator';
|
|
5
|
-
import type { Service } from '../types';
|
|
5
|
+
import type { Service } from '../types/index.js';
|
|
6
6
|
import type { DeployConfigSubGenPromptOptions } from '@sap-ux/deploy-config-sub-generator';
|
|
7
7
|
/**
|
|
8
8
|
* Add the '@sap/fiori:fiori-deployment' generator as a subgenerator.
|
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
exports.addFlpGen = addFlpGen;
|
|
5
|
-
const node_path_1 = require("node:path");
|
|
6
|
-
const types_1 = require("../types");
|
|
7
|
-
const fiori_generator_shared_1 = require("@sap-ux/fiori-generator-shared");
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { defaultNavActionDisplay } from '../types/index.js';
|
|
3
|
+
import { getSemanticObject } from '@sap-ux/fiori-generator-shared';
|
|
8
4
|
/**
|
|
9
5
|
* Add the '@sap/fiori:fiori-deployment' generator as a subgenerator.
|
|
10
6
|
*
|
|
@@ -18,7 +14,7 @@ const fiori_generator_shared_1 = require("@sap-ux/fiori-generator-shared");
|
|
|
18
14
|
* @param appWizard - instance of the AppWizard
|
|
19
15
|
* @param promptSettings - prompt settings for the deployment generator
|
|
20
16
|
*/
|
|
21
|
-
async function addDeployGen({ service, projectName, targetFolder, applicationType }, composeWith, logger, appWizard, promptSettings) {
|
|
17
|
+
export async function addDeployGen({ service, projectName, targetFolder, applicationType }, composeWith, logger, appWizard, promptSettings) {
|
|
22
18
|
await composeWith('@sap/fiori:deploy-config', {
|
|
23
19
|
launchDeployConfigAsSubGenerator: true,
|
|
24
20
|
appGenServiceHost: service.host,
|
|
@@ -50,12 +46,12 @@ async function addDeployGen({ service, projectName, targetFolder, applicationTyp
|
|
|
50
46
|
* @param vscode
|
|
51
47
|
* @param promptSettings - prompt settings for the flp generator used in the inquirer
|
|
52
48
|
*/
|
|
53
|
-
async function addFlpGen({ projectName, targetFolder, title, skipPrompt }, composeWith, logger, appWizard, vscode, promptSettings) {
|
|
49
|
+
export async function addFlpGen({ projectName, targetFolder, title, skipPrompt }, composeWith, logger, appWizard, vscode, promptSettings) {
|
|
54
50
|
let flpConfigOptions = {
|
|
55
51
|
launchFlpConfigAsSubGenerator: true,
|
|
56
52
|
appWizard,
|
|
57
53
|
vscode,
|
|
58
|
-
appRootPath:
|
|
54
|
+
appRootPath: join(targetFolder, projectName),
|
|
59
55
|
logWrapper: logger,
|
|
60
56
|
inquirerPromptOptions: promptSettings
|
|
61
57
|
};
|
|
@@ -64,8 +60,8 @@ async function addFlpGen({ projectName, targetFolder, title, skipPrompt }, compo
|
|
|
64
60
|
...flpConfigOptions,
|
|
65
61
|
skipPrompt: true,
|
|
66
62
|
inboundConfig: {
|
|
67
|
-
semanticObject:
|
|
68
|
-
action:
|
|
63
|
+
semanticObject: getSemanticObject(projectName),
|
|
64
|
+
action: defaultNavActionDisplay,
|
|
69
65
|
title
|
|
70
66
|
}
|
|
71
67
|
};
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import type { Template as TemplateSettingsFE } from '@sap-ux/fiori-elements-writer';
|
|
2
2
|
import { TemplateType as TemplateTypeFE } from '@sap-ux/fiori-elements-writer';
|
|
3
|
-
import type { Template as TemplateSettingsFF } from '@sap-ux/fiori-freestyle-writer';
|
|
3
|
+
import type { Template as TemplateSettingsFF, BasicAppSettings } from '@sap-ux/fiori-freestyle-writer';
|
|
4
4
|
import { TemplateType as TemplateTypeFF } from '@sap-ux/fiori-freestyle-writer';
|
|
5
|
-
import type { BasicAppSettings } from '@sap-ux/fiori-freestyle-writer/dist/types';
|
|
6
5
|
import { type EntityRelatedAnswers } from '@sap-ux/odata-service-inquirer';
|
|
7
|
-
import type { Floorplan, State } from '../types';
|
|
6
|
+
import type { Floorplan, State } from '../types/index.js';
|
|
8
7
|
/**
|
|
9
8
|
* Get the writer template type from the Fiori App floorplan.
|
|
10
9
|
*
|
|
@@ -1,34 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const ui5_info_1 = require("@sap-ux/ui5-info");
|
|
13
|
-
const types_1 = require("../types");
|
|
14
|
-
const utils_1 = require("../utils");
|
|
15
|
-
const fiori_generator_shared_1 = require("@sap-ux/fiori-generator-shared");
|
|
16
|
-
const feature_toggle_1 = require("@sap-ux/feature-toggle");
|
|
1
|
+
import { Authentication as DestinationAuthType, isAbapEnvironmentOnBtp } from '@sap-ux/btp-utils';
|
|
2
|
+
import { OdataVersion, TemplateType as TemplateTypeFE } from '@sap-ux/fiori-elements-writer';
|
|
3
|
+
import { TemplateType as TemplateTypeFF } from '@sap-ux/fiori-freestyle-writer';
|
|
4
|
+
import { DatasourceType } from '@sap-ux/odata-service-inquirer';
|
|
5
|
+
import { ServiceType } from '@sap-ux/odata-service-writer';
|
|
6
|
+
import { AuthenticationType } from '@sap-ux/store';
|
|
7
|
+
import { latestVersionString } from '@sap-ux/ui5-info';
|
|
8
|
+
import { DEFAULT_HOST, DEFAULT_SERVICE_PATH, FPM_DEFAULT_PAGE_NAME, FloorplanFE, FloorplanFF, MAIN_DATASOURCE_NAME, MAIN_MODEL_NAME, UI5_VERSION_PROPS } from '../types/index.js';
|
|
9
|
+
import { assignSapUxLayerValue, convertCapRuntimeToCapProjectType, generateToolsId, getAnnotations, getAppId, getMinSupportedUI5Version } from '../utils/index.js';
|
|
10
|
+
import { hostEnvironment, getHostEnvironment } from '@sap-ux/fiori-generator-shared';
|
|
11
|
+
import { isFeatureEnabled } from '@sap-ux/feature-toggle';
|
|
17
12
|
/**
|
|
18
13
|
* Get the writer template type from the Fiori App floorplan.
|
|
19
14
|
*
|
|
20
15
|
* @param floorplan
|
|
21
16
|
* @returns {TemplateTypeFE | TemplateTypeFF} - The template type
|
|
22
17
|
*/
|
|
23
|
-
function getTemplateType(floorplan) {
|
|
18
|
+
export function getTemplateType(floorplan) {
|
|
24
19
|
const templateMap = {
|
|
25
|
-
[
|
|
26
|
-
[
|
|
27
|
-
[
|
|
28
|
-
[
|
|
29
|
-
[
|
|
30
|
-
[
|
|
31
|
-
[
|
|
20
|
+
[FloorplanFE.FE_ALP]: 'alp',
|
|
21
|
+
[FloorplanFE.FE_FEOP]: 'feop',
|
|
22
|
+
[FloorplanFE.FE_LROP]: 'lrop',
|
|
23
|
+
[FloorplanFE.FE_OVP]: 'ovp',
|
|
24
|
+
[FloorplanFE.FE_WORKLIST]: 'worklist',
|
|
25
|
+
[FloorplanFE.FE_FPM]: 'fpm',
|
|
26
|
+
[FloorplanFF.FF_SIMPLE]: 'basic'
|
|
32
27
|
};
|
|
33
28
|
return templateMap[floorplan];
|
|
34
29
|
}
|
|
@@ -40,10 +35,10 @@ function getTemplateType(floorplan) {
|
|
|
40
35
|
* @param viewName
|
|
41
36
|
* @returns {Template} - The template configuration
|
|
42
37
|
*/
|
|
43
|
-
function transformTemplateType(floorplan, entityRelatedConfig, viewName) {
|
|
44
|
-
if (floorplan ===
|
|
38
|
+
export function transformTemplateType(floorplan, entityRelatedConfig, viewName) {
|
|
39
|
+
if (floorplan === FloorplanFF.FF_SIMPLE) {
|
|
45
40
|
return {
|
|
46
|
-
type:
|
|
41
|
+
type: TemplateTypeFF.Basic, // We only support one template type now so it can be hardcoded
|
|
47
42
|
settings: {
|
|
48
43
|
viewName
|
|
49
44
|
}
|
|
@@ -71,12 +66,12 @@ function transformTemplateType(floorplan, entityRelatedConfig, viewName) {
|
|
|
71
66
|
? { pageBuildingBlockTitle: entityRelatedConfig.pageBuildingBlockTitle }
|
|
72
67
|
: {};
|
|
73
68
|
const templateSettingsMap = {
|
|
74
|
-
[
|
|
69
|
+
[TemplateTypeFE.ListReportObjectPage]: {
|
|
75
70
|
entityConfig: _entityConfig,
|
|
76
71
|
tableType: entityRelatedConfig?.tableType,
|
|
77
72
|
hierarchyQualifier: entityRelatedConfig?.hierarchyQualifier
|
|
78
73
|
},
|
|
79
|
-
[
|
|
74
|
+
[TemplateTypeFE.AnalyticalListPage]: {
|
|
80
75
|
entityConfig: _entityConfig,
|
|
81
76
|
selectionMode: entityRelatedConfig?.tableSelectionMode,
|
|
82
77
|
tableType: entityRelatedConfig?.tableType,
|
|
@@ -88,21 +83,21 @@ function transformTemplateType(floorplan, entityRelatedConfig, viewName) {
|
|
|
88
83
|
: entityRelatedConfig?.presentationQualifier,
|
|
89
84
|
smartVariantManagement: entityRelatedConfig?.smartVariantManagement
|
|
90
85
|
},
|
|
91
|
-
[
|
|
86
|
+
[TemplateTypeFE.FormEntryObjectPage]: {
|
|
92
87
|
entityConfig: _entityConfig
|
|
93
88
|
},
|
|
94
|
-
[
|
|
89
|
+
[TemplateTypeFE.OverviewPage]: {
|
|
95
90
|
filterEntitySet: entityRelatedConfig?.filterEntitySet?.entitySetName
|
|
96
91
|
},
|
|
97
|
-
[
|
|
92
|
+
[TemplateTypeFE.Worklist]: {
|
|
98
93
|
entityConfig: _entityConfig,
|
|
99
94
|
tableType: entityRelatedConfig?.tableType,
|
|
100
95
|
hierarchyQualifier: entityRelatedConfig?.hierarchyQualifier
|
|
101
96
|
},
|
|
102
|
-
[
|
|
97
|
+
[TemplateTypeFE.FlexibleProgrammingModel]: {
|
|
103
98
|
entityConfig: _entityConfig,
|
|
104
99
|
...pageBuildingBlockConfig,
|
|
105
|
-
pageName:
|
|
100
|
+
pageName: FPM_DEFAULT_PAGE_NAME
|
|
106
101
|
}
|
|
107
102
|
};
|
|
108
103
|
const fewTemplate = {
|
|
@@ -119,12 +114,12 @@ function transformTemplateType(floorplan, entityRelatedConfig, viewName) {
|
|
|
119
114
|
*/
|
|
120
115
|
function canGenerateTests(templateType) {
|
|
121
116
|
return ([
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
].includes(templateType) || templateType ===
|
|
117
|
+
TemplateTypeFE.FormEntryObjectPage,
|
|
118
|
+
TemplateTypeFE.AnalyticalListPage,
|
|
119
|
+
TemplateTypeFE.ListReportObjectPage,
|
|
120
|
+
TemplateTypeFE.Worklist,
|
|
121
|
+
TemplateTypeFE.FlexibleProgrammingModel
|
|
122
|
+
].includes(templateType) || templateType === TemplateTypeFF.Basic);
|
|
128
123
|
}
|
|
129
124
|
/**
|
|
130
125
|
* Get the ui5 uri used in yaml and index files.
|
|
@@ -134,7 +129,7 @@ function canGenerateTests(templateType) {
|
|
|
134
129
|
function getUI5Uri() {
|
|
135
130
|
// Remove any trailing '/' 2083 is the max length of a URL for some supported browsers
|
|
136
131
|
const envSetUI5CdnUrl = process.env.UI5_CDN_URL?.replace(/\/{1,2083}$/, '');
|
|
137
|
-
return envSetUI5CdnUrl ??
|
|
132
|
+
return envSetUI5CdnUrl ?? UI5_VERSION_PROPS.OFFICIAL_URL;
|
|
138
133
|
}
|
|
139
134
|
/**
|
|
140
135
|
* Return the preview settings for the app configuration based on the service configuration.
|
|
@@ -144,17 +139,17 @@ function getUI5Uri() {
|
|
|
144
139
|
*/
|
|
145
140
|
function getPreviewSettings(service) {
|
|
146
141
|
let previewSettings = {};
|
|
147
|
-
if (service.destinationAuthType ===
|
|
148
|
-
service.connectedSystem?.destination?.Authentication ===
|
|
149
|
-
|
|
142
|
+
if (service.destinationAuthType === DestinationAuthType.SAML_ASSERTION ||
|
|
143
|
+
service.connectedSystem?.destination?.Authentication === DestinationAuthType.SAML_ASSERTION ||
|
|
144
|
+
AuthenticationType.ReentranceTicket === service.connectedSystem?.backendSystem?.authenticationType ||
|
|
150
145
|
// Apps generated with stored service keys (legacy) will use re-entrance tickets for connectivity
|
|
151
146
|
// New stored systems will only use re-entrance
|
|
152
147
|
service.connectedSystem?.backendSystem?.serviceKeys ||
|
|
153
148
|
// If 'cloud' this will enable preview on VSCode (using re-entrance) for app portability
|
|
154
|
-
(
|
|
149
|
+
(getHostEnvironment() === hostEnvironment.bas &&
|
|
155
150
|
service.connectedSystem?.destination &&
|
|
156
|
-
|
|
157
|
-
previewSettings = { authenticationType:
|
|
151
|
+
isAbapEnvironmentOnBtp(service.connectedSystem?.destination))) {
|
|
152
|
+
previewSettings = { authenticationType: AuthenticationType.ReentranceTicket };
|
|
158
153
|
}
|
|
159
154
|
else if (service.apiHubConfig) {
|
|
160
155
|
previewSettings = { apiHub: true };
|
|
@@ -181,21 +176,21 @@ function getPreviewSettings(service) {
|
|
|
181
176
|
* @param generateIndexHtml
|
|
182
177
|
* @returns {FioriElementsApp<T>} - The app configuration
|
|
183
178
|
*/
|
|
184
|
-
async function transformState({ project, service, floorplan, entityRelatedConfig, viewName }, generateIndexHtml = true) {
|
|
179
|
+
export async function transformState({ project, service, floorplan, entityRelatedConfig, viewName }, generateIndexHtml = true) {
|
|
185
180
|
const appConfig = getBaseAppConfig({ project, service, floorplan, entityRelatedConfig, viewName }, generateIndexHtml);
|
|
186
|
-
if (service.source !==
|
|
181
|
+
if (service.source !== DatasourceType.none) {
|
|
187
182
|
appConfig.service = {
|
|
188
|
-
url: service.host ?? (service.edmx ? undefined :
|
|
189
|
-
path: service.servicePath ||
|
|
190
|
-
type: service.capService ?
|
|
191
|
-
version: service.version ??
|
|
183
|
+
url: service.host ?? (service.edmx ? undefined : DEFAULT_HOST),
|
|
184
|
+
path: service.servicePath || DEFAULT_SERVICE_PATH,
|
|
185
|
+
type: service.capService ? ServiceType.CDS : ServiceType.EDMX,
|
|
186
|
+
version: service.version ?? OdataVersion.v4, // Wont be set for FF no datasource template flow so default to v4 for now as the service wont be written
|
|
192
187
|
metadata: service.edmx && !service.capService ? service.edmx : undefined,
|
|
193
|
-
name:
|
|
188
|
+
name: MAIN_DATASOURCE_NAME,
|
|
194
189
|
client: service.client,
|
|
195
|
-
model: appConfig.template?.type ===
|
|
190
|
+
model: appConfig.template?.type === TemplateTypeFE.OverviewPage ? MAIN_MODEL_NAME : '', // OVP requires a named default model
|
|
196
191
|
previewSettings: service.previewSettings ?? {},
|
|
197
192
|
annotations: project.skipAnnotations !== true
|
|
198
|
-
? await
|
|
193
|
+
? await getAnnotations(project.name, service.annotations?.[0], service?.capService)
|
|
199
194
|
: undefined,
|
|
200
195
|
ignoreCertError: service.ignoreCertError,
|
|
201
196
|
externalServices: service.valueListMetadata
|
|
@@ -207,7 +202,7 @@ async function transformState({ project, service, floorplan, entityRelatedConfig
|
|
|
207
202
|
};
|
|
208
203
|
}
|
|
209
204
|
if (service.capService) {
|
|
210
|
-
const disableCapRootPkgJsonUpdates =
|
|
205
|
+
const disableCapRootPkgJsonUpdates = isFeatureEnabled('sap.ux.testBetaFeatures.disableCapRootPkgJsonUpdates');
|
|
211
206
|
const { cdsUi5PluginInfo, ...capServiceInfo } = service.capService;
|
|
212
207
|
appConfig.service.capService = {
|
|
213
208
|
...capServiceInfo,
|
|
@@ -241,8 +236,8 @@ async function transformState({ project, service, floorplan, entityRelatedConfig
|
|
|
241
236
|
* @returns the default ui5 version to be applied when calling the writers
|
|
242
237
|
*/
|
|
243
238
|
function getUI5VersionDefault(floorplan, ui5Version, odataVersion) {
|
|
244
|
-
if (!ui5Version || ui5Version ===
|
|
245
|
-
const minUI5Version =
|
|
239
|
+
if (!ui5Version || ui5Version === latestVersionString) {
|
|
240
|
+
const minUI5Version = getMinSupportedUI5Version(odataVersion ?? OdataVersion.v4, floorplan);
|
|
246
241
|
// If the UI5 version is not specified, we should use the minimum supported version for the given OData version as the manifest `minUI5Version`
|
|
247
242
|
// `ui5Version` should not be specified as this allows the writers to use the correct version and generate ui5 bootstrap code without specifying the version
|
|
248
243
|
return {
|
|
@@ -269,9 +264,9 @@ function getUI5VersionDefault(floorplan, ui5Version, odataVersion) {
|
|
|
269
264
|
* @returns
|
|
270
265
|
*/
|
|
271
266
|
function getBaseAppConfig({ project, service, floorplan, entityRelatedConfig, viewName }, generateIndexHtml) {
|
|
272
|
-
const appId =
|
|
267
|
+
const appId = getAppId(project.name, project.namespace);
|
|
273
268
|
const backendType = service.capService
|
|
274
|
-
?
|
|
269
|
+
? convertCapRuntimeToCapProjectType(service.capService.capType)
|
|
275
270
|
: 'EDMXBackend';
|
|
276
271
|
// FE or FF template settings
|
|
277
272
|
const template = transformTemplateType(floorplan, entityRelatedConfig, viewName);
|
|
@@ -282,7 +277,7 @@ function getBaseAppConfig({ project, service, floorplan, entityRelatedConfig, vi
|
|
|
282
277
|
title: project.title,
|
|
283
278
|
description: project.description,
|
|
284
279
|
sourceTemplate: {
|
|
285
|
-
toolsId:
|
|
280
|
+
toolsId: generateToolsId()
|
|
286
281
|
},
|
|
287
282
|
projectType: backendType
|
|
288
283
|
},
|
|
@@ -290,7 +285,7 @@ function getBaseAppConfig({ project, service, floorplan, entityRelatedConfig, vi
|
|
|
290
285
|
name: project.name,
|
|
291
286
|
description: project.description,
|
|
292
287
|
version: '0.0.1',
|
|
293
|
-
sapuxLayer:
|
|
288
|
+
sapuxLayer: assignSapUxLayerValue(false)
|
|
294
289
|
},
|
|
295
290
|
ui5: {
|
|
296
291
|
version: ui5Version,
|
|
@@ -298,9 +293,9 @@ function getBaseAppConfig({ project, service, floorplan, entityRelatedConfig, vi
|
|
|
298
293
|
ui5Theme: project.ui5Theme,
|
|
299
294
|
localVersion: project.localUI5Version,
|
|
300
295
|
minUI5Version: minUI5Version,
|
|
301
|
-
frameworkUrl: service.capService ?
|
|
296
|
+
frameworkUrl: service.capService ? UI5_VERSION_PROPS.BCP_OFFICIAL_URL : getUI5Uri(),
|
|
302
297
|
// These 2 properties should be removed when: https://github.com/SAP/open-ux-tools/issues/2304 is implemented
|
|
303
|
-
manifestLibs: floorplan ===
|
|
298
|
+
manifestLibs: floorplan === FloorplanFF.FF_SIMPLE ? ['sap.m', 'sap.ui.core'] : undefined,
|
|
304
299
|
ui5Libs: []
|
|
305
300
|
},
|
|
306
301
|
appOptions: {
|
|
@@ -311,7 +306,9 @@ function getBaseAppConfig({ project, service, floorplan, entityRelatedConfig, vi
|
|
|
311
306
|
// Striclty speaking we should not need to guard here. If a template is not supported for OPA test generation then nothing should be generated.
|
|
312
307
|
addTests: canGenerateTests(template.type),
|
|
313
308
|
generateIndex: generateIndexHtml,
|
|
314
|
-
|
|
309
|
+
...(!(floorplan === FloorplanFF.FF_SIMPLE) && {
|
|
310
|
+
addAnnotations: entityRelatedConfig?.addFEOPAnnotations || entityRelatedConfig?.addLineItemAnnotations
|
|
311
|
+
}),
|
|
315
312
|
useVirtualPreviewEndpoints: project.enableVirtualEndpoints,
|
|
316
313
|
addCdsUi5Plugin: project.addCdsUi5Plugin ?? true // Defaults to true
|
|
317
314
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AppGenInfo } from '@sap-ux/fiori-generator-shared';
|
|
2
2
|
import type { Editor } from 'mem-fs-editor';
|
|
3
|
-
import type { ApiHubConfig, State } from '../types';
|
|
3
|
+
import type { ApiHubConfig, State } from '../types/index.js';
|
|
4
4
|
/**
|
|
5
5
|
* Writes app related information files - README.md & .appGenInfo.json.
|
|
6
6
|
* The files are based on the project, service, and additional properties.
|