@sap-ux/repo-app-import-sub-generator 0.3.15 → 0.3.17
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/app-config.js +3 -1
- package/generators/app/index.js +3 -1
- package/generators/prompts/prompt-helpers.js +7 -2
- package/generators/prompts/prompts.d.ts +2 -1
- package/generators/prompts/prompts.js +39 -6
- package/generators/utils/download-utils.js +7 -1
- package/generators/utils/updates.js +15 -1
- package/generators/utils/validators.js +1 -0
- package/package.json +8 -7
|
@@ -46,7 +46,9 @@ exports.getAbapDeployConfig = getAbapDeployConfig;
|
|
|
46
46
|
*/
|
|
47
47
|
const fetchServiceMetadata = async (provider, serviceUrl) => {
|
|
48
48
|
try {
|
|
49
|
-
|
|
49
|
+
const metdata = await provider.service(serviceUrl).metadata();
|
|
50
|
+
logger_1.default.logger?.debug('Metadata fetched successfully');
|
|
51
|
+
return metdata;
|
|
50
52
|
}
|
|
51
53
|
catch (err) {
|
|
52
54
|
logger_1.default.logger?.error((0, i18n_1.t)('error.metadataFetchError', { error: err.message }));
|
package/generators/app/index.js
CHANGED
|
@@ -94,7 +94,7 @@ class default_1 extends yeoman_generator_1.default {
|
|
|
94
94
|
*/
|
|
95
95
|
async prompting() {
|
|
96
96
|
const quickDeployedAppConfig = this.options?.data?.quickDeployedAppConfig;
|
|
97
|
-
const questions = await (0, prompts_1.getPrompts)(this.appRootPath, quickDeployedAppConfig, this.appWizard);
|
|
97
|
+
const questions = await (0, prompts_1.getPrompts)(this.appRootPath, quickDeployedAppConfig, this.appWizard, (0, fiori_generator_shared_1.isCli)());
|
|
98
98
|
const answers = await this.prompt(questions);
|
|
99
99
|
const { targetFolder } = answers;
|
|
100
100
|
if (quickDeployedAppConfig?.appId) {
|
|
@@ -203,7 +203,9 @@ class default_1 extends yeoman_generator_1.default {
|
|
|
203
203
|
async install() {
|
|
204
204
|
if (!this.options.skipInstall) {
|
|
205
205
|
try {
|
|
206
|
+
logger_1.default.logger?.debug('Running npm install...');
|
|
206
207
|
await this._runNpmInstall(this.projectPath);
|
|
208
|
+
logger_1.default.logger?.debug('npm install completed successfully.');
|
|
207
209
|
}
|
|
208
210
|
catch (error) {
|
|
209
211
|
logger_1.default.logger?.error((0, i18n_1.t)('error.installationErrors.npmInstall', { error }));
|
|
@@ -57,9 +57,13 @@ exports.extractAppData = extractAppData;
|
|
|
57
57
|
const formatAppChoices = (appList) => {
|
|
58
58
|
return appList
|
|
59
59
|
.filter((app) => {
|
|
60
|
-
|
|
60
|
+
logger_1.default.logger?.debug(`formatAppChoices: ${JSON.stringify(app)}`);
|
|
61
|
+
const hasRequiredFields = app['sap.app/id'] &&
|
|
62
|
+
app['repoName'] &&
|
|
63
|
+
app['url'] &&
|
|
64
|
+
Object.prototype.hasOwnProperty.call(app, 'sap.app/title'); // allow for empty title
|
|
61
65
|
if (!hasRequiredFields) {
|
|
62
|
-
logger_1.default.logger?.warn((0, i18n_1.t)('warn.requiredFieldsMissing', { app: app.
|
|
66
|
+
logger_1.default.logger?.warn((0, i18n_1.t)('warn.requiredFieldsMissing', { app: app['sap.app/id'] }));
|
|
63
67
|
}
|
|
64
68
|
return hasRequiredFields;
|
|
65
69
|
})
|
|
@@ -85,6 +89,7 @@ async function getAppList(provider, appId) {
|
|
|
85
89
|
}
|
|
86
90
|
catch (error) {
|
|
87
91
|
logger_1.default.logger?.error((0, i18n_1.t)('error.applicationListFetchError', { error: error.message }));
|
|
92
|
+
logger_1.default.logger?.debug((0, i18n_1.t)('error.applicationListFetchError', { error: JSON.stringify(error) }));
|
|
88
93
|
return [];
|
|
89
94
|
}
|
|
90
95
|
}
|
|
@@ -6,7 +6,8 @@ import type { AppWizard } from '@sap-devx/yeoman-ui-types';
|
|
|
6
6
|
* @param {string} [appRootPath] - The root path of the application.
|
|
7
7
|
* @param {QuickDeployedAppConfig} [quickDeployedAppConfig] - The quick deployed app configuration.
|
|
8
8
|
* @param {AppWizard} [appWizard] - The app wizard instance.
|
|
9
|
+
* @param {boolean} [isCli] - Indicates if the prompts are being generated for CLI usage.
|
|
9
10
|
* @returns {Promise<RepoAppDownloadQuestions[]>} A list of prompts for user interaction.
|
|
10
11
|
*/
|
|
11
|
-
export declare function getPrompts(appRootPath?: string, quickDeployedAppConfig?: QuickDeployedAppConfig, appWizard?: AppWizard): Promise<RepoAppDownloadQuestions[]>;
|
|
12
|
+
export declare function getPrompts(appRootPath?: string, quickDeployedAppConfig?: QuickDeployedAppConfig, appWizard?: AppWizard, isCli?: boolean): Promise<RepoAppDownloadQuestions[]>;
|
|
12
13
|
//# sourceMappingURL=prompts.d.ts.map
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.getPrompts = void 0;
|
|
4
7
|
const odata_service_inquirer_1 = require("@sap-ux/odata-service-inquirer");
|
|
@@ -8,6 +11,7 @@ const project_input_validator_1 = require("@sap-ux/project-input-validator");
|
|
|
8
11
|
const prompt_state_1 = require("./prompt-state");
|
|
9
12
|
const prompt_helpers_1 = require("./prompt-helpers");
|
|
10
13
|
const validators_1 = require("../utils/validators");
|
|
14
|
+
const logger_1 = __importDefault(require("../utils/logger"));
|
|
11
15
|
/**
|
|
12
16
|
* Gets the target folder selection prompt.
|
|
13
17
|
*
|
|
@@ -43,23 +47,45 @@ const getTargetFolderPrompt = (appRootPath, appId) => {
|
|
|
43
47
|
default: () => appRootPath
|
|
44
48
|
};
|
|
45
49
|
};
|
|
50
|
+
const getCliValidatePrompts = async (appList, quickDeployedAppConfig, appWizard) => {
|
|
51
|
+
return {
|
|
52
|
+
when: async (answers) => {
|
|
53
|
+
if (answers?.[types_1.PromptNames.selectedApp]) {
|
|
54
|
+
try {
|
|
55
|
+
await (0, validators_1.validateAppSelection)(answers[types_1.PromptNames.selectedApp], appList, quickDeployedAppConfig, appWizard);
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
if (error instanceof Error) {
|
|
59
|
+
logger_1.default.logger?.error(error.message);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
logger_1.default.logger?.error((0, i18n_1.t)('error.appDownloadErrors.validationError', { error: error }));
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return false;
|
|
67
|
+
},
|
|
68
|
+
name: `${types_1.PromptNames.selectedApp}-validation`
|
|
69
|
+
};
|
|
70
|
+
};
|
|
46
71
|
/**
|
|
47
72
|
* Retrieves prompts for selecting a system, app list, and target folder where the app will be generated.
|
|
48
73
|
*
|
|
49
74
|
* @param {string} [appRootPath] - The root path of the application.
|
|
50
75
|
* @param {QuickDeployedAppConfig} [quickDeployedAppConfig] - The quick deployed app configuration.
|
|
51
76
|
* @param {AppWizard} [appWizard] - The app wizard instance.
|
|
77
|
+
* @param {boolean} [isCli] - Indicates if the prompts are being generated for CLI usage.
|
|
52
78
|
* @returns {Promise<RepoAppDownloadQuestions[]>} A list of prompts for user interaction.
|
|
53
79
|
*/
|
|
54
|
-
async function getPrompts(appRootPath, quickDeployedAppConfig, appWizard) {
|
|
80
|
+
async function getPrompts(appRootPath, quickDeployedAppConfig, appWizard, isCli = false) {
|
|
55
81
|
try {
|
|
56
82
|
prompt_state_1.PromptState.reset();
|
|
57
83
|
const systemQuestions = await (0, odata_service_inquirer_1.getSystemSelectionQuestions)({
|
|
58
|
-
serviceSelection: { hide: true },
|
|
84
|
+
serviceSelection: { hide: true, useAutoComplete: isCli },
|
|
59
85
|
systemSelection: { defaultChoice: quickDeployedAppConfig?.serviceProviderInfo?.name }
|
|
60
|
-
},
|
|
86
|
+
}, !isCli);
|
|
61
87
|
let appList = [];
|
|
62
|
-
const
|
|
88
|
+
const appSelectionPrompts = [
|
|
63
89
|
{
|
|
64
90
|
when: async (answers) => {
|
|
65
91
|
if (answers[types_1.PromptNames.systemSelection] &&
|
|
@@ -78,11 +104,18 @@ async function getPrompts(appRootPath, quickDeployedAppConfig, appWizard) {
|
|
|
78
104
|
},
|
|
79
105
|
message: (0, i18n_1.t)('prompts.appSelection.message'),
|
|
80
106
|
choices: () => (appList.length ? (0, prompt_helpers_1.formatAppChoices)(appList) : []),
|
|
81
|
-
validate: async (answers) =>
|
|
107
|
+
validate: async (answers) => {
|
|
108
|
+
const result = await (0, validators_1.validateAppSelection)(answers, appList, quickDeployedAppConfig, appWizard);
|
|
109
|
+
return !!result;
|
|
110
|
+
}
|
|
82
111
|
}
|
|
83
112
|
];
|
|
113
|
+
// Only for CLI use as `list` prompt validation does not run on CLI unless autocomplete plugin is used
|
|
114
|
+
if (isCli) {
|
|
115
|
+
appSelectionPrompts?.push(getCliValidatePrompts(appList, quickDeployedAppConfig, appWizard));
|
|
116
|
+
}
|
|
84
117
|
const targetFolderPrompts = getTargetFolderPrompt(appRootPath, quickDeployedAppConfig?.appId);
|
|
85
|
-
return [...systemQuestions.prompts, ...
|
|
118
|
+
return [...systemQuestions.prompts, ...appSelectionPrompts, targetFolderPrompts];
|
|
86
119
|
}
|
|
87
120
|
catch (error) {
|
|
88
121
|
throw new Error(`Failed to generate prompts: ${error.message}`);
|
|
@@ -32,6 +32,8 @@ async function extractZip(extractedProjectPath, fs) {
|
|
|
32
32
|
if (!zipEntry.isDirectory) {
|
|
33
33
|
// Extract the file content
|
|
34
34
|
const fileContent = zipEntry.getData().toString('utf8');
|
|
35
|
+
const filePath = (0, path_1.join)(extractedProjectPath, zipEntry.entryName);
|
|
36
|
+
logger_1.default.logger?.debug(`extractZip: Extracting file: "${filePath}" with contents: "${fileContent}" .`);
|
|
35
37
|
// Load the file content into mem-fs for use in the temporary extracted project directory
|
|
36
38
|
fs.write((0, path_1.join)(extractedProjectPath, zipEntry.entryName), fileContent);
|
|
37
39
|
}
|
|
@@ -49,7 +51,11 @@ exports.extractZip = extractZip;
|
|
|
49
51
|
*/
|
|
50
52
|
async function downloadApp(repoName) {
|
|
51
53
|
const serviceProvider = prompt_state_1.PromptState.systemSelection?.connectedSystem?.serviceProvider;
|
|
52
|
-
const
|
|
54
|
+
const ui5AbapRepository = await serviceProvider.getUi5AbapRepository();
|
|
55
|
+
ui5AbapRepository.log = logger_1.default.logger;
|
|
56
|
+
logger_1.default.logger?.debug(`App download started: ${repoName}`);
|
|
57
|
+
const downloadedAppPackage = await ui5AbapRepository.downloadFiles(repoName);
|
|
58
|
+
logger_1.default.logger?.debug(`App download completed: ${repoName}`);
|
|
53
59
|
// store downloaded package in prompt state
|
|
54
60
|
prompt_state_1.PromptState.admZip = downloadedAppPackage;
|
|
55
61
|
}
|
|
@@ -75,7 +75,21 @@ async function replaceWebappFiles(projectPath, extractedPath, fs) {
|
|
|
75
75
|
const extractedFilePath = (0, path_1.join)(extractedPath, extractedFile);
|
|
76
76
|
// Check if the extracted file exists before replacing
|
|
77
77
|
if (fs.exists(extractedFilePath)) {
|
|
78
|
-
|
|
78
|
+
if (extractedFile === project_access_1.FileName.Manifest) {
|
|
79
|
+
// Use datasource and model from the generated manifest
|
|
80
|
+
const extractedManifestJSON = fs.readJSON(extractedFilePath);
|
|
81
|
+
const generatedManifestJSON = fs.readJSON(webappFilePath);
|
|
82
|
+
if (generatedManifestJSON?.['sap.app']?.dataSources && extractedManifestJSON?.['sap.app']) {
|
|
83
|
+
extractedManifestJSON['sap.app'].dataSources = generatedManifestJSON['sap.app'].dataSources;
|
|
84
|
+
}
|
|
85
|
+
if (generatedManifestJSON?.['sap.ui5']?.models && extractedManifestJSON?.['sap.ui5']) {
|
|
86
|
+
extractedManifestJSON['sap.ui5'].models = generatedManifestJSON['sap.ui5']?.models;
|
|
87
|
+
}
|
|
88
|
+
fs.writeJSON(webappFilePath, extractedManifestJSON, undefined, 2);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
fs.copy(extractedFilePath, webappFilePath);
|
|
92
|
+
}
|
|
79
93
|
}
|
|
80
94
|
else {
|
|
81
95
|
logger_1.default.logger?.warn((0, i18n_1.t)('warn.extractedFileNotFound', { extractedFilePath }));
|
|
@@ -133,6 +133,7 @@ async function validateAppSelection(answers, appList, quickDeployedAppConfig, ap
|
|
|
133
133
|
return isQfaJsonPresent;
|
|
134
134
|
}
|
|
135
135
|
catch (error) {
|
|
136
|
+
logger_1.default.logger?.debug(`validateAppSelection: Error downloading app: ${error.message}`);
|
|
136
137
|
return (0, i18n_1.t)('error.appDownloadErrors.appDownloadFailure', { error: error.message });
|
|
137
138
|
}
|
|
138
139
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sap-ux/repo-app-import-sub-generator",
|
|
3
3
|
"description": "Generator to download LROP Fiori applications deployed from an ABAP repository.",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.17",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "https://github.com/SAP/open-ux-tools.git",
|
|
@@ -25,20 +25,21 @@
|
|
|
25
25
|
"inquirer": "8.2.6",
|
|
26
26
|
"yeoman-generator": "5.10.0",
|
|
27
27
|
"@sap-ux/feature-toggle": "0.3.0",
|
|
28
|
-
"@sap-ux/project-access": "1.30.2",
|
|
29
|
-
"@sap-ux/inquirer-common": "0.7.5",
|
|
30
28
|
"@sap-ux/fiori-generator-shared": "0.12.4",
|
|
31
|
-
"@sap-ux/
|
|
32
|
-
"@sap-ux/
|
|
29
|
+
"@sap-ux/inquirer-common": "0.7.5",
|
|
30
|
+
"@sap-ux/project-access": "1.30.2",
|
|
31
|
+
"@sap-ux/odata-service-inquirer": "2.4.11",
|
|
33
32
|
"@sap-ux/fiori-elements-writer": "2.4.10",
|
|
33
|
+
"@sap-ux/logger": "0.7.0",
|
|
34
34
|
"@sap-ux/project-input-validator": "0.6.2",
|
|
35
35
|
"@sap-ux/launch-config": "0.10.2",
|
|
36
36
|
"@sap-ux/fiori-tools-settings": "0.2.0",
|
|
37
|
-
"@sap-ux/abap-deploy-config-writer": "0.1.
|
|
37
|
+
"@sap-ux/abap-deploy-config-writer": "0.1.4",
|
|
38
38
|
"@sap-ux/btp-utils": "1.1.0",
|
|
39
39
|
"@sap-ux/ui5-info": "0.11.0",
|
|
40
|
-
"@sap-ux/axios-extension": "1.21.
|
|
40
|
+
"@sap-ux/axios-extension": "1.21.2",
|
|
41
41
|
"@sap-ux/store": "1.1.0",
|
|
42
|
+
"@sap-ux/system-access": "0.6.2",
|
|
42
43
|
"@sap-ux/guided-answers-helper": "0.3.0"
|
|
43
44
|
},
|
|
44
45
|
"devDependencies": {
|