@sap-ux/repo-app-import-sub-generator 1.0.20 → 1.1.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.
@@ -0,0 +1,42 @@
1
+ import { OdataVersion } from '@sap-ux/odata-service-inquirer';
2
+ import type { Editor } from 'mem-fs-editor';
3
+ import type { AppInfo, AbapRepositoryContext } from '../app/types.js';
4
+ import type { AbapDeployConfig } from '@sap-ux/ui5-config';
5
+ /**
6
+ * App configuration derived from the downloaded manifest for the ABAP repository flow.
7
+ * Used only for README generation, launch config creation, and adding a minimal package.json.
8
+ */
9
+ export interface AbapRepoAppConfig {
10
+ app: {
11
+ id: string;
12
+ title: string;
13
+ flpAppId: string;
14
+ };
15
+ service: {
16
+ url: string | undefined;
17
+ version: OdataVersion;
18
+ };
19
+ ui5: {
20
+ version: string;
21
+ };
22
+ }
23
+ /**
24
+ * Builds the app configuration for the ABAP repository download flow by reading
25
+ * the downloaded manifest. Returns a typed config object used for README generation, launch config, and deploy config.
26
+ *
27
+ * @param {string} webappPath - Path to the webapp folder.
28
+ * @param {AppInfo} appInfo - The selected app info from prompts.
29
+ * @param {Editor} fs - The file system editor.
30
+ * @returns {AbapRepoAppConfig} Derived app configuration.
31
+ */
32
+ export declare function getAbapRepoAppConfig(webappPath: string, appInfo: AppInfo, fs: Editor): AbapRepoAppConfig;
33
+ /**
34
+ * Generates the deployment configuration for an ABAP repository application.
35
+ * Fetches package and description from the UI5 ABAP Repository service.
36
+ *
37
+ * @param {AppInfo} app - The application information collected from user prompts.
38
+ * @param {AppDownloadContext} context - The download context.
39
+ * @returns {Promise<AbapDeployConfig>} The deployment configuration.
40
+ */
41
+ export declare function getAbapRepoDeployConfig(app: AppInfo, context: AbapRepositoryContext): Promise<AbapDeployConfig>;
42
+ //# sourceMappingURL=app-config-abap-repo.d.ts.map
@@ -0,0 +1,87 @@
1
+ import { OdataVersion } from '@sap-ux/odata-service-inquirer';
2
+ import { PromptState } from '../prompts/prompt-state.js';
3
+ import RepoAppDownloadLogger from '../utils/logger.js';
4
+ import { t } from '../utils/i18n.js';
5
+ import { getFlpId } from '@sap-ux/fiori-generator-shared';
6
+ import { FileName, getMainService } from '@sap-ux/project-access';
7
+ import { resolveTransportRequest } from '../utils/download-utils.js';
8
+ import { AuthenticationType } from '@sap-ux/store';
9
+ import { readManifest } from '../utils/file-helpers.js';
10
+ import { join } from 'node:path';
11
+ /**
12
+ * Builds the app configuration for the ABAP repository download flow by reading
13
+ * the downloaded manifest. Returns a typed config object used for README generation, launch config, and deploy config.
14
+ *
15
+ * @param {string} webappPath - Path to the webapp folder.
16
+ * @param {AppInfo} appInfo - The selected app info from prompts.
17
+ * @param {Editor} fs - The file system editor.
18
+ * @returns {AbapRepoAppConfig} Derived app configuration.
19
+ */
20
+ export function getAbapRepoAppConfig(webappPath, appInfo, fs) {
21
+ const manifest = readManifest(join(webappPath, FileName.Manifest), fs);
22
+ const appId = manifest?.['sap.app']?.id ?? appInfo.appId;
23
+ const appTitle = manifest?.['sap.app']?.title ?? appInfo.title ?? '';
24
+ const minUI5Version = manifest?.['sap.ui5']?.dependencies?.minUI5Version ?? '';
25
+ const ui5Version = Array.isArray(minUI5Version) ? (minUI5Version[0] ?? '') : minUI5Version;
26
+ const mainServiceName = getMainService(manifest);
27
+ const odataVersionStr = mainServiceName
28
+ ? manifest?.['sap.app']?.dataSources?.[mainServiceName]?.settings?.odataVersion
29
+ : undefined;
30
+ const odataVersion = odataVersionStr === '4.0' ? OdataVersion.v4 : OdataVersion.v2;
31
+ return {
32
+ app: {
33
+ id: appId,
34
+ title: appTitle,
35
+ flpAppId: `${getFlpId(appId)}-tile`
36
+ },
37
+ service: {
38
+ url: PromptState.baseURL,
39
+ version: odataVersion
40
+ },
41
+ ui5: {
42
+ version: ui5Version
43
+ }
44
+ };
45
+ }
46
+ /**
47
+ * Generates the deployment configuration for an ABAP repository application.
48
+ * Fetches package and description from the UI5 ABAP Repository service.
49
+ *
50
+ * @param {AppInfo} app - The application information collected from user prompts.
51
+ * @param {AppDownloadContext} context - The download context.
52
+ * @returns {Promise<AbapDeployConfig>} The deployment configuration.
53
+ */
54
+ export async function getAbapRepoDeployConfig(app, context) {
55
+ const { serviceProvider } = context;
56
+ let packageName = '';
57
+ let description = '';
58
+ try {
59
+ // get package and description from repository
60
+ const repoInfo = await serviceProvider
61
+ ?.getUi5AbapRepository()
62
+ .getInfo(app?.repoName ?? '');
63
+ packageName = repoInfo?.Package ?? '';
64
+ description = repoInfo?.Description ?? '';
65
+ }
66
+ catch (error) {
67
+ RepoAppDownloadLogger.logger?.warn(t('warn.repoInfoFetchFailed', { repoName: app?.repoName, error: error?.message }));
68
+ }
69
+ const transport = await resolveTransportRequest(serviceProvider, packageName, app?.repoName ?? '');
70
+ return {
71
+ target: {
72
+ url: PromptState.baseURL,
73
+ client: PromptState.sapClient,
74
+ destination: PromptState.destinationName,
75
+ ...(PromptState.authenticationType === AuthenticationType.ReentranceTicket && {
76
+ authenticationType: PromptState.authenticationType
77
+ })
78
+ },
79
+ app: {
80
+ name: app?.repoName,
81
+ package: packageName,
82
+ description: description || app?.description,
83
+ transport
84
+ }
85
+ }; // NOSONAR
86
+ }
87
+ //# sourceMappingURL=app-config-abap-repo.js.map
@@ -1,23 +1,8 @@
1
1
  import { type FioriElementsApp, type LROPSettings } from '@sap-ux/fiori-elements-writer';
