@sap-ux/repo-app-import-sub-generator 0.0.0
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/README.md +16 -0
- package/generators/app/app-config.d.ts +25 -0
- package/generators/app/app-config.js +122 -0
- package/generators/app/index.d.ts +72 -0
- package/generators/app/index.js +291 -0
- package/generators/app/types.d.ts +136 -0
- package/generators/app/types.js +13 -0
- package/generators/prompts/prompt-helpers.d.ts +40 -0
- package/generators/prompts/prompt-helpers.js +108 -0
- package/generators/prompts/prompt-state.d.ts +48 -0
- package/generators/prompts/prompt-state.js +65 -0
- package/generators/prompts/prompts.d.ts +10 -0
- package/generators/prompts/prompts.js +111 -0
- package/generators/telemetryEvents/index.d.ts +7 -0
- package/generators/telemetryEvents/index.js +11 -0
- package/generators/translations/repo-app-import-sub-generator.i18n.json +67 -0
- package/generators/utils/constants.d.ts +14 -0
- package/generators/utils/constants.js +44 -0
- package/generators/utils/download-utils.d.ts +17 -0
- package/generators/utils/download-utils.js +48 -0
- package/generators/utils/event-hook.d.ts +18 -0
- package/generators/utils/event-hook.js +34 -0
- package/generators/utils/file-helpers.d.ts +19 -0
- package/generators/utils/file-helpers.js +52 -0
- package/generators/utils/i18n.d.ts +14 -0
- package/generators/utils/i18n.js +34 -0
- package/generators/utils/logger.d.ts +33 -0
- package/generators/utils/logger.js +41 -0
- package/generators/utils/updates.d.ts +23 -0
- package/generators/utils/updates.js +90 -0
- package/generators/utils/validators.d.ts +17 -0
- package/generators/utils/validators.js +94 -0
- package/package.json +84 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Editor } from 'mem-fs-editor';
|
|
2
|
+
/**
|
|
3
|
+
* Validates and updates the UI5 version in the manifest.
|
|
4
|
+
*
|
|
5
|
+
* - If the minUI5Version in the manifest is not found in the list of released UI5 versions,
|
|
6
|
+
* it updates the manifest with the closest released version.
|
|
7
|
+
* - If internal features are enabled, it sets the minUI5Version to '${sap.ui5.dist.version}'.
|
|
8
|
+
*
|
|
9
|
+
* @param {string} manifestFilePath - The manifest file path.
|
|
10
|
+
* @param {Editor} fs - The file system editor instance.
|
|
11
|
+
* @returns {Promise<Manifest>} - The updated manifest object.
|
|
12
|
+
* @throws {Error} - Throws an error if the manifest structure is invalid or no fallback version is available.
|
|
13
|
+
*/
|
|
14
|
+
export declare function validateAndUpdateManifestUI5Version(manifestFilePath: string, fs: Editor): Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* Replaces the specified files in the `webapp` directory with the corresponding files from the `extractedPath`.
|
|
17
|
+
*
|
|
18
|
+
* @param {string} projectPath - The path to the downloaded App.
|
|
19
|
+
* @param {string} extractedPath - The path from which files will be copied.
|
|
20
|
+
* @param {Editor} fs - The file system editor instance to modify files in memory.
|
|
21
|
+
*/
|
|
22
|
+
export declare function replaceWebappFiles(projectPath: string, extractedPath: string, fs: Editor): Promise<void>;
|
|
23
|
+
//# sourceMappingURL=updates.d.ts.map
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.replaceWebappFiles = exports.validateAndUpdateManifestUI5Version = void 0;
|
|
7
|
+
const path_1 = require("path");
|
|
8
|
+
const project_access_1 = require("@sap-ux/project-access");
|
|
9
|
+
const i18n_1 = require("./i18n");
|
|
10
|
+
const logger_1 = __importDefault(require("./logger"));
|
|
11
|
+
const feature_toggle_1 = require("@sap-ux/feature-toggle");
|
|
12
|
+
const ui5_info_1 = require("@sap-ux/ui5-info");
|
|
13
|
+
const file_helpers_1 = require("./file-helpers");
|
|
14
|
+
const constants_1 = require("./constants");
|
|
15
|
+
/**
|
|
16
|
+
* Validates and updates the UI5 version in the manifest.
|
|
17
|
+
*
|
|
18
|
+
* - If the minUI5Version in the manifest is not found in the list of released UI5 versions,
|
|
19
|
+
* it updates the manifest with the closest released version.
|
|
20
|
+
* - If internal features are enabled, it sets the minUI5Version to '${sap.ui5.dist.version}'.
|
|
21
|
+
*
|
|
22
|
+
* @param {string} manifestFilePath - The manifest file path.
|
|
23
|
+
* @param {Editor} fs - The file system editor instance.
|
|
24
|
+
* @returns {Promise<Manifest>} - The updated manifest object.
|
|
25
|
+
* @throws {Error} - Throws an error if the manifest structure is invalid or no fallback version is available.
|
|
26
|
+
*/
|
|
27
|
+
async function validateAndUpdateManifestUI5Version(manifestFilePath, fs) {
|
|
28
|
+
const manifestJson = (0, file_helpers_1.readManifest)(manifestFilePath, fs);
|
|
29
|
+
if (!manifestJson?.['sap.ui5']?.dependencies || !manifestJson?.['sap.app']?.sourceTemplate) {
|
|
30
|
+
// Check if the manifest structure is valid) {
|
|
31
|
+
throw new Error((0, i18n_1.t)('error.readManifestErrors.invalidManifestStructureError'));
|
|
32
|
+
}
|
|
33
|
+
const manifestUi5Version = manifestJson['sap.ui5']?.dependencies?.minUI5Version;
|
|
34
|
+
const availableUI5Versions = await (0, ui5_info_1.getUI5Versions)({ includeMaintained: true });
|
|
35
|
+
// Check if the manifest version exists in the list of released versions
|
|
36
|
+
const ui5VersionAvailable = availableUI5Versions.find((ui5Version) => ui5Version.version === manifestUi5Version);
|
|
37
|
+
if (ui5VersionAvailable) {
|
|
38
|
+
// Return the manifest as it is if the version is valid
|
|
39
|
+
// No changes needed
|
|
40
|
+
}
|
|
41
|
+
else if ((0, feature_toggle_1.isInternalFeaturesSettingEnabled)()) {
|
|
42
|
+
// Handle internal features setting
|
|
43
|
+
manifestJson['sap.ui5'].dependencies.minUI5Version = '${sap.ui5.dist.version}';
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
// Handle fallback to the closest released version
|
|
47
|
+
const closestAvailableUi5Version = availableUI5Versions[0]?.version;
|
|
48
|
+
manifestJson['sap.ui5'].dependencies.minUI5Version = closestAvailableUi5Version;
|
|
49
|
+
}
|
|
50
|
+
manifestJson['sap.app'].sourceTemplate.id = constants_1.fioriAppSourcetemplateId;
|
|
51
|
+
// update manifest at extracted path
|
|
52
|
+
fs.writeJSON(manifestFilePath, manifestJson, undefined, 2);
|
|
53
|
+
}
|
|
54
|
+
exports.validateAndUpdateManifestUI5Version = validateAndUpdateManifestUI5Version;
|
|
55
|
+
/**
|
|
56
|
+
* Replaces the specified files in the `webapp` directory with the corresponding files from the `extractedPath`.
|
|
57
|
+
*
|
|
58
|
+
* @param {string} projectPath - The path to the downloaded App.
|
|
59
|
+
* @param {string} extractedPath - The path from which files will be copied.
|
|
60
|
+
* @param {Editor} fs - The file system editor instance to modify files in memory.
|
|
61
|
+
*/
|
|
62
|
+
async function replaceWebappFiles(projectPath, extractedPath, fs) {
|
|
63
|
+
try {
|
|
64
|
+
const webappPath = (0, path_1.join)(projectPath, project_access_1.DirName.Webapp);
|
|
65
|
+
// Define the paths of the files to be replaced
|
|
66
|
+
const filesToReplace = [
|
|
67
|
+
{ webappFile: project_access_1.FileName.Manifest, extractedFile: project_access_1.FileName.Manifest },
|
|
68
|
+
{ webappFile: (0, path_1.join)('i18n', 'i18n.properties'), extractedFile: (0, path_1.join)('i18n', 'i18n.properties') },
|
|
69
|
+
{ webappFile: 'index.html', extractedFile: 'index.html' },
|
|
70
|
+
{ webappFile: 'Component.js', extractedFile: 'component.js' }
|
|
71
|
+
];
|
|
72
|
+
// Loop through each file and perform the replacement
|
|
73
|
+
for (const { webappFile, extractedFile } of filesToReplace) {
|
|
74
|
+
const webappFilePath = (0, path_1.join)(webappPath, webappFile);
|
|
75
|
+
const extractedFilePath = (0, path_1.join)(extractedPath, extractedFile);
|
|
76
|
+
// Check if the extracted file exists before replacing
|
|
77
|
+
if (fs.exists(extractedFilePath)) {
|
|
78
|
+
fs.copy(extractedFilePath, webappFilePath);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
logger_1.default.logger?.warn((0, i18n_1.t)('warn.extractedFileNotFound', { extractedFilePath }));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
logger_1.default.logger?.error((0, i18n_1.t)('error.replaceWebappFilesError', { error }));
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
exports.replaceWebappFiles = replaceWebappFiles;
|
|
90
|
+
//# sourceMappingURL=updates.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { QfaJsonConfig } from '../app/types';
|
|
2
|
+
/**
|
|
3
|
+
* Validates the entire app configuration.
|
|
4
|
+
*
|
|
5
|
+
* @param {QfaJsonConfig} config - The QFA JSON configuration containing app details.
|
|
6
|
+
* @returns {boolean} - Returns true if the configuration is valid, false otherwise.
|
|
7
|
+
*/
|
|
8
|
+
export declare const validateQfaJsonFile: (config: QfaJsonConfig) => boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Validates the prompt state for the app download process.
|
|
11
|
+
*
|
|
12
|
+
* @param {string} targetFolder - The target folder for the app download.
|
|
13
|
+
* @param {string} [appId] - The selected app id.
|
|
14
|
+
* @returns {boolean} - Returns true if the prompt state is valid, false otherwise.
|
|
15
|
+
*/
|
|
16
|
+
export declare const isValidPromptState: (targetFolder: string, appId?: string) => boolean;
|
|
17
|
+
//# sourceMappingURL=validators.d.ts.map
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.isValidPromptState = exports.validateQfaJsonFile = void 0;
|
|
7
|
+
const i18n_1 = require("../utils/i18n");
|
|
8
|
+
const logger_1 = __importDefault(require("../utils/logger"));
|
|
9
|
+
const prompt_state_1 = require("../prompts/prompt-state");
|
|
10
|
+
/**
|
|
11
|
+
* Validates the metadata section of the app configuration.
|
|
12
|
+
*
|
|
13
|
+
* @param {QfaJsonConfig['metadata']} metadata - The metadata object.
|
|
14
|
+
* @returns {boolean} - Returns true if valid, false otherwise.
|
|
15
|
+
*/
|
|
16
|
+
const validateMetadata = (metadata) => {
|
|
17
|
+
if (!metadata.package || typeof metadata.package !== 'string') {
|
|
18
|
+
logger_1.default.logger?.error((0, i18n_1.t)('error.invalidMetadataPackage'));
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
return true;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Validates the service binding details section of the app configuration.
|
|
25
|
+
*
|
|
26
|
+
* @param {QfaJsonConfig['serviceBindingDetails']} serviceBinding - The service binding details object.
|
|
27
|
+
* @returns {boolean} - Returns true if valid, false otherwise.
|
|
28
|
+
*/
|
|
29
|
+
const validateServiceBindingDetails = (serviceBinding) => {
|
|
30
|
+
if (!serviceBinding.serviceName || typeof serviceBinding.serviceName !== 'string') {
|
|
31
|
+
logger_1.default.logger?.error((0, i18n_1.t)('error.invalidServiceName'));
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
if (!serviceBinding.serviceVersion || typeof serviceBinding.serviceVersion !== 'string') {
|
|
35
|
+
logger_1.default.logger?.error((0, i18n_1.t)('error.invalidServiceVersion'));
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
if (!serviceBinding.mainEntityName || typeof serviceBinding.mainEntityName !== 'string') {
|
|
39
|
+
logger_1.default.logger?.error((0, i18n_1.t)('error.invalidMainEntityName'));
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
return true;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Validates the project attribute section of the app configuration.
|
|
46
|
+
*
|
|
47
|
+
* @param {QfaJsonConfig['projectAttribute']} projectAttribute - The project attribute object.
|
|
48
|
+
* @returns {boolean} - Returns true if valid, false otherwise.
|
|
49
|
+
*/
|
|
50
|
+
const validateProjectAttribute = (projectAttribute) => {
|
|
51
|
+
if (!projectAttribute.moduleName || typeof projectAttribute.moduleName !== 'string') {
|
|
52
|
+
logger_1.default.logger?.error((0, i18n_1.t)('error.invalidModuleName'));
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
return true;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Validates the deployment details section of the app configuration.
|
|
59
|
+
*
|
|
60
|
+
* @param {QfaJsonConfig['deploymentDetails']} deploymentDetails - The deployment details object.
|
|
61
|
+
* @returns {boolean} - Returns true if valid, false otherwise.
|
|
62
|
+
*/
|
|
63
|
+
const validateDeploymentDetails = (deploymentDetails) => {
|
|
64
|
+
if (!deploymentDetails.repositoryName) {
|
|
65
|
+
logger_1.default.logger?.error((0, i18n_1.t)('error.invalidRepositoryName'));
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
return true;
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Validates the entire app configuration.
|
|
72
|
+
*
|
|
73
|
+
* @param {QfaJsonConfig} config - The QFA JSON configuration containing app details.
|
|
74
|
+
* @returns {boolean} - Returns true if the configuration is valid, false otherwise.
|
|
75
|
+
*/
|
|
76
|
+
const validateQfaJsonFile = (config) => {
|
|
77
|
+
return (validateMetadata(config.metadata) &&
|
|
78
|
+
validateServiceBindingDetails(config.serviceBindingDetails) &&
|
|
79
|
+
validateProjectAttribute(config.projectAttribute) &&
|
|
80
|
+
validateDeploymentDetails(config.deploymentDetails));
|
|
81
|
+
};
|
|
82
|
+
exports.validateQfaJsonFile = validateQfaJsonFile;
|
|
83
|
+
/**
|
|
84
|
+
* Validates the prompt state for the app download process.
|
|
85
|
+
*
|
|
86
|
+
* @param {string} targetFolder - The target folder for the app download.
|
|
87
|
+
* @param {string} [appId] - The selected app id.
|
|
88
|
+
* @returns {boolean} - Returns true if the prompt state is valid, false otherwise.
|
|
89
|
+
*/
|
|
90
|
+
const isValidPromptState = (targetFolder, appId) => {
|
|
91
|
+
return !!(prompt_state_1.PromptState.systemSelection.connectedSystem?.serviceProvider && appId && targetFolder);
|
|
92
|
+
};
|
|
93
|
+
exports.isValidPromptState = isValidPromptState;
|
|
94
|
+
//# sourceMappingURL=validators.js.map
|
package/package.json
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sap-ux/repo-app-import-sub-generator",
|
|
3
|
+
"description": "Generator to download LROP Fiori applications deployed from an ABAP repository.",
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/SAP/open-ux-tools.git",
|
|
8
|
+
"directory": "packages/repo-app-import-sub-generator"
|
|
9
|
+
},
|
|
10
|
+
"bugs": {
|
|
11
|
+
"url": "https://github.com/SAP/open-ux-tools/issues?q=is%3Aopen+is%3Aissue"
|
|
12
|
+
},
|
|
13
|
+
"license": "Apache-2.0",
|
|
14
|
+
"main": "generators/app/index.js",
|
|
15
|
+
"files": [
|
|
16
|
+
"LICENSE",
|
|
17
|
+
"generators",
|
|
18
|
+
"!generators/*.map",
|
|
19
|
+
"!generators/**/*.map"
|
|
20
|
+
],
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@sap-devx/yeoman-ui-types": "1.14.4",
|
|
23
|
+
"adm-zip": "0.5.10",
|
|
24
|
+
"i18next": "23.5.1",
|
|
25
|
+
"inquirer": "8.2.6",
|
|
26
|
+
"yeoman-generator": "5.10.0",
|
|
27
|
+
"@sap-ux/feature-toggle": "0.2.3",
|
|
28
|
+
"@sap-ux/fiori-generator-shared": "0.10.2",
|
|
29
|
+
"@sap-ux/inquirer-common": "0.6.35",
|
|
30
|
+
"@sap-ux/project-access": "1.29.18",
|
|
31
|
+
"@sap-ux/odata-service-inquirer": "2.2.33",
|
|
32
|
+
"@sap-ux/fiori-elements-writer": "2.1.38",
|
|
33
|
+
"@sap-ux/logger": "0.6.0",
|
|
34
|
+
"@sap-ux/project-input-validator": "0.5.0",
|
|
35
|
+
"@sap-ux/launch-config": "0.8.1",
|
|
36
|
+
"@sap-ux/abap-deploy-config-writer": "0.0.103",
|
|
37
|
+
"@sap-ux/btp-utils": "1.0.3",
|
|
38
|
+
"@sap-ux/ui5-info": "0.9.1",
|
|
39
|
+
"@sap-ux/fiori-tools-settings": "0.1.0",
|
|
40
|
+
"@sap-ux/axios-extension": "1.20.0",
|
|
41
|
+
"@sap-ux/store": "1.0.0"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@jest/types": "29.6.3",
|
|
45
|
+
"@types/inquirer": "8.2.6",
|
|
46
|
+
"@types/mem-fs": "1.1.2",
|
|
47
|
+
"@types/mem-fs-editor": "7.0.1",
|
|
48
|
+
"@types/yeoman-generator": "5.2.11",
|
|
49
|
+
"@types/yeoman-environment": "2.10.11",
|
|
50
|
+
"inquirer-autocomplete-prompt": "2.0.1",
|
|
51
|
+
"@types/inquirer-autocomplete-prompt": "2.0.1",
|
|
52
|
+
"@types/yeoman-test": "4.0.6",
|
|
53
|
+
"@types/fs-extra": "9.0.13",
|
|
54
|
+
"fs-extra": "10.0.0",
|
|
55
|
+
"@vscode-logging/logger": "2.0.0",
|
|
56
|
+
"@types/adm-zip": "0.5.5",
|
|
57
|
+
"memfs": "3.4.13",
|
|
58
|
+
"mem-fs-editor": "9.4.0",
|
|
59
|
+
"lodash": "4.17.21",
|
|
60
|
+
"@types/lodash": "4.14.202",
|
|
61
|
+
"rimraf": "5.0.5",
|
|
62
|
+
"typescript": "5.3.3",
|
|
63
|
+
"unionfs": "4.4.0",
|
|
64
|
+
"yeoman-test": "6.3.0",
|
|
65
|
+
"yo": "4",
|
|
66
|
+
"@sap-ux/nodejs-utils": "0.1.9",
|
|
67
|
+
"@sap-ux/store": "1.0.0",
|
|
68
|
+
"@sap-ux/ui5-config": "0.26.5"
|
|
69
|
+
},
|
|
70
|
+
"engines": {
|
|
71
|
+
"node": ">=18.x"
|
|
72
|
+
},
|
|
73
|
+
"scripts": {
|
|
74
|
+
"build": "tsc --build",
|
|
75
|
+
"clean": "rimraf --glob generators test/test-output coverage *.tsbuildinfo",
|
|
76
|
+
"watch": "tsc --watch",
|
|
77
|
+
"lint": "eslint . --ext .ts",
|
|
78
|
+
"lint:fix": "eslint . --ext .ts --fix",
|
|
79
|
+
"test": "jest --ci --forceExit --detectOpenHandles --colors --passWithNoTests",
|
|
80
|
+
"test-u": "jest --ci --forceExit --detectOpenHandles --colors -u",
|
|
81
|
+
"link": "pnpm link --global",
|
|
82
|
+
"unlink": "pnpm unlink --global"
|
|
83
|
+
}
|
|
84
|
+
}
|