@sap-ux/fiori-app-sub-generator 0.0.2
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/LICENSE +201 -0
- package/generators/app/index.d.ts +3 -0
- package/generators/app/index.js +5 -0
- package/generators/app-headless/index.d.ts +34 -0
- package/generators/app-headless/index.js +75 -0
- package/generators/app-headless/transforms.d.ts +9 -0
- package/generators/app-headless/transforms.js +208 -0
- package/generators/fiori-app-generator/end.d.ts +49 -0
- package/generators/fiori-app-generator/end.js +105 -0
- package/generators/fiori-app-generator/fioriAppGenerator.d.ts +45 -0
- package/generators/fiori-app-generator/fioriAppGenerator.js +319 -0
- package/generators/fiori-app-generator/fioriAppGeneratorOptions.d.ts +94 -0
- package/generators/fiori-app-generator/fioriAppGeneratorOptions.js +3 -0
- package/generators/fiori-app-generator/index.d.ts +3 -0
- package/generators/fiori-app-generator/index.js +19 -0
- package/generators/fiori-app-generator/install.d.ts +34 -0
- package/generators/fiori-app-generator/install.js +80 -0
- package/generators/fiori-app-generator/prompting.d.ts +84 -0
- package/generators/fiori-app-generator/prompting.js +303 -0
- package/generators/fiori-app-generator/subgenHelpers.d.ts +43 -0
- package/generators/fiori-app-generator/subgenHelpers.js +71 -0
- package/generators/fiori-app-generator/transforms.d.ts +38 -0
- package/generators/fiori-app-generator/transforms.js +278 -0
- package/generators/fiori-app-generator/writing.d.ts +27 -0
- package/generators/fiori-app-generator/writing.js +94 -0
- package/generators/index.d.ts +6 -0
- package/generators/index.js +22 -0
- package/generators/translations/fioriAppSubGenerator.i18n.json +119 -0
- package/generators/types/common.d.ts +46 -0
- package/generators/types/common.js +3 -0
- package/generators/types/constants.d.ts +60 -0
- package/generators/types/constants.js +98 -0
- package/generators/types/external.d.ts +261 -0
- package/generators/types/external.js +88 -0
- package/generators/types/index.d.ts +7 -0
- package/generators/types/index.js +23 -0
- package/generators/types/state.d.ts +149 -0
- package/generators/types/state.js +35 -0
- package/generators/types/telemetryEvents.d.ts +61 -0
- package/generators/types/telemetryEvents.js +3 -0
- package/generators/types/yeomanUiStepConfig.d.ts +13 -0
- package/generators/types/yeomanUiStepConfig.js +3 -0
- package/generators/utils/appWizardCache.d.ts +40 -0
- package/generators/utils/appWizardCache.js +72 -0
- package/generators/utils/command-runner.d.ts +30 -0
- package/generators/utils/command-runner.js +88 -0
- package/generators/utils/common.d.ts +147 -0
- package/generators/utils/common.js +286 -0
- package/generators/utils/eventHooks.d.ts +29 -0
- package/generators/utils/eventHooks.js +48 -0
- package/generators/utils/i18n.d.ts +16 -0
- package/generators/utils/i18n.js +54 -0
- package/generators/utils/index.d.ts +9 -0
- package/generators/utils/index.js +25 -0
- package/generators/utils/sapuxLayer.d.ts +15 -0
- package/generators/utils/sapuxLayer.js +24 -0
- package/generators/utils/stepsHelper.d.ts +47 -0
- package/generators/utils/stepsHelper.js +161 -0
- package/generators/utils/telemetry.d.ts +16 -0
- package/generators/utils/telemetry.js +41 -0
- package/package.json +84 -0
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getTemplateType = getTemplateType;
|
|
4
|
+
exports.transformTemplateType = transformTemplateType;
|
|
5
|
+
exports.transformState = transformState;
|
|
6
|
+
const btp_utils_1 = require("@sap-ux/btp-utils");
|
|
7
|
+
const fiori_elements_writer_1 = require("@sap-ux/fiori-elements-writer");
|
|
8
|
+
const fiori_freestyle_writer_1 = require("@sap-ux/fiori-freestyle-writer");
|
|
9
|
+
const odata_service_inquirer_1 = require("@sap-ux/odata-service-inquirer");
|
|
10
|
+
const odata_service_writer_1 = require("@sap-ux/odata-service-writer");
|
|
11
|
+
const store_1 = require("@sap-ux/store");
|
|
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
|
+
/**
|
|
17
|
+
* Get the writer template type from the Fiori App floorplan.
|
|
18
|
+
*
|
|
19
|
+
* @param floorplan
|
|
20
|
+
* @returns {TemplateTypeFE | TemplateTypeFF} - The template type
|
|
21
|
+
*/
|
|
22
|
+
function getTemplateType(floorplan) {
|
|
23
|
+
const templateMap = {
|
|
24
|
+
[types_1.FloorplanFE.FE_ALP]: 'alp',
|
|
25
|
+
[types_1.FloorplanFE.FE_FEOP]: 'feop',
|
|
26
|
+
[types_1.FloorplanFE.FE_LROP]: 'lrop',
|
|
27
|
+
[types_1.FloorplanFE.FE_OVP]: 'ovp',
|
|
28
|
+
[types_1.FloorplanFE.FE_WORKLIST]: 'worklist',
|
|
29
|
+
[types_1.FloorplanFE.FE_FPM]: 'fpm',
|
|
30
|
+
[types_1.FloorplanFF.FF_SIMPLE]: 'basic'
|
|
31
|
+
};
|
|
32
|
+
return templateMap[floorplan];
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Transform the Fiori App floorplan to the type required by the open source ux-tools writer modules.
|
|
36
|
+
*
|
|
37
|
+
* @param floorplan
|
|
38
|
+
* @param entityRelatedConfig
|
|
39
|
+
* @param viewName
|
|
40
|
+
* @returns {Template} - The template configuration
|
|
41
|
+
*/
|
|
42
|
+
function transformTemplateType(floorplan, entityRelatedConfig, viewName) {
|
|
43
|
+
if (floorplan === types_1.FloorplanFF.FF_SIMPLE) {
|
|
44
|
+
return {
|
|
45
|
+
type: fiori_freestyle_writer_1.TemplateType.Basic, // We only support one template type now so it can be hardcoded
|
|
46
|
+
settings: {
|
|
47
|
+
viewName
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
// Since we have already returned the FF template type, we can safely cast the template type to TemplateTypeFE
|
|
52
|
+
const templateType = getTemplateType(floorplan);
|
|
53
|
+
let _entityConfig;
|
|
54
|
+
if (entityRelatedConfig?.mainEntity) {
|
|
55
|
+
_entityConfig = {
|
|
56
|
+
mainEntityName: entityRelatedConfig.mainEntity.entitySetName
|
|
57
|
+
};
|
|
58
|
+
if (entityRelatedConfig?.navigationEntity?.navigationPropertyName) {
|
|
59
|
+
_entityConfig.navigationEntity = {
|
|
60
|
+
EntitySet: entityRelatedConfig.navigationEntity?.entitySetName,
|
|
61
|
+
Name: entityRelatedConfig.navigationEntity?.navigationPropertyName
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const templateSettingsMap = {
|
|
66
|
+
[fiori_elements_writer_1.TemplateType.ListReportObjectPage]: {
|
|
67
|
+
entityConfig: _entityConfig,
|
|
68
|
+
tableType: entityRelatedConfig?.tableType,
|
|
69
|
+
hierarchyQualifier: entityRelatedConfig?.hierarchyQualifier
|
|
70
|
+
},
|
|
71
|
+
[fiori_elements_writer_1.TemplateType.AnalyticalListPage]: {
|
|
72
|
+
entityConfig: _entityConfig,
|
|
73
|
+
selectionMode: entityRelatedConfig?.tableSelectionMode,
|
|
74
|
+
tableType: entityRelatedConfig?.tableType,
|
|
75
|
+
hierarchyQualifier: entityRelatedConfig?.hierarchyQualifier,
|
|
76
|
+
autoHide: entityRelatedConfig?.tableAutoHide,
|
|
77
|
+
multiSelect: entityRelatedConfig?.tableMultiSelect,
|
|
78
|
+
qualifier: !entityRelatedConfig?.presentationQualifier
|
|
79
|
+
? undefined
|
|
80
|
+
: entityRelatedConfig?.presentationQualifier,
|
|
81
|
+
smartVariantManagement: entityRelatedConfig?.smartVariantManagement
|
|
82
|
+
},
|
|
83
|
+
[fiori_elements_writer_1.TemplateType.FormEntryObjectPage]: {
|
|
84
|
+
entityConfig: _entityConfig
|
|
85
|
+
},
|
|
86
|
+
[fiori_elements_writer_1.TemplateType.OverviewPage]: {
|
|
87
|
+
filterEntityType: entityRelatedConfig?.filterEntityType?.entitySetName
|
|
88
|
+
},
|
|
89
|
+
[fiori_elements_writer_1.TemplateType.Worklist]: {
|
|
90
|
+
entityConfig: _entityConfig,
|
|
91
|
+
tableType: entityRelatedConfig?.tableType,
|
|
92
|
+
hierarchyQualifier: entityRelatedConfig?.hierarchyQualifier
|
|
93
|
+
},
|
|
94
|
+
[fiori_elements_writer_1.TemplateType.FlexibleProgrammingModel]: {
|
|
95
|
+
entityConfig: _entityConfig,
|
|
96
|
+
pageName: types_1.FPM_DEFAULT_PAGE_NAME
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
const fewTemplate = {
|
|
100
|
+
type: templateType,
|
|
101
|
+
settings: templateSettingsMap[templateType]
|
|
102
|
+
};
|
|
103
|
+
return fewTemplate;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Check if the template supports open test generation from the generators perspective.
|
|
107
|
+
*
|
|
108
|
+
* @param templateType
|
|
109
|
+
* @returns {boolean} - true if the template supports open test generation from the generators perspective
|
|
110
|
+
*/
|
|
111
|
+
function canGenerateTests(templateType) {
|
|
112
|
+
return ([
|
|
113
|
+
fiori_elements_writer_1.TemplateType.FormEntryObjectPage,
|
|
114
|
+
fiori_elements_writer_1.TemplateType.AnalyticalListPage,
|
|
115
|
+
fiori_elements_writer_1.TemplateType.ListReportObjectPage,
|
|
116
|
+
fiori_elements_writer_1.TemplateType.Worklist,
|
|
117
|
+
fiori_elements_writer_1.TemplateType.FlexibleProgrammingModel
|
|
118
|
+
].includes(templateType) || templateType === fiori_freestyle_writer_1.TemplateType.Basic);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Get the ui5 uri used in yaml and index files.
|
|
122
|
+
*
|
|
123
|
+
* @returns {string} - The UI5 URI
|
|
124
|
+
*/
|
|
125
|
+
function getUI5Uri() {
|
|
126
|
+
// Remove any trailing '/' 2083 is the max length of a URL for some supported browsers
|
|
127
|
+
const envSetUI5CdnUrl = process.env.UI5_CDN_URL?.replace(/\/{1,2083}$/, '');
|
|
128
|
+
return envSetUI5CdnUrl ?? types_1.UI5_VERSION_PROPS.OFFICIAL_URL;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Transform Fiori Tools State to the type required by the open source ux-tools module.
|
|
132
|
+
* Process inputs to set correct defaults.
|
|
133
|
+
*
|
|
134
|
+
* @param param0
|
|
135
|
+
* @param param0.project
|
|
136
|
+
* @param param0.service
|
|
137
|
+
* @param param0.floorplan
|
|
138
|
+
* @param param0.entityRelatedConfig
|
|
139
|
+
* @param param0.viewName
|
|
140
|
+
* @param generateIndexHtml
|
|
141
|
+
* @returns {FioriElementsApp<T>} - The app configuration
|
|
142
|
+
*/
|
|
143
|
+
async function transformState({ project, service, floorplan, entityRelatedConfig, viewName }, generateIndexHtml = true) {
|
|
144
|
+
const appConfig = getBaseAppConfig({ project, service, floorplan, entityRelatedConfig, viewName }, generateIndexHtml);
|
|
145
|
+
if (service.source !== odata_service_inquirer_1.DatasourceType.none) {
|
|
146
|
+
appConfig.service = {
|
|
147
|
+
url: service.host ?? (service.edmx ? undefined : types_1.DEFAULT_HOST),
|
|
148
|
+
path: service.servicePath || types_1.DEFAULT_SERVICE_PATH,
|
|
149
|
+
type: service.capService ? odata_service_writer_1.ServiceType.CDS : odata_service_writer_1.ServiceType.EDMX,
|
|
150
|
+
version: service.version ?? fiori_elements_writer_1.OdataVersion.v4, // Wont be set for FF no datasource template flow so default to v4 for now as the service wont be written
|
|
151
|
+
metadata: service.edmx && !service.capService ? service.edmx : undefined,
|
|
152
|
+
name: types_1.MAIN_DATASOURCE_NAME,
|
|
153
|
+
client: service.client,
|
|
154
|
+
model: appConfig.template?.type === fiori_elements_writer_1.TemplateType.OverviewPage ? types_1.MAIN_MODEL_NAME : '', // OVP requires a named default model
|
|
155
|
+
previewSettings: {},
|
|
156
|
+
annotations: project.skipAnnotations !== true
|
|
157
|
+
? await (0, utils_1.getAnnotations)(project.name, service.annotations?.[0], service?.capService)
|
|
158
|
+
: undefined
|
|
159
|
+
};
|
|
160
|
+
const destinationName = service.destinationName ?? service.connectedSystem?.destination?.Name;
|
|
161
|
+
if (destinationName) {
|
|
162
|
+
appConfig.service.destination = {
|
|
163
|
+
name: destinationName
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
if (service.capService) {
|
|
167
|
+
const { cdsUi5PluginInfo, ...capServiceInfo } = service.capService;
|
|
168
|
+
appConfig.service.capService = {
|
|
169
|
+
...capServiceInfo,
|
|
170
|
+
cdsUi5PluginInfo
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
if (service.destinationAuthType === btp_utils_1.Authentication.SAML_ASSERTION ||
|
|
174
|
+
service.connectedSystem?.destination?.Authentication === btp_utils_1.Authentication.SAML_ASSERTION ||
|
|
175
|
+
store_1.AuthenticationType.ReentranceTicket === service.connectedSystem?.backendSystem?.authenticationType) {
|
|
176
|
+
appConfig.service.previewSettings = { authenticationType: store_1.AuthenticationType.ReentranceTicket };
|
|
177
|
+
}
|
|
178
|
+
else if (service.connectedSystem?.backendSystem?.serviceKeys ||
|
|
179
|
+
// If 'cloud' write `scp` property to yamls to enable preview on VSCode (using oAuth)
|
|
180
|
+
((0, fiori_generator_shared_1.getHostEnvironment)() === fiori_generator_shared_1.hostEnvironment.vscode &&
|
|
181
|
+
service.connectedSystem?.destination &&
|
|
182
|
+
(0, btp_utils_1.isAbapEnvironmentOnBtp)(service.connectedSystem?.destination))) {
|
|
183
|
+
appConfig.service.previewSettings = { scp: true };
|
|
184
|
+
}
|
|
185
|
+
else if (service.apiHubConfig) {
|
|
186
|
+
appConfig.service.previewSettings = { apiHub: true };
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return appConfig;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Apply the default values for UI5 version if not specified. This should probably be done in the writers directly.
|
|
193
|
+
*
|
|
194
|
+
* @param floorplan
|
|
195
|
+
* @param ui5Version
|
|
196
|
+
* @param odataVersion
|
|
197
|
+
* @returns the default ui5 version to be applied when calling the writers
|
|
198
|
+
*/
|
|
199
|
+
function getUI5VersionDefault(floorplan, ui5Version, odataVersion) {
|
|
200
|
+
if (!ui5Version || ui5Version === ui5_info_1.latestVersionString) {
|
|
201
|
+
const minUI5Version = (0, utils_1.getMinSupportedUI5Version)(odataVersion ?? fiori_elements_writer_1.OdataVersion.v4, floorplan);
|
|
202
|
+
// If the UI5 version is not specified, we should use the minimum supported version for the given OData version as the manifest `minUI5Version`
|
|
203
|
+
// `ui5Version` should not be specified as this allows the writers to use the correct version and generate ui5 bootstrap code without specifying the version
|
|
204
|
+
return {
|
|
205
|
+
minUI5Version
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
return {
|
|
209
|
+
minUI5Version: ui5Version,
|
|
210
|
+
ui5Version
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Get the base app configuration for the Fiori Elements or Freestyle app.
|
|
215
|
+
* Which type of app is generated is determined by the template type derived from the floorplan specified.
|
|
216
|
+
* This does not assign the service configuration.
|
|
217
|
+
*
|
|
218
|
+
* @param state
|
|
219
|
+
* @param state.project
|
|
220
|
+
* @param state.service
|
|
221
|
+
* @param state.floorplan
|
|
222
|
+
* @param state.entityRelatedConfig
|
|
223
|
+
* @param state.viewName
|
|
224
|
+
* @param generateIndexHtml
|
|
225
|
+
* @returns
|
|
226
|
+
*/
|
|
227
|
+
function getBaseAppConfig({ project, service, floorplan, entityRelatedConfig, viewName }, generateIndexHtml) {
|
|
228
|
+
const appId = (0, utils_1.getAppId)(project.name, project.namespace);
|
|
229
|
+
const backendType = service.capService
|
|
230
|
+
? (0, utils_1.convertCapRuntimeToCapProjectType)(service.capService.capType)
|
|
231
|
+
: 'EDMXBackend';
|
|
232
|
+
// FE or FF template settings
|
|
233
|
+
const template = transformTemplateType(floorplan, entityRelatedConfig, viewName);
|
|
234
|
+
const { minUI5Version, ui5Version } = getUI5VersionDefault(floorplan, project.ui5Version, service.version);
|
|
235
|
+
const appConfig = {
|
|
236
|
+
app: {
|
|
237
|
+
id: appId,
|
|
238
|
+
title: project.title,
|
|
239
|
+
description: project.description,
|
|
240
|
+
flpAppId: (0, utils_1.getFlpId)(appId, floorplan === types_1.FloorplanFF.FF_SIMPLE ? types_1.defaultNavActionDisplay : types_1.defaultNavActionTile),
|
|
241
|
+
sourceTemplate: {
|
|
242
|
+
toolsId: (0, utils_1.generateToolsId)()
|
|
243
|
+
},
|
|
244
|
+
projectType: backendType
|
|
245
|
+
},
|
|
246
|
+
package: {
|
|
247
|
+
name: project.name,
|
|
248
|
+
description: project.description,
|
|
249
|
+
version: '0.0.1',
|
|
250
|
+
sapuxLayer: (0, utils_1.assignSapUxLayerValue)(false)
|
|
251
|
+
},
|
|
252
|
+
ui5: {
|
|
253
|
+
version: ui5Version,
|
|
254
|
+
// descriptorVersion: project.manifestVersion, // The generator never sets this so no need to pass it
|
|
255
|
+
ui5Theme: project.ui5Theme,
|
|
256
|
+
localVersion: project.localUI5Version,
|
|
257
|
+
minUI5Version: minUI5Version,
|
|
258
|
+
frameworkUrl: service.capService ? types_1.UI5_VERSION_PROPS.BCP_OFFICIAL_URL : getUI5Uri(),
|
|
259
|
+
// These 2 properties should be removed when: https://github.com/SAP/open-ux-tools/issues/2304 is implemented
|
|
260
|
+
manifestLibs: floorplan === types_1.FloorplanFF.FF_SIMPLE ? ['sap.m', 'sap.ui.core'] : undefined,
|
|
261
|
+
ui5Libs: []
|
|
262
|
+
},
|
|
263
|
+
appOptions: {
|
|
264
|
+
codeAssist: project.enableCodeAssist,
|
|
265
|
+
eslint: project.enableEslint,
|
|
266
|
+
typescript: project.enableTypeScript,
|
|
267
|
+
sapux: project.sapux,
|
|
268
|
+
loadReuseLibs: !service.capService,
|
|
269
|
+
// Striclty speaking we should not need to guard here. If a template is not supported for OPA test generation then nothing should be generated.
|
|
270
|
+
addTests: canGenerateTests(template.type),
|
|
271
|
+
generateIndex: generateIndexHtml,
|
|
272
|
+
addAnnotations: entityRelatedConfig?.addFEOPAnnotations || entityRelatedConfig?.addLineItemAnnotations
|
|
273
|
+
},
|
|
274
|
+
template: template
|
|
275
|
+
};
|
|
276
|
+
return appConfig;
|
|
277
|
+
}
|
|
278
|
+
//# sourceMappingURL=transforms.js.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ReadMe } from '@sap-ux/fiori-generator-shared';
|
|
2
|
+
import type { Editor } from 'mem-fs-editor';
|
|
3
|
+
import type { ApiHubConfig, State } from '../types';
|
|
4
|
+
/**
|
|
5
|
+
* Writes a README.md file based on project, service, and additional readme properties.
|
|
6
|
+
*
|
|
7
|
+
* @param state
|
|
8
|
+
* @param state.project
|
|
9
|
+
* @param state.service
|
|
10
|
+
* @param state.floorplan
|
|
11
|
+
* @param state.entityRelatedConfig
|
|
12
|
+
* @param generatorName
|
|
13
|
+
* @param generatorVersion
|
|
14
|
+
* @param targetPath
|
|
15
|
+
* @param fs
|
|
16
|
+
* @param readMe
|
|
17
|
+
*/
|
|
18
|
+
export declare function writeReadMe({ project, service, floorplan, entityRelatedConfig }: State, generatorName: string, generatorVersion: string, targetPath: string, fs: Editor, readMe?: Partial<ReadMe>): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Create the files for apiHub integration.
|
|
21
|
+
*
|
|
22
|
+
* @param fs
|
|
23
|
+
* @param destPath
|
|
24
|
+
* @param apiHubConfig
|
|
25
|
+
*/
|
|
26
|
+
export declare function writeAPIHubKeyFiles(fs: Editor, destPath: string, apiHubConfig: ApiHubConfig): void;
|
|
27
|
+
//# sourceMappingURL=writing.d.ts.map
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.writeReadMe = writeReadMe;
|
|
4
|
+
exports.writeAPIHubKeyFiles = writeAPIHubKeyFiles;
|
|
5
|
+
const fiori_generator_shared_1 = require("@sap-ux/fiori-generator-shared");
|
|
6
|
+
const path_1 = require("path");
|
|
7
|
+
const types_1 = require("../types");
|
|
8
|
+
const utils_1 = require("../utils");
|
|
9
|
+
/**
|
|
10
|
+
* Writes a README.md file based on project, service, and additional readme properties.
|
|
11
|
+
*
|
|
12
|
+
* @param state
|
|
13
|
+
* @param state.project
|
|
14
|
+
* @param state.service
|
|
15
|
+
* @param state.floorplan
|
|
16
|
+
* @param state.entityRelatedConfig
|
|
17
|
+
* @param generatorName
|
|
18
|
+
* @param generatorVersion
|
|
19
|
+
* @param targetPath
|
|
20
|
+
* @param fs
|
|
21
|
+
* @param readMe
|
|
22
|
+
*/
|
|
23
|
+
async function writeReadMe({ project, service, floorplan, entityRelatedConfig }, generatorName, generatorVersion, targetPath, fs, readMe) {
|
|
24
|
+
const templateLabel = (0, utils_1.t)(`floorplans.label.${floorplan}`, {
|
|
25
|
+
odataVersion: service.version
|
|
26
|
+
});
|
|
27
|
+
const datasourceLabel = (0, utils_1.getReadMeDataSourceLabel)(service.source, (0, utils_1.isBTPHosted)(service.connectedSystem), service.apiHubConfig?.apiHubType);
|
|
28
|
+
// Assign any custom overriding properties that may be provided via headless, adaptors
|
|
29
|
+
const readMeCustom = Object.assign({
|
|
30
|
+
generatorName,
|
|
31
|
+
generatorVersion,
|
|
32
|
+
template: templateLabel,
|
|
33
|
+
serviceType: datasourceLabel,
|
|
34
|
+
serviceUrl: `${service.capService ? types_1.DEFAULT_CAP_HOST : service.host ?? ''}${service.servicePath ?? ''}` ||
|
|
35
|
+
(0, utils_1.t)('texts.notApplicable')
|
|
36
|
+
}, readMe);
|
|
37
|
+
readMeCustom.additionalEntries ??= [];
|
|
38
|
+
if (entityRelatedConfig?.mainEntity) {
|
|
39
|
+
readMeCustom.additionalEntries.push({
|
|
40
|
+
label: (0, utils_1.t)('readme.label.mainEntity'),
|
|
41
|
+
value: entityRelatedConfig.mainEntity.entitySetName
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
if (entityRelatedConfig?.navigationEntity) {
|
|
45
|
+
readMeCustom.additionalEntries.push({
|
|
46
|
+
label: (0, utils_1.t)('readme.label.navigationEntity'),
|
|
47
|
+
value: entityRelatedConfig.navigationEntity.navigationPropertyName || 'None'
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
if (entityRelatedConfig?.filterEntityType) {
|
|
51
|
+
readMeCustom.additionalEntries.push({
|
|
52
|
+
label: (0, utils_1.t)('readme.label.filterEntityType'),
|
|
53
|
+
value: entityRelatedConfig.filterEntityType.entitySetName
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
const launchText = await (0, utils_1.getLaunchText)(service.capService, project.name, !!project.enableTypeScript, project.namespace);
|
|
57
|
+
const readme = {
|
|
58
|
+
generationDate: readMeCustom?.generationDate ?? new Date().toString(),
|
|
59
|
+
generatorPlatform: readMeCustom?.generatorPlatform ?? (0, fiori_generator_shared_1.getHostEnvironment)().name,
|
|
60
|
+
serviceType: readMeCustom?.serviceType,
|
|
61
|
+
metadataFilename: service.localEdmxFilePath ? (0, path_1.basename)(service.localEdmxFilePath) : '',
|
|
62
|
+
serviceUrl: readMeCustom?.serviceUrl,
|
|
63
|
+
appName: project.name,
|
|
64
|
+
appTitle: project.title,
|
|
65
|
+
appDescription: project.description,
|
|
66
|
+
appNamespace: project.namespace ?? '',
|
|
67
|
+
ui5Theme: project.ui5Theme,
|
|
68
|
+
ui5Version: readMeCustom?.ui5Version || project.manifestMinUI5Version || project.ui5Version,
|
|
69
|
+
enableCodeAssist: project.enableCodeAssist,
|
|
70
|
+
enableEslint: project.enableEslint,
|
|
71
|
+
enableTypeScript: project.enableTypeScript,
|
|
72
|
+
showMockDataInfo: !!service.edmx && !service.capService,
|
|
73
|
+
generatorVersion: readMeCustom?.generatorVersion ?? '',
|
|
74
|
+
template: readMeCustom?.template ?? '',
|
|
75
|
+
generatorName: readMeCustom?.generatorName ?? '',
|
|
76
|
+
additionalEntries: readMeCustom?.additionalEntries ?? [],
|
|
77
|
+
launchText
|
|
78
|
+
};
|
|
79
|
+
(0, fiori_generator_shared_1.generateReadMe)(targetPath, readme, fs);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Create the files for apiHub integration.
|
|
83
|
+
*
|
|
84
|
+
* @param fs
|
|
85
|
+
* @param destPath
|
|
86
|
+
* @param apiHubConfig
|
|
87
|
+
*/
|
|
88
|
+
function writeAPIHubKeyFiles(fs, destPath, apiHubConfig) {
|
|
89
|
+
const envFilePath = (0, path_1.join)(destPath, '.env');
|
|
90
|
+
const envContent = `API_HUB_API_KEY=${apiHubConfig.apiHubKey}\nAPI_HUB_TYPE=${apiHubConfig.apiHubType}`;
|
|
91
|
+
// Create .env to store apiHub integration.
|
|
92
|
+
fs.write(envFilePath, envContent);
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=writing.js.map
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./types"), exports);
|
|
18
|
+
__exportStar(require("./app"), exports);
|
|
19
|
+
__exportStar(require("./app-headless"), exports);
|
|
20
|
+
__exportStar(require("./utils"), exports);
|
|
21
|
+
__exportStar(require("./fiori-app-generator"), exports);
|
|
22
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
{
|
|
2
|
+
"floorplans": {
|
|
3
|
+
"label": {
|
|
4
|
+
"basic": "Basic{{odataVersion, odataVersionFormatter}}",
|
|
5
|
+
"fpm": "Custom Page{{odataVersion, odataVersionFormatter}}",
|
|
6
|
+
"lrop": "List Report Page{{odataVersion, odataVersionFormatter}}",
|
|
7
|
+
"worklist": "Worklist Page{{odataVersion, odataVersionFormatter}}",
|
|
8
|
+
"alp": "Analytical List Page{{odataVersion, odataVersionFormatter}}",
|
|
9
|
+
"ovp": "Overview Page{{odataVersion, odataVersionFormatter}}",
|
|
10
|
+
"feop": "Form Entry Object Page{{odataVersion, odataVersionFormatter}}"
|
|
11
|
+
},
|
|
12
|
+
"description": {
|
|
13
|
+
"basic": "Create a freestyle application, starting with an empty page.",
|
|
14
|
+
"fpm": "Create an SAP Fiori elements application containing a custom page based on the flexible programming model.",
|
|
15
|
+
"lrop": "Create an SAP Fiori elements application containing a list report and an object page.",
|
|
16
|
+
"worklist": "Create an SAP Fiori elements application containing a worklist and an object page.",
|
|
17
|
+
"alp": "Create an SAP Fiori elements application containing an analytical list and an object page.",
|
|
18
|
+
"ovp": "Create an SAP Fiori elements application containing an overview page.",
|
|
19
|
+
"feop": "Create an SAP Fiori elements application containing an object page optimized for data entry."
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"defaults": {
|
|
23
|
+
"projectName": "project{{defaultProjectNumber}}",
|
|
24
|
+
"projectTitle": "App Title",
|
|
25
|
+
"projectDescription": "An SAP Fiori application."
|
|
26
|
+
},
|
|
27
|
+
"readme": {
|
|
28
|
+
"label": {
|
|
29
|
+
"mainEntity": "Main Entity",
|
|
30
|
+
"filterEntityType": "Filter Entity Type",
|
|
31
|
+
"navigationEntity": "Navigation Entity",
|
|
32
|
+
"sapSystemType": {
|
|
33
|
+
"abapOnBtp": "ABAP Environment on SAP Business Technology Platform",
|
|
34
|
+
"s4hc": "SAP S/4HANA Cloud Environment",
|
|
35
|
+
"onPrem": "ABAP On Premise"
|
|
36
|
+
},
|
|
37
|
+
"datasourceType": {
|
|
38
|
+
"sapSystem": "SAP System",
|
|
39
|
+
"buinessHub": "SAP Business Accelerator Hub",
|
|
40
|
+
"apiBusinessHubEnterprise": "SAP API Business Hub Enterprise",
|
|
41
|
+
"capProject": "Local Cap",
|
|
42
|
+
"odataServiceUrl": "OData Url",
|
|
43
|
+
"none": "None",
|
|
44
|
+
"metadataFile": "File",
|
|
45
|
+
"projectSpecificDestination": "MTA File"
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"texts": {
|
|
49
|
+
"runInstruction": "In order to launch the generated app, simply run the following from the generated app root folder:\n\n```\n npm start\n```"
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
"texts": {
|
|
53
|
+
"notApplicable": "N/A"
|
|
54
|
+
},
|
|
55
|
+
"steps": {
|
|
56
|
+
"templateSelection": {
|
|
57
|
+
"description": "Choose your application template.",
|
|
58
|
+
"title": "Template Selection"
|
|
59
|
+
},
|
|
60
|
+
"datasourceAndServiceSelection": {
|
|
61
|
+
"description": "Configure the data source and select a service.",
|
|
62
|
+
"title": "Data Source and Service Selection"
|
|
63
|
+
},
|
|
64
|
+
"entityOrViewConfig": {
|
|
65
|
+
"description": "Configure the selected service.",
|
|
66
|
+
"title": "Entity Selection"
|
|
67
|
+
},
|
|
68
|
+
"projectAttributesConfig": {
|
|
69
|
+
"description": "Configure the main project attributes.",
|
|
70
|
+
"title": "Project Attributes"
|
|
71
|
+
},
|
|
72
|
+
"deployConfig": {
|
|
73
|
+
"description": "Configure deployment settings.",
|
|
74
|
+
"title": "Deployment Configuration"
|
|
75
|
+
},
|
|
76
|
+
"flpConfig": {
|
|
77
|
+
"description": "Configure Fiori Launchpad settings{{appFolderName}}.",
|
|
78
|
+
"title": "Fiori Launchpad Configuration"
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
"logMessages": {
|
|
82
|
+
"installingDependencies": "Installing dependencies to package path: {{- path}}...",
|
|
83
|
+
"dependenciesInstalled": "Project dependencies installed in {{installTime}} seconds",
|
|
84
|
+
"errorInstallingDependencies": "Unknown error while installing project dependencies.",
|
|
85
|
+
"commandFailedWithError": "{{command}} failed with error code {{errorCode}}.",
|
|
86
|
+
"commandErrorCodeWithStack": "Error code {{errorCode}} returned from {{command}}. {{stack}}",
|
|
87
|
+
"applicationGenerationSuccess": "Application generated successfully, available at {{- targetFolder}}",
|
|
88
|
+
"copyingTemplateFiles": "Copying '{{templateName}}' template files...",
|
|
89
|
+
"generatingAppWithVersion": "Generating application with {{- generatorName}} {{generatorVersion}}",
|
|
90
|
+
"warningCachingNotSupported": "Warning: caching is not supported",
|
|
91
|
+
"attemptingToExecutePostGenerationCommand": "Attempting to execute command after app generation: {{- command}}",
|
|
92
|
+
"installSkippedOptionSpecified": "Option `--skipInstall` was specified. Installation of dependencies will be skipped.",
|
|
93
|
+
"generatorExiting": "Application generation exiting due to error: {{error}}"
|
|
94
|
+
},
|
|
95
|
+
"error": {
|
|
96
|
+
"fatalError": "An error has occurred, please restart the generator",
|
|
97
|
+
"errorWritingApplicationFiles": "An error occurred writing application files",
|
|
98
|
+
"appConfigVersion": "Application config version must match a supported version: {{versions}}",
|
|
99
|
+
"appConfigUnparseableEdmx": "Application config property edmx cannot be parsed",
|
|
100
|
+
"appConfigMissingRequiredProperty": "Application config is missing a required property: {{propertyName}}",
|
|
101
|
+
"edmxNotFound": "Edmx (metadata) is required to continue with generation. Application generation exiting.",
|
|
102
|
+
"unsupportedPostGenerationEvent": "Unsupported post generation event: {{event}}",
|
|
103
|
+
"commandFailed": "Command failed with error",
|
|
104
|
+
"invalidYUIStepConfig": "Invalid Yeoman UI step config: First step cannot have dependency property"
|
|
105
|
+
},
|
|
106
|
+
"wizardMessages": {
|
|
107
|
+
"filesGenerated": "The files have been generated."
|
|
108
|
+
},
|
|
109
|
+
"prompts": {
|
|
110
|
+
"viewName": {
|
|
111
|
+
"message": "View name",
|
|
112
|
+
"validationMessages": {
|
|
113
|
+
"viewNameRequired": "You must provide a view name in order to continue.",
|
|
114
|
+
"viewNameTooLong": "View name cannot contain more than 120 characters",
|
|
115
|
+
"viewNameInvalid": "The view name must start with a letter and may contain letters, digits, dashes, and underscores."
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { DatasourceType, OdataServicePromptOptions, OdataVersion, promptNames } from '@sap-ux/odata-service-inquirer';
|
|
2
|
+
import type { UI5ApplicationPromptOptions } from '@sap-ux/ui5-application-inquirer';
|
|
3
|
+
/**
|
|
4
|
+
* package.json script entries (commands and tasks)
|
|
5
|
+
*/
|
|
6
|
+
export type Script = {
|
|
7
|
+
name: string;
|
|
8
|
+
command: string;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* workspace folder
|
|
12
|
+
*/
|
|
13
|
+
export type WorkspaceFolder = {
|
|
14
|
+
folderName: string;
|
|
15
|
+
path: string;
|
|
16
|
+
};
|
|
17
|
+
export type FioriAppGeneratorPromptSettings = UI5ApplicationPromptOptions & Pick<OdataServicePromptOptions, promptNames.systemSelection>;
|
|
18
|
+
/**
|
|
19
|
+
* Custom environment type until yeoman-environment provides one
|
|
20
|
+
*/
|
|
21
|
+
export interface YeomanEnvironment {
|
|
22
|
+
conflicter: {
|
|
23
|
+
force: boolean;
|
|
24
|
+
};
|
|
25
|
+
adapter: {
|
|
26
|
+
actualAdapter: unknown;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Defines the options required for generating a launch configuration for a project.
|
|
31
|
+
*/
|
|
32
|
+
export interface GenerateLaunchConfigOptions {
|
|
33
|
+
/** The type of data source used by the project (e.g. metadata file or OData source URL). */
|
|
34
|
+
datasourceType: DatasourceType;
|
|
35
|
+
/** SAP client parameter. */
|
|
36
|
+
sapClientParam?: string;
|
|
37
|
+
/** The file path to the root directory of the project. */
|
|
38
|
+
targetFolder: string;
|
|
39
|
+
/** The name of the project. */
|
|
40
|
+
projectName: string;
|
|
41
|
+
/** The application ID for the project. */
|
|
42
|
+
flpAppId?: string;
|
|
43
|
+
/** Optional OData service version (e.g. v2 or v4). */
|
|
44
|
+
odataVersion?: OdataVersion;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=common.d.ts.map
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { FioriStep } from './yeomanUiStepConfig';
|
|
2
|
+
export declare const LEGACY_CAP_TYPE_NODE = "capNode";
|
|
3
|
+
export declare const LEGACY_CAP_TYPE_JAVA = "capJava";
|
|
4
|
+
export declare const enum SapSystemSourceType {
|
|
5
|
+
SCP = "abapOnBtp",
|
|
6
|
+
ON_PREM = "onPrem",
|
|
7
|
+
S4HC = "s4hc"
|
|
8
|
+
}
|
|
9
|
+
export declare const PLATFORMS: {
|
|
10
|
+
VSCODE: {
|
|
11
|
+
name: string;
|
|
12
|
+
technical: string;
|
|
13
|
+
};
|
|
14
|
+
SBAS: {
|
|
15
|
+
name: string;
|
|
16
|
+
technical: string;
|
|
17
|
+
};
|
|
18
|
+
CLI: {
|
|
19
|
+
name: string;
|
|
20
|
+
technical: string;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
export declare const UI5_VERSION_PROPS: {
|
|
24
|
+
OFFICIAL_URL: string;
|
|
25
|
+
BCP_OFFICIAL_URL: string;
|
|
26
|
+
SNAPSHOT_URL: string;
|
|
27
|
+
VERSIONS_FILE: string;
|
|
28
|
+
};
|
|
29
|
+
export declare const SAP_CLIENT_KEY = "sap-client";
|
|
30
|
+
export declare const API_HUB_API_KEY = "API_HUB_API_KEY";
|
|
31
|
+
export declare const API_HUB_TYPE = "API_HUB_TYPE";
|
|
32
|
+
export declare const enum ApiHubType {
|
|
33
|
+
apiHub = "API_HUB",
|
|
34
|
+
apiHubEnterprise = "API_HUB_ENTERPRISE"
|
|
35
|
+
}
|
|
36
|
+
export declare const STEP_FLOORPLAN = "FLOORPLAN";
|
|
37
|
+
export declare const STEP_DATASOURCE_AND_SERVICE = "DATASOURCE_AND_SERVICE";
|
|
38
|
+
export declare const STEP_ENTITY = "ENTITY";
|
|
39
|
+
export declare const STEP_PROJECT_ATTRIBUTES = "PROJECT_ATTRIBUTES";
|
|
40
|
+
export declare const STEP_DEPLOY_CONFIG = "DEPLOY_CONFIG";
|
|
41
|
+
export declare const STEP_FLP_CONFIG = "FLP_CONFIG";
|
|
42
|
+
export declare const FIORI_STEPS: FioriStep[];
|
|
43
|
+
export declare const DEFAULT_HOST = "http://localhost";
|
|
44
|
+
export declare const DEFAULT_CAP_HOST = "http://localhost:4004";
|
|
45
|
+
export declare const DEFAULT_SERVICE_PATH = "/sap/opu/odata";
|
|
46
|
+
export declare const MAIN_DATASOURCE_NAME = "mainService";
|
|
47
|
+
export declare const MAIN_MODEL_NAME = "mainModel";
|
|
48
|
+
export declare const generatorName = "SAP Fiori Application Generator";
|
|
49
|
+
export declare const FPM_DEFAULT_PAGE_NAME = "Main";
|
|
50
|
+
export declare const minSupportedUi5Version = "1.65.0";
|
|
51
|
+
export declare const minSupportedUi5VersionV4 = "1.84.0";
|
|
52
|
+
export declare const defaultNavActionTile = "tile";
|
|
53
|
+
export declare const defaultNavActionDisplay = "display";
|
|
54
|
+
/**
|
|
55
|
+
* Represents a list of App Generator specific feature toggles.
|
|
56
|
+
*/
|
|
57
|
+
export declare enum Features {
|
|
58
|
+
enableGAIntegration = "enableGAIntegration"
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=constants.d.ts.map
|