2
- import type { AbapServiceProvider } from '@sap-ux/axios-extension';
3
2
  import type { Editor } from 'mem-fs-editor';
4
- import type { AppInfo, QfaJsonConfig } from '../app/types.js';
3
+ import type { AppInfo, AdtQuickDeployContext } from '../app/types.js';
5
4
  import type { AbapDeployConfig } from '@sap-ux/ui5-config';
6
5
  import { type OdataServiceAnswers } from '@sap-ux/odata-service-inquirer';
7
- /**
8
- * Shared context for downloading and deploying ABAP applications.
9
- */
10
- export interface AppDownloadContext {
11
- serviceProvider?: AbapServiceProvider;
12
- qfaJson: QfaJsonConfig;
13
- }
14
- /**
15
- * Generates the deployment configuration for an ABAP application.
16
- *
17
- * @param {AppDownloadContext} context - The download context with service provider and qfa info.
18
- * @returns {AbapDeployConfig} The deployment configuration containing `target` and `app` info.
19
- */
20
- export declare const getAbapDeployConfig: (context: AppDownloadContext) => Promise<AbapDeployConfig>;
21
6
  /**
22
7
  * Gets the application configuration based on the provided user answers and manifest data.
23
8
  * This configuration will be used to initialize a new Fiori application.
@@ -30,5 +15,12 @@ export declare const getAbapDeployConfig: (context: AppDownloadContext) => Promi
30
15
  * @returns {Promise<FioriElementsApp<LROPSettings>>} - A promise resolving to the generated app configuration.
31
16
  * @throws {Error} - Throws an error if there are issues generating the configuration.
32
17
  */
33
- export declare function getAppConfig(app: AppInfo, extractedProjectPath: string, context: AppDownloadContext, systemSelection: OdataServiceAnswers, fs: Editor): Promise<FioriElementsApp<LROPSettings>>;
34
- //# sourceMappingURL=app-config.d.ts.map
18
+ export declare function getAppConfig(app: AppInfo, extractedProjectPath: string, context: AdtQuickDeployContext, systemSelection: OdataServiceAnswers, fs: Editor): Promise<FioriElementsApp<LROPSettings>>;
19
+ /**
20
+ * Generates the deployment configuration for an ADT Quick Deploy application.
21
+ *
22
+ * @param {AdtQuickDeployContext} context - The download context.
23
+ * @returns {Promise<AbapDeployConfig>} The deployment configuration.
24
+ */
25
+ export declare function getAdtDeployConfig(context: AdtQuickDeployContext): Promise<AbapDeployConfig>;
26
+ //# sourceMappingURL=app-config-quick-deploy.d.ts.map
@@ -1,78 +1,20 @@
1
1
  import { TemplateType } from '@sap-ux/fiori-elements-writer';
2
2
  import { OdataVersion } from '@sap-ux/odata-service-inquirer';
3
- import { TransportChecksService } from '@sap-ux/axios-extension';
4
3
  import { t } from '../utils/i18n.js';
5
4
  import { readManifest } from '../utils/file-helpers.js';
6
- import { fioriAppSourcetemplateId } from '../utils/constants.js';
5
+ import { fioriAppSourcetemplateId, adtSourceTemplateId } from '../utils/constants.js';
7
6
  import { PromptState } from '../prompts/prompt-state.js';
8
7
  import RepoAppDownloadLogger from '../utils/logger.js';
9
8
  import { FileName } from '@sap-ux/project-access';
10
9
  import { join } from 'node:path';
11
10
  import { getUI5Versions } from '@sap-ux/ui5-info';
12
- /**
13
- * Resolve a transport request for the given app/package context.
14
- * This function performs defensive checks and logs clear, actionable messages.
15
- *
16
- * @param context - AppDownloadContext containing qfaJson and serviceProvider
17
- * @returns { Promise<string> } - Resolved transport request string
18
- * - '' when package is local ('$TMP')
19
- * - '<transport-request-id>' when transport request is found
20
- * - 'REPLACE_WITH_TRANSPORT' when no transport request is found
21
- * @throws Error when the transport check fails
22
- */
23
- async function resolveTransportRequest(context) {
24
- const { serviceProvider, qfaJson } = context;
25
- const packageName = qfaJson.metadata.package;
26
- const appName = qfaJson.deploymentDetails.repositoryName;
27
- if (packageName === '$TMP') {
28
- return '';
29
- }
30
- try {
31
- const transportService = await serviceProvider?.getAdtService(TransportChecksService);
32
- const transportRequests = await transportService?.getTransportRequests(packageName, appName);
33
- if (transportRequests?.length === 1) {
34
- return transportRequests[0].transportNumber;
35
- }
36
- return 'REPLACE_WITH_TRANSPORT';
37
- }
38
- catch (error) {
39
- if (error.message === TransportChecksService.LocalPackageError) {
40
- return '';
41
- }
42
- const msg = t('error.transportCheckFailed', { error: error?.message });
43
- RepoAppDownloadLogger.logger?.error(msg);
44
- throw new Error(msg);
45
- }
46
- }
47
- /**
48
- * Generates the deployment configuration for an ABAP application.
49
- *
50
- * @param {AppDownloadContext} context - The download context with service provider and qfa info.
51
- * @returns {AbapDeployConfig} The deployment configuration containing `target` and `app` info.
52
- */
53
- export const getAbapDeployConfig = async (context) => {
54
- const { qfaJson } = context;
55
- const transportRequest = await resolveTransportRequest(context);
56
- return {
57
- target: {
58
- url: PromptState.baseURL,
59
- client: PromptState.sapClient,
60
- destination: PromptState.destinationName
61
- },
62
- app: {
63
- name: qfaJson.deploymentDetails.repositoryName,
64
- package: qfaJson.metadata.package,
65
- description: qfaJson.deploymentDetails.repositoryDescription,
66
- transport: transportRequest
67
- }
68
- }; // NOSONAR
69
- };
11
+ import { resolveTransportRequest } from '../utils/download-utils.js';
70
12
  /**
71
13
  * Fetches the metadata of a given service from the provided ABAP service provider.
72
14
  *
73
15
  * @param {AbapServiceProvider} provider - The ABAP service provider instance.
74
16
  * @param {string} serviceUrl - The URL of the service to retrieve metadata for.
75
- * @returns {Promise<any>} - A promise resolving to the service metadata.
17
+ * @returns {Promise<string | undefined>} - A promise resolving to the service metadata.
76
18
  */
77
19
  const fetchServiceMetadata = async (provider, serviceUrl) => {
78
20
  try {
@@ -101,15 +43,16 @@ export async function getAppConfig(app, extractedProjectPath, context, systemSel
101
43
  const manifest = readManifest(join(extractedProjectPath, FileName.Manifest), fs);
102
44
  const serviceProvider = PromptState.systemSelection?.connectedSystem?.serviceProvider;
103
45
  context.serviceProvider = serviceProvider;
46
+ if (manifest?.['sap.app']?.sourceTemplate?.id !== adtSourceTemplateId) {
47
+ RepoAppDownloadLogger.logger?.error(t('error.readManifestErrors.sourceTemplateNotSupported'));
48
+ }
104
49
  if (!manifest?.['sap.app']?.dataSources) {
105
50
  RepoAppDownloadLogger.logger?.error(t('error.dataSourcesNotFound'));
106
51
  }
107
52
  const odataVersion = manifest?.['sap.app']?.dataSources?.mainService?.settings?.odataVersion?.startsWith('4')
108
53
  ? OdataVersion.v4
109
54
  : OdataVersion.v2;
110
- // Fetch metadata for the service
111
55
  const metadata = await fetchServiceMetadata(serviceProvider, manifest?.['sap.app']?.dataSources?.mainService.uri ?? '');
112
- // Fetch latest UI5 versions from npm
113
56
  const ui5Versions = await getUI5Versions({ onlyNpmVersion: true });
114
57
  const localVersion = ui5Versions[0]?.version;
115
58
  const appConfig = {
@@ -164,4 +107,28 @@ export async function getAppConfig(app, extractedProjectPath, context, systemSel
164
107
  throw error;
165
108
  }
166
109
  }
167
- //# sourceMappingURL=app-config.js.map
110
+ /**
111
+ * Generates the deployment configuration for an ADT Quick Deploy application.
112
+ *
113
+ * @param {AdtQuickDeployContext} context - The download context.
114
+ * @returns {Promise<AbapDeployConfig>} The deployment configuration.
115
+ */
116
+ export async function getAdtDeployConfig(context) {
117
+ const { qfaJson, serviceProvider } = context;
118
+ const packageName = qfaJson.metadata.package;
119
+ const transport = await resolveTransportRequest(serviceProvider, packageName, qfaJson.deploymentDetails.repositoryName);
120
+ return {
121
+ target: {
122
+ url: PromptState.baseURL,
123
+ client: PromptState.sapClient,
124
+ destination: PromptState.destinationName
125
+ },
126
+ app: {
127
+ name: qfaJson.deploymentDetails.repositoryName,
128
+ package: packageName,
129
+ description: qfaJson.deploymentDetails.repositoryDescription,
130
+ transport
131
+ }
132
+ }; // NOSONAR
133
+ }
134
+ //# sourceMappingURL=app-config-quick-deploy.js.map
@@ -9,12 +9,14 @@ export default class extends Generator {
9
9
  private readonly appWizard;
10
10
  private readonly vscode?;
11
11
  private readonly appRootPath;
12
- private readonly prompts;
13
12
  private readonly answers;
13
+ private readonly downloadType;
14
+ private readonly prompts;
14
15
  options: RepoAppDownloadOptions;
15
16
  private projectPath;
16
17
  private extractedProjectPath;
17
18
  private debugOptions;
19
+ private deployConfig;
18
20
  setPromptsCallback: (fn: object) => void;
19
21
  /**
20
22
  * Constructor for Downloading App.
@@ -35,6 +37,15 @@ export default class extends Generator {
35
37
  * Writes the configuration files for the project, including deployment config, and README.
36
38
  */
37
39
  writing(): Promise<void>;
40
+ /**
41
+ * Writing phase for ABAP Repository downloads.
42
+ */
43
+ private _generateAbapRepositoryApp;
44
+ /**
45
+ * Writing phase for ADT Quick Deploy downloads.
46
+ * Generates a full Fiori project from qfa.json metadata including deploy config.
47
+ */
48
+ private _generateAdtQuickDeployApp;
38
49
  /**
39
50
  * Returns the configuration for the README file.
40
51
  *
@@ -2,11 +2,12 @@ import Generator from 'yeoman-generator';
2
2
  import RepoAppDownloadLogger from '../utils/logger.js';
3
3
  import { AppWizard, Prompts, MessageType } from '@sap-devx/yeoman-ui-types';
4
4
  import { isInternalFeaturesSettingEnabled } from '@sap-ux/feature-toggle';
5
- import { generatorTitle, extractedFilePath, generatorName, defaultAnswers, qfaJsonFileName } from '../utils/constants.js';
5
+ import { extractedFilePath, generatorName, defaultAnswers, qfaJsonFileName, downloadTypeConfig } from '../utils/constants.js';
6
6
  import { t } from '../utils/i18n.js';
7
7
  import { extractZip } from '../utils/download-utils.js';
8
8
  import { EventName } from '../telemetryEvents/index.js';
9
9
  import { getDefaultTargetFolder, generateAppGenInfo, sendTelemetry, TelemetryHelper, isCli, setYeomanEnvConflicterForce } from '@sap-ux/fiori-generator-shared';
10
+ import { AppDownloadType, PromptNames } from './types.js';
10
11
  import { getPrompts } from '../prompts/prompts.js';
11
12
  import { generate, TemplateType } from '@sap-ux/fiori-elements-writer';
12
13
  import { join, basename } from 'node:path';
@@ -19,9 +20,9 @@ import { OdataVersion } from '@sap-ux/odata-service-inquirer';
19
20
  import { writeApplicationInfoSettings } from '@sap-ux/fiori-tools-settings';
20
21
  import { generate as generateDeployConfig } from '@sap-ux/abap-deploy-config-writer';
21
22
  import { PromptState } from '../prompts/prompt-state.js';
22
- import { PromptNames } from './types.js';
23
- import { getAbapDeployConfig, getAppConfig } from './app-config.js';
24
- import { makeValidJson } from '../utils/file-helpers.js';
23
+ import { getAppConfig, getAdtDeployConfig } from './app-config-quick-deploy.js';
24
+ import { getAbapRepoAppConfig, getAbapRepoDeployConfig } from './app-config-abap-repo.js';
25
+ import { makeValidJson, processDebugArtifacts, addPackageJsonIfNotFound } from '../utils/file-helpers.js';
25
26
  import { replaceWebappFiles, validateAndUpdateManifestUI5Version } from '../utils/updates.js';
26
27
  import { getYUIDetails } from '../prompts/prompt-helpers.js';
27
28
  import { isValidPromptState, validateQfaJsonFile } from '../utils/validators.js';
@@ -34,12 +35,14 @@ export default class extends Generator {
34
35
  appWizard;
35
36
  vscode;
36
37
  appRootPath;
37
- prompts;
38
38
  answers = defaultAnswers;
39
+ downloadType;
40
+ prompts;
39
41
  options;
40
42
  projectPath;
41
43
  extractedProjectPath;
42
44
  debugOptions;
45
+ deployConfig;
43
46
  setPromptsCallback;
44
47
  /**
45
48
  * Constructor for Downloading App.
@@ -54,11 +57,10 @@ export default class extends Generator {
54
57
  this.vscode = opts.vscode;
55
58
  this.appRootPath = opts?.appRootPath ?? getDefaultTargetFolder(this.vscode) ?? this.destinationRoot();
56
59
  this.options = opts;
60
+ this.downloadType = opts.data?.appDownloadType ?? AppDownloadType.ADTQuickDeploy;
57
61
  // Configure logging
58
62
  RepoAppDownloadLogger.configureLogging(this.rootGeneratorName(), this.log, this.options.logWrapper, this.options.logLevel, this.options.logger, this.vscode);
59
- // Initialise prompts and callbacks if not launched as a subgenerator
60
- this.appWizard.setHeaderTitle(generatorTitle);
61
- this.prompts = new Prompts(getYUIDetails());
63
+ this.prompts = new Prompts(getYUIDetails(this.downloadType));
62
64
  this.setPromptsCallback = (fn) => {
63
65
  if (this.prompts) {
64
66
  this.prompts.setCallback(fn);
@@ -85,7 +87,7 @@ export default class extends Generator {
85
87
  */
86
88
  async prompting() {
87
89
  const quickDeployedAppConfig = this.options?.data?.quickDeployedAppConfig;
88
- const questions = await getPrompts(this.appRootPath, quickDeployedAppConfig, this.appWizard, isCli());
90
+ const questions = await getPrompts(this.appRootPath, quickDeployedAppConfig, this.appWizard, isCli(), this.downloadType);
89
91
  const answers = await this.prompt(questions);
90
92
  const { targetFolder } = answers;
91
93
  if (quickDeployedAppConfig?.appId) {
@@ -108,6 +110,46 @@ export default class extends Generator {
108
110
  * Writes the configuration files for the project, including deployment config, and README.
109
111
  */
110
112
  async writing() {
113
+ if (this.downloadType === AppDownloadType.AbapRepository) {
114
+ await this._generateAbapRepositoryApp();
115
+ }
116
+ else {
117
+ await this._generateAdtQuickDeployApp();
118
+ }
119
+ }
120
+ /**
121
+ * Writing phase for ABAP Repository downloads.
122
+ */
123
+ async _generateAbapRepositoryApp() {
124
+ const webappPath = join(this.projectPath, DirName.Webapp);
125
+ await extractZip(webappPath, this.fs);
126
+ processDebugArtifacts(webappPath, this.fs);
127
+ const appConfig = getAbapRepoAppConfig(webappPath, this.answers.selectedApp, this.fs);
128
+ // If package.json does not exist in the extracted app, add a minimal one with the appId as the package name.
129
+ addPackageJsonIfNotFound(this.projectPath, appConfig.app.id, this.fs);
130
+ // Generate deploy config
131
+ const serviceProvider = PromptState.systemSelection?.connectedSystem?.serviceProvider;
132
+ const context = {
133
+ serviceProvider,
134
+ appDownloadType: AppDownloadType.AbapRepository
135
+ };
136
+ this.deployConfig = await getAbapRepoDeployConfig(this.answers.selectedApp, context);
137
+ if (this.vscode) {
138
+ // Generate Fiori launch config
139
+ const fioriOptions = this._getLaunchConfig(appConfig);
140
+ // Create launch configuration
141
+ await createLaunchConfig(this.projectPath, fioriOptions, this.fs, RepoAppDownloadLogger.logger);
142
+ writeApplicationInfoSettings(this.projectPath);
143
+ }
144
+ // Generate README
145
+ const readMeConfig = this._getReadMeConfig(appConfig);
146
+ generateAppGenInfo(this.projectPath, readMeConfig, this.fs);
147
+ }
148
+ /**
149
+ * Writing phase for ADT Quick Deploy downloads.
150
+ * Generates a full Fiori project from qfa.json metadata including deploy config.
151
+ */
152
+ async _generateAdtQuickDeployApp() {
111
153
  await extractZip(this.extractedProjectPath, this.fs);
112
154
  // Check if the qfa.json file
113
155
  const qfaJsonFilePath = join(this.extractedProjectPath, qfaJsonFileName);
@@ -115,14 +157,15 @@ export default class extends Generator {
115
157
  // Generate project files
116
158
  validateQfaJsonFile(qfaJson);
117
159
  const context = {
118
- qfaJson
160
+ qfaJson,
161
+ appDownloadType: AppDownloadType.ADTQuickDeploy
119
162
  };
120
163
  // Generate app config
121
164
  const config = await getAppConfig(this.answers.selectedApp, this.extractedProjectPath, context, this.answers.systemSelection, this.fs);
122
165
  await generate(this.projectPath, config, this.fs);
123
166
  // Generate deploy config
124
- const deployConfig = await getAbapDeployConfig(context);
125
- await generateDeployConfig(this.projectPath, deployConfig, undefined, this.fs);
167
+ this.deployConfig = await getAdtDeployConfig(context);
168
+ await generateDeployConfig(this.projectPath, this.deployConfig, undefined, this.fs);
126
169
  if (this.vscode) {
127
170
  // Generate Fiori launch config
128
171
  const fioriOptions = this._getLaunchConfig(config);
@@ -150,7 +193,7 @@ export default class extends Generator {
150
193
  appName: config.app.id,
151
194
  appTitle: config.app.title ?? '',
152
195
  appNamespace: config.app.id.substring(0, config.app.id.lastIndexOf('.')),
153
- appDescription: t('readMe.appDescription'),
196
+ appDescription: downloadTypeConfig[this.downloadType].readMeAppDescription,
154
197
  ui5Theme: getDefaultUI5Theme(config.ui5?.version),
155
198
  generatorName: generatorName,
156
199
  generatorVersion: this.rootGeneratorVersion(),
@@ -260,7 +303,8 @@ export default class extends Generator {
260
303
  await runPostAppGenHook({
261
304
  path: this.projectPath,
262
305
  vscodeInstance: this.vscode,
263
- postGenCommand: this.options.data?.postGenCommand
306
+ postGenCommand: this.options.data?.postGenCommand,
307
+ deployConfig: this.deployConfig
264
308
  });
265
309
  }
266
310
  }
@@ -269,7 +313,7 @@ export default class extends Generator {
269
313
  */
270
314
  async end() {
271
315
  try {
272
- this.appWizard.showInformation(t('info.repoAppDownloadCompleteMsg'), MessageType.notification);
316
+ this.appWizard.showInformation(downloadTypeConfig[this.downloadType].generatorSuccessMsg, MessageType.notification);
273
317
  await this._handlePostAppGeneration();
274
318
  await sendTelemetry(EventName.GENERATION_SUCCESS, TelemetryHelper.createTelemetryData({
275
319
  appType: 'repo-app-import-sub-generator',
@@ -1,10 +1,39 @@
1
1
  import type Generator from 'yeoman-generator';
2
2
  import type { AppWizard } from '@sap-devx/yeoman-ui-types';
3
3
  import type { VSCodeInstance, TelemetryData, LogWrapper } from '@sap-ux/fiori-generator-shared';
4
- import type { AppIndex } from '@sap-ux/axios-extension';
4
+ import type { AppIndex, AbapServiceProvider } from '@sap-ux/axios-extension';
5
5
  import type { OdataServiceAnswers } from '@sap-ux/odata-service-inquirer';
6
6
  import type { YUIQuestion } from '@sap-ux/inquirer-common';
7
7
  import type { AutocompleteQuestionOptions } from 'inquirer-autocomplete-prompt';
8
+ /**
9
+ * Identifies which download flow is active.
10
+ * ADTQuickDeploy: app was quick-deployed via ADT; uses qfa.json for config.
11
+ * AbapRepository: app lives in ABAP UI5 repository; config is read from manifest.
12
+ */
13
+ export declare const AppDownloadType: {
14
+ ADTQuickDeploy: string;
15
+ AbapRepository: string;
16
+ };
17
+ export type AppDownloadType = (typeof AppDownloadType)[keyof typeof AppDownloadType];
18
+ /**
19
+ * Context for the ADT Quick Deploy download flow.
20
+ */
21
+ export interface AdtQuickDeployContext {
22
+ appDownloadType: typeof AppDownloadType.ADTQuickDeploy;
23
+ qfaJson: QfaJsonConfig;
24
+ serviceProvider?: AbapServiceProvider;
25
+ }
26
+ /**
27
+ * Context for the ABAP Repository download flow.
28
+ */
29
+ export interface AbapRepositoryContext {
30
+ appDownloadType: typeof AppDownloadType.AbapRepository;
31
+ serviceProvider?: AbapServiceProvider;
32
+ }
33
+ /**
34
+ * Union of download contexts.
35
+ */
36
+ export type AppDownloadContext = AdtQuickDeployContext | AbapRepositoryContext;
8
37
  /**
9
38
  * Quick deploy app config are applicable only in scenarios where an application
10
39
  * deployed via ADT Quick Deploy is being downloaded from a repository.
@@ -44,6 +73,8 @@ export interface RepoAppDownloadOptions extends Generator.GeneratorOptions {
44
73
  telemetryData?: TelemetryData;
45
74
  /** Logger instance for logging operations. */
46
75
  logWrapper?: LogWrapper;
76
+ /** The type of app download. */
77
+ appDownloadType?: AppDownloadType;
47
78
  }
48
79
  /**
49
80
  * Represents a question in the app download process.
@@ -1,3 +1,12 @@
1
+ /**
2
+ * Identifies which download flow is active.
3
+ * ADTQuickDeploy: app was quick-deployed via ADT; uses qfa.json for config.
4
+ * AbapRepository: app lives in ABAP UI5 repository; config is read from manifest.
5
+ */
6
+ export const AppDownloadType = {
7
+ ADTQuickDeploy: 'adtQuickDeploy',
8
+ AbapRepository: 'abapRepository'
9
+ };
1
10
  /**
2
11
  * Enum representing the names of prompts used in the application download process.
3
12
  */
@@ -1,12 +1,14 @@
1
1
  import type { AppIndex } from '@sap-ux/axios-extension';
2
2
  import type { AppInfo, AppItem } from '../app/types.js';
3
+ import { AppDownloadType } from '../app/types.js';
3
4
  import { type ConnectedSystem } from '@sap-ux/odata-service-inquirer';
4
5
  /**
5
6
  * Returns the details for the YUI prompt.
6
7
  *
8
+ * @param downloadType - The type of app download to determine which details to return.
7
9
  * @returns step details
8
10
  */
9
- export declare function getYUIDetails(): {
11
+ export declare function getYUIDetails(downloadType: AppDownloadType): {
10
12
  name: string;
11
13
  description: string;
12
14
  }[];
@@ -35,7 +37,8 @@ export declare const formatAppChoices: (appList: AppIndex) => Array<{
35
37
  *
36
38
  * @param {ConnectedSystem} connectedSystem - The ABAP service provider.
37
39
  * @param {string} appId - Application ID to be downloaded.
40
+ * @param {AppDownloadType} downloadType - The download type determining which search params to use.
38
41
  * @returns {Promise<AppIndex>} A list of applications filtered by source template.
39
42
  */
40
- export declare function fetchAppListForSelectedSystem(connectedSystem: ConnectedSystem, appId?: string): Promise<AppIndex>;
43
+ export declare function fetchAppListForSelectedSystem(connectedSystem: ConnectedSystem, appId?: string, downloadType?: AppDownloadType): Promise<AppIndex>;
41
44
  //# sourceMappingURL=prompt-helpers.d.ts.map
@@ -1,19 +1,17 @@
1
- import { appListSearchParams, appListResultFields, generatorTitle, generatorDescription } from '../utils/constants.js';
1
+ import { appListResultFields, downloadTypeConfig, generatorTitleConfig, adtSourceTemplateId } from '../utils/constants.js';
2
+ import { AppDownloadType } from '../app/types.js';
2
3
  import { PromptState } from './prompt-state.js';
3
4
  import { t } from '../utils/i18n.js';
4
5
  import RepoAppDownloadLogger from '../utils/logger.js';
5
6
  /**
6
7
  * Returns the details for the YUI prompt.
7
8
  *
9
+ * @param downloadType - The type of app download to determine which details to return.
8
10
  * @returns step details
9
11
  */
10
- export function getYUIDetails() {
11
- return [
12
- {
13
- name: generatorTitle,
14
- description: generatorDescription
15
- }
16
- ];
12
+ export function getYUIDetails(downloadType) {
13
+ const { title, description } = generatorTitleConfig[downloadType];
14
+ return [{ name: title, description }];
17
15
  }
18
16
  /**
19
17
  * Returns the prompt details for the selected application.
@@ -66,21 +64,27 @@ export const formatAppChoices = (appList) => {
66
64
  *
67
65
  * @param {AbapServiceProvider} provider - The ABAP service provider.
68
66
  * @param {string} appId - Application ID to filter the list.
67
+ * @param {AppDownloadType} downloadType - The download type determining which search params to use.
69
68
  * @returns {Promise<AppIndex>} A list of applications filtered by source template.
70
69
  */
71
- async function getAppList(provider, appId) {
70
+ async function getAppList(provider, appId, downloadType = AppDownloadType.ADTQuickDeploy) {
72
71
  try {
72
+ const baseSearchParams = downloadTypeConfig[downloadType].searchParams;
73
73
  const searchParams = appId
74
74
  ? {
75
- ...appListSearchParams,
75
+ ...baseSearchParams,
76
76
  'sap.app/id': appId
77
77
  }
78
- : appListSearchParams;
79
- return await provider.getAppIndex().search(searchParams, appListResultFields);
78
+ : baseSearchParams;
79
+ const results = await provider.getAppIndex().search(searchParams, appListResultFields);
80
+ if (downloadType === AppDownloadType.AbapRepository) {
81
+ // For ABAP Repository downloads, filter out apps with the ADT source template as they follow the quick deploy app download flow.
82
+ return results.filter((app) => app['sap.app/sourceTemplate/id'] !== adtSourceTemplateId);
83
+ }
84
+ return results;
80
85
  }
81
86
  catch (error) {
82
87
  RepoAppDownloadLogger.logger?.error(t('error.applicationListFetchError', { error: error.message }));
83
- RepoAppDownloadLogger.logger?.debug(t('error.applicationListFetchError', { error: JSON.stringify(error) }));
84
88
  return [];
85
89
  }
86
90
  }
@@ -89,14 +93,15 @@ async function getAppList(provider, appId) {
89
93
  *
90
94
  * @param {ConnectedSystem} connectedSystem - The ABAP service provider.
91
95
  * @param {string} appId - Application ID to be downloaded.
96
+ * @param {AppDownloadType} downloadType - The download type determining which search params to use.
92
97
  * @returns {Promise<AppIndex>} A list of applications filtered by source template.
93
98
  */
94
- export async function fetchAppListForSelectedSystem(connectedSystem, appId) {
99
+ export async function fetchAppListForSelectedSystem(connectedSystem, appId, downloadType = AppDownloadType.ADTQuickDeploy) {
95
100
  if (connectedSystem?.serviceProvider) {
96
101
  PromptState.systemSelection = {
97
102
  connectedSystem: connectedSystem
98
103
  };
99
- return await getAppList(connectedSystem.serviceProvider, appId);
104
+ return await getAppList(connectedSystem.serviceProvider, appId, downloadType);
100
105
  }
101
106
  return [];
102
107
  }