@ui5/task-adaptation 1.6.5 → 1.6.7

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.
Files changed (77) hide show
  1. package/CHANGELOG.md +9 -1
  2. package/README.md +0 -4
  3. package/dist/adapters/abapAdapter.d.ts +2 -1
  4. package/dist/adapters/abapAdapter.js +3 -0
  5. package/dist/adapters/adapter.d.ts +2 -1
  6. package/dist/adapters/cfAdapter.d.ts +2 -1
  7. package/dist/adapters/cfAdapter.js +14 -0
  8. package/dist/adapters/commands/command.d.ts +7 -7
  9. package/dist/adapters/commands/command.js +3 -2
  10. package/dist/adapters/commands/downloadAnnotationsCommand.d.ts +1 -1
  11. package/dist/adapters/commands/downloadAnnotationsCommand.js +4 -3
  12. package/dist/adapters/commands/fetchPreviewResourcesCommand.js +4 -2
  13. package/dist/adapters/commands/filterFilesCommand.d.ts +1 -1
  14. package/dist/adapters/commands/filterFilesCommand.js +2 -1
  15. package/dist/adapters/commands/i18nPropertiesMergeCommand.d.ts +1 -1
  16. package/dist/adapters/commands/i18nPropertiesMergeCommand.js +9 -6
  17. package/dist/adapters/commands/omitDeletedResourcesCommand.d.ts +1 -1
  18. package/dist/adapters/commands/omitDeletedResourcesCommand.js +1 -1
  19. package/dist/adapters/commands/processPreviewResourcesCommand.d.ts +1 -1
  20. package/dist/adapters/commands/processPreviewResourcesCommand.js +14 -7
  21. package/dist/adapters/commands/renameFilesCommand.d.ts +10 -2
  22. package/dist/adapters/commands/renameFilesCommand.js +45 -17
  23. package/dist/adapters/commands/renameManifestCommand.d.ts +14 -0
  24. package/dist/adapters/commands/renameManifestCommand.js +32 -0
  25. package/dist/adapters/commands/writeResourcesCommand.d.ts +1 -1
  26. package/dist/adapters/commands/xsAppJsonEnhanceRoutesCommand.d.ts +1 -1
  27. package/dist/adapters/commands/xsAppJsonEnhanceRoutesCommand.js +4 -3
  28. package/dist/adapters/commands/xsAppJsonMergeCommand.d.ts +1 -1
  29. package/dist/adapters/commands/xsAppJsonMergeCommand.js +4 -3
  30. package/dist/adapters/previewAdapter.d.ts +2 -1
  31. package/dist/adapters/previewAdapter.js +3 -0
  32. package/dist/annotations/abapAnnotationManager.js +1 -1
  33. package/dist/annotations/dataSource/dataSourceManager.d.ts +2 -1
  34. package/dist/annotations/dataSource/dataSourceManager.js +16 -8
  35. package/dist/appVariant.d.ts +4 -3
  36. package/dist/appVariant.js +14 -7
  37. package/dist/baseApp.d.ts +3 -3
  38. package/dist/baseApp.js +4 -4
  39. package/dist/bundle.js +24 -8
  40. package/dist/cache/cacheHolder.d.ts +11 -2
  41. package/dist/cache/cacheHolder.js +23 -1
  42. package/dist/index.d.ts +10 -1
  43. package/dist/index.js +24 -4
  44. package/dist/landscapeConfiguration.d.ts +3 -3
  45. package/dist/landscapeConfiguration.js +38 -28
  46. package/dist/model/types.d.ts +4 -1
  47. package/dist/repositories/abapProvider.js +2 -2
  48. package/dist/repositories/abapRepository.d.ts +1 -1
  49. package/dist/repositories/cacheRepository.d.ts +10 -0
  50. package/dist/repositories/cacheRepository.js +29 -0
  51. package/dist/repositories/html5Repository.d.ts +1 -1
  52. package/dist/repositories/localRepository.d.ts +1 -1
  53. package/dist/repositories/repository.d.ts +1 -1
  54. package/dist/util/commonUtil.d.ts +6 -1
  55. package/dist/util/commonUtil.js +16 -1
  56. package/dist/util/fsUtil.d.ts +2 -2
  57. package/dist/util/fsUtil.js +4 -4
  58. package/dist/util/manifestUtil.d.ts +6 -0
  59. package/dist/util/manifestUtil.js +15 -0
  60. package/dist/util/movingHandler/changeFileMoveHandler.d.ts +3 -3
  61. package/dist/util/movingHandler/changeFileMoveHandler.js +5 -4
  62. package/dist/util/renamingHandlers/jsonRenamingHandler.d.ts +6 -5
  63. package/dist/util/renamingHandlers/jsonRenamingHandler.js +15 -15
  64. package/dist/util/renamingUtil.d.ts +17 -0
  65. package/dist/util/renamingUtil.js +102 -81
  66. package/dist/util/resourceUtil.d.ts +15 -6
  67. package/dist/util/resourceUtil.js +45 -13
  68. package/dist/util/validator/abapConnectionValidator.d.ts +5 -0
  69. package/dist/util/validator/abapConnectionValidator.js +22 -0
  70. package/dist/util/validator/abapValidator.d.ts +2 -4
  71. package/dist/util/validator/abapValidator.js +4 -16
  72. package/dist/util/zipUtil.d.ts +1 -1
  73. package/dist/util/zipUtil.js +1 -1
  74. package/package.json +7 -7
  75. package/types/ui5.d.ts +2 -0
  76. package/dist/util/renamingHandlers/renamingHandler.d.ts +0 -4
  77. package/dist/util/renamingHandlers/renamingHandler.js +0 -2
package/CHANGELOG.md CHANGED
@@ -2,7 +2,13 @@
2
2
  All notable changes to this project will be documented in this file.
3
3
  This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
4
4
 
5
- A list of unreleased changes can be found [here](https://github.com/SAP/ui5-task-adaptation/compare/v1.6.5...HEAD).
5
+ A list of unreleased changes can be found [here](https://github.com/SAP/ui5-task-adaptation/compare/v1.6.7...HEAD).
6
+
7
+ <a name="v1.6.7"></a>
8
+ ## [v1.6.7] - 2026-07-28
9
+
10
+ <a name="v1.6.6"></a>
11
+ ## [v1.6.6] - 2026-06-30
6
12
 
7
13
  <a name="v1.6.5"></a>
8
14
  ## [v1.6.5] - 2026-06-24
@@ -158,6 +164,8 @@ A list of unreleased changes can be found [here](https://github.com/SAP/ui5-task
158
164
  <a name="v1.0.0"></a>
159
165
  ## v1.0.0 - 2020-12-09
160
166
 
167
+ [v1.6.7]: https://github.com/SAP/ui5-task-adaptation/compare/v1.6.6...v1.6.7
168
+ [v1.6.6]: https://github.com/SAP/ui5-task-adaptation/compare/v1.6.5...v1.6.6
161
169
  [v1.6.5]: https://github.com/SAP/ui5-task-adaptation/compare/v1.6.4...v1.6.5
162
170
  [v1.6.4]: https://github.com/SAP/ui5-task-adaptation/compare/v1.6.3...v1.6.4
163
171
  [v1.6.3]: https://github.com/SAP/ui5-task-adaptation/compare/v1.6.2...v1.6.3
package/README.md CHANGED
@@ -23,10 +23,6 @@ target:
23
23
  destination: abc
24
24
  ```
25
25
 
26
- ### Local/Offline Build
27
- Specify environment variables `ADP_BUILDER_MODE=local` and `ADP_BUILDER_DIR=<path-to-base-app-files>` to build the Adaptation Project from local base app files offline - without accessing the remote repositories.
28
-
29
- ### More
30
26
  For more information, see [Create an Adaptation Project](https://help.sap.com/docs/bas/developing-sap-fiori-app-in-sap-business-application-studio/create-project) (on SAP S/4HANA Cloud) or [Create an Adaptation Project](https://help.sap.com/docs/bas/developing-sap-fiori-app-in-sap-business-application-studio/create-adaptation-project-c7b455d488bc4229af7efe0311546752) (on SAP BTP, Cloud Foundry environment).
31
27
  > [!NOTE]
32
28
  > For SAP S/4HANA (on-premise) systems, a different builder is used.
@@ -1,5 +1,5 @@
1
1
  import { IAdapter } from "./adapter.js";
2
- import { AdaptCommandChain, PostCommandChain, SetupCommandChain } from "./commands/command.js";
2
+ import { AdaptCommandChain, ManifestUpdateCommandChain, PostCommandChain, SetupCommandChain } from "./commands/command.js";
3
3
  import BaseApp from "../baseApp.js";
4
4
  import AppVariant from "../appVariant.js";
5
5
  import IAnnotationManager from "../annotations/annotationManager.js";
@@ -11,4 +11,5 @@ export default class AbapAdapter implements IAdapter {
11
11
  createSetupCommandChain(_appId: string, _repository: IRepository): SetupCommandChain;
12
12
  createAdaptCommandChain(baseApp: BaseApp, appVariant: AppVariant): AdaptCommandChain;
13
13
  createPostCommandChain(references: Map<string, string>, adaptationProject: AppVariant, ui5BuilderTools: UI5BuilderTools): PostCommandChain;
14
+ createManifestPreviewCommandChain(_baseApp: BaseApp, _appVariant: AppVariant): ManifestUpdateCommandChain;
14
15
  }
@@ -28,5 +28,8 @@ export default class AbapAdapter {
28
28
  createPostCommandChain(references, adaptationProject, ui5BuilderTools) {
29
29
  return new PostCommandChain(getCommonPostCommands(references, adaptationProject, ui5BuilderTools));
30
30
  }
31
+ createManifestPreviewCommandChain(_baseApp, _appVariant) {
32
+ throw new Error("previewManifest currently supports Cloud Foundry (CF) landscapes only");
33
+ }
31
34
  }
32
35
  //# sourceMappingURL=abapAdapter.js.map
@@ -3,11 +3,12 @@ import BaseApp from "../baseApp.js";
3
3
  import { IAppVariantIdHierarchyManifestItem } from "../model/appVariantIdHierarchyItem.js";
4
4
  import { UI5BuilderTools } from "../model/types.js";
5
5
  import IRepository from "../repositories/repository.js";
6
- import { AdaptCommandChain, IPromiseCommand, ManifestUpdateCommand, PostCommand, PostCommandChain, SetupCommandChain } from "./commands/command.js";
6
+ import { AdaptCommandChain, IPromiseCommand, ManifestUpdateCommand, ManifestUpdateCommandChain, PostCommand, PostCommandChain, SetupCommandChain } from "./commands/command.js";
7
7
  export interface IAdapter {
8
8
  createSetupCommandChain(appId: string, repository: IRepository): SetupCommandChain;
9
9
  createAdaptCommandChain(baseApp: BaseApp, appVariant: AppVariant): AdaptCommandChain;
10
10
  createPostCommandChain(references: Map<string, string>, adaptationProject: AppVariant, ui5BuilderTools: UI5BuilderTools): PostCommandChain;
11
+ createManifestPreviewCommandChain(baseApp: BaseApp, appVariant: AppVariant): ManifestUpdateCommandChain;
11
12
  }
12
13
  export declare function getCommonManifestUpdateCommands(baseApp: BaseApp, appVariant: AppVariant, appVariantIdHierarchyItem: IAppVariantIdHierarchyManifestItem): ManifestUpdateCommand[];
13
14
  export declare function getCommonPostCommands(references: Map<string, string>, adaptationProject: AppVariant, ui5BuilderTools: UI5BuilderTools): PostCommand[];
@@ -1,6 +1,6 @@
1
1
  import { IConfiguration } from "../model/configuration.js";
2
2
  import { IAdapter } from "./adapter.js";
3
- import { AdaptCommandChain, PostCommandChain, SetupCommandChain } from "./commands/command.js";
3
+ import { AdaptCommandChain, ManifestUpdateCommandChain, PostCommandChain, SetupCommandChain } from "./commands/command.js";
4
4
  import BaseApp from "../baseApp.js";
5
5
  import AppVariant from "../appVariant.js";
6
6
  import { UI5BuilderTools } from "../model/types.js";
@@ -12,4 +12,5 @@ export default class CFAdapter implements IAdapter {
12
12
  createSetupCommandChain(_appId: string, _repository: IRepository): SetupCommandChain;
13
13
  createAdaptCommandChain(baseApp: BaseApp, appVariant: AppVariant): AdaptCommandChain;
14
14
  createPostCommandChain(references: Map<string, string>, adaptationProject: AppVariant, ui5BuilderTools: UI5BuilderTools): PostCommandChain;
15
+ createManifestPreviewCommandChain(baseApp: BaseApp, appVariant: AppVariant): ManifestUpdateCommandChain;
15
16
  }
@@ -1,7 +1,9 @@
1
1
  import { dependsOn, getCommonManifestUpdateCommands, getCommonPostCommands } from "./adapter.js";
2
2
  import { AdaptCommandChain, ManifestUpdateCommandChain, PostCommandChain, SetupCommandChain } from "./commands/command.js";
3
+ import { getReferences } from "../util/commonUtil.js";
3
4
  import XsAppJsonEnhanceRoutesCommand from "./commands/xsAppJsonEnhanceRoutesCommand.js";
4
5
  import UpdateCloudPlatformCommand from "./commands/updateCloudPlatformCommand.js";
6
+ import RenameManifestCommand from "./commands/renameManifestCommand.js";
5
7
  import I18nPropertiesMergeCommand from "./commands/i18nPropertiesMergeCommand.js";
6
8
  import XsAppJsonMergeCommand from "./commands/xsAppJsonMergeCommand.js";
7
9
  import FetchEndpointsCommand from "./commands/fetchEndpointsCommand.js";
@@ -39,5 +41,17 @@ export default class CFAdapter {
39
41
  ...getCommonPostCommands(references, adaptationProject, ui5BuilderTools)
40
42
  ]);
41
43
  }
44
+ createManifestPreviewCommandChain(baseApp, appVariant) {
45
+ const appVariantIdHierarchyItem = {
46
+ appVariantId: baseApp.id,
47
+ version: baseApp.version
48
+ };
49
+ const references = getReferences([appVariant], appVariant.id);
50
+ return new ManifestUpdateCommandChain([
51
+ ...getCommonManifestUpdateCommands(baseApp, appVariant, appVariantIdHierarchyItem),
52
+ new UpdateCloudPlatformCommand(this.configuration.sapCloudService),
53
+ new RenameManifestCommand(references),
54
+ ]);
55
+ }
42
56
  }
43
57
  //# sourceMappingURL=cfAdapter.js.map
@@ -21,7 +21,7 @@ export declare abstract class AdaptCommand {
21
21
  * @param files - Map of all files being processed
22
22
  * @param filename - The current file being processed
23
23
  */
24
- abstract execute(files: Map<string, string>, filename: string): Promise<void>;
24
+ abstract execute(files: Map<string, Buffer>, filename: string): Promise<void>;
25
25
  }
26
26
  export declare abstract class MergeCommand {
27
27
  readonly commandType = "merge";
@@ -32,7 +32,7 @@ export declare abstract class MergeCommand {
32
32
  * @param filename - The current file being processed
33
33
  * @param appVariantContent - Content from the app variant
34
34
  */
35
- abstract execute(files: Map<string, string>, filename: string, appVariantContent: string): Promise<void>;
35
+ abstract execute(files: Map<string, Buffer>, filename: string, appVariantContent: Buffer): Promise<void>;
36
36
  }
37
37
  export declare abstract class ManifestUpdateCommand {
38
38
  readonly commandType = "manifestUpdate";
@@ -46,7 +46,7 @@ export declare class ManifestUpdateCommandChain extends AdaptCommand {
46
46
  private commands;
47
47
  constructor(commands?: ManifestUpdateCommand[]);
48
48
  accept: (filename: string) => filename is "manifest.json";
49
- execute(files: Map<string, string>, filename: string): Promise<void>;
49
+ execute(files: Map<string, Buffer>, filename: string): Promise<void>;
50
50
  }
51
51
  export declare abstract class PostCommand {
52
52
  readonly commandType = "post";
@@ -54,7 +54,7 @@ export declare abstract class PostCommand {
54
54
  * Executes the command on the specified file
55
55
  * @param files - Map of all files being processed
56
56
  */
57
- abstract execute(files: Map<string, string>): Promise<void>;
57
+ abstract execute(files: Map<string, Buffer>): Promise<void>;
58
58
  }
59
59
  /**
60
60
  * CommandChain implements the Chain of Responsibility pattern
@@ -67,15 +67,15 @@ export declare class PostCommandChain {
67
67
  * Executes all commands in the chain that accept the given filename
68
68
  * @param files - Map of all files being processed
69
69
  */
70
- execute(files: ReadonlyMap<string, string>): Promise<ReadonlyMap<string, string>>;
70
+ execute(files: ReadonlyMap<string, Buffer>): Promise<ReadonlyMap<string, Buffer>>;
71
71
  }
72
72
  export declare class AdaptCommandChain {
73
73
  private files;
74
74
  private appVariantFiles;
75
75
  private adaptCommands;
76
76
  private mergeCommands;
77
- constructor(files: ReadonlyMap<string, string>, appVariantFiles: ReadonlyMap<string, string>, commands: (AdaptCommand | MergeCommand)[]);
78
- execute(): Promise<ReadonlyMap<string, string>>;
77
+ constructor(files: ReadonlyMap<string, Buffer>, appVariantFiles: ReadonlyMap<string, Buffer>, commands: (AdaptCommand | MergeCommand)[]);
78
+ execute(): Promise<ReadonlyMap<string, Buffer>>;
79
79
  }
80
80
  export interface IPromiseCommand<T> {
81
81
  result: Promise<T>;
@@ -1,3 +1,4 @@
1
+ import { stringToBuffer, bufferToJson } from "../../util/commonUtil.js";
1
2
  import { getLogger } from "@ui5/logger";
2
3
  const log = getLogger("@ui5/task-adaptation::CommandChain");
3
4
  export class SetupCommand {
@@ -42,14 +43,14 @@ export class ManifestUpdateCommandChain extends AdaptCommand {
42
43
  if (!manifestContent) {
43
44
  throw new Error("Original application should have manifest.json in root folder");
44
45
  }
45
- const manifest = JSON.parse(manifestContent);
46
+ const manifest = bufferToJson(manifestContent);
46
47
  const timings = [];
47
48
  for (const command of this.commands) {
48
49
  const start = performance.now();
49
50
  await command.execute(manifest);
50
51
  pushTiming(command, timings, start);
51
52
  }
52
- files.set(filename, JSON.stringify(manifest));
53
+ files.set(filename, stringToBuffer(JSON.stringify(manifest)));
53
54
  logTimings(this, timings);
54
55
  }
55
56
  }
@@ -6,5 +6,5 @@ export default class DownloadAnnotationsCommand extends AdaptCommand {
6
6
  private annotationManager;
7
7
  constructor(appVariantId: string, prefix: string, annotationManager: IAnnotationManager);
8
8
  accept: (filename: string) => filename is "manifest.json";
9
- execute(files: Map<string, string>, filename: string): Promise<void>;
9
+ execute(files: Map<string, Buffer>, filename: string): Promise<void>;
10
10
  }
@@ -1,4 +1,5 @@
1
1
  import { AdaptCommand } from "./command.js";
2
+ import { stringToBuffer, bufferToJson } from "../../util/commonUtil.js";
2
3
  export default class DownloadAnnotationsCommand extends AdaptCommand {
3
4
  appVariantId;
4
5
  prefix;
@@ -11,12 +12,12 @@ export default class DownloadAnnotationsCommand extends AdaptCommand {
11
12
  }
12
13
  accept = (filename) => filename === "manifest.json";
13
14
  async execute(files, filename) {
14
- const baseAppManifest = JSON.parse(files.get(filename));
15
+ const baseAppManifest = bufferToJson(files.get(filename));
15
16
  let newFiles = await this.annotationManager.process(baseAppManifest, this.appVariantId, this.prefix);
16
17
  if (newFiles) {
17
- newFiles.forEach((value, key) => files.set(key, value));
18
+ newFiles.forEach((value, key) => files.set(key, stringToBuffer(value)));
18
19
  }
19
- files.set(filename, JSON.stringify(baseAppManifest));
20
+ files.set(filename, stringToBuffer(JSON.stringify(baseAppManifest)));
20
21
  }
21
22
  }
22
23
  //# sourceMappingURL=downloadAnnotationsCommand.js.map
@@ -1,4 +1,5 @@
1
1
  import FsUtil from "../../util/fsUtil.js";
2
+ import { stringToBuffer, bufferToString } from "../../util/commonUtil.js";
2
3
  import { posix as path } from "path";
3
4
  import { SetupCommand } from "./command.js";
4
5
  import { getLogger } from "@ui5/logger";
@@ -19,7 +20,7 @@ export default class FetchPreviewResourcesCommand extends SetupCommand {
19
20
  async preparePreview() {
20
21
  let ui5AppInfo = "";
21
22
  try {
22
- ui5AppInfo = await FsUtil.readInProject("ui5AppInfo.json", "utf-8");
23
+ ui5AppInfo = bufferToString(await FsUtil.readInProject("ui5AppInfo.json"));
23
24
  }
24
25
  catch (error) {
25
26
  throw new Error(`ui5AppInfo.json is missing in project root, cannot process preview resources: ${error instanceof Error ? error.message : String(error)}`);
@@ -76,7 +77,8 @@ export default class FetchPreviewResourcesCommand extends SetupCommand {
76
77
  const newFilename = path.join(libraryName, filename);
77
78
  // Source path in xs-app.json needs to be adjusted to new location
78
79
  if (filename.includes("xs-app.json")) {
79
- content = this.modifyRoutes(content, libraryName, libId);
80
+ const modified = this.modifyRoutes(bufferToString(content), libraryName, libId);
81
+ content = stringToBuffer(modified);
80
82
  }
81
83
  files.set(newFilename, content);
82
84
  });
@@ -1,4 +1,4 @@
1
1
  import { PostCommand } from "./command.js";
2
2
  export default class FilterFilesCommand extends PostCommand {
3
- execute(files: Map<string, string>): Promise<void>;
3
+ execute(files: Map<string, Buffer>): Promise<void>;
4
4
  }
@@ -1,10 +1,11 @@
1
1
  import { PostCommand } from "./command.js";
2
+ import { bufferToJson } from "../../util/commonUtil.js";
2
3
  export default class FilterFilesCommand extends PostCommand {
3
4
  async execute(files) {
4
5
  const IGNORE_FILES = ["manifest.appdescr_variant"];
5
6
  const shouldIgnore = (filename, content) => {
6
7
  if (filename.endsWith(".change")) {
7
- return JSON.parse(content).changeType?.startsWith("appdescr_"); // validate JSON
8
+ return bufferToJson(content).changeType?.startsWith("appdescr_"); // validate JSON
8
9
  }
9
10
  return IGNORE_FILES.includes(filename);
10
11
  };
@@ -8,7 +8,7 @@ export default class I18nPropertiesMergeCommand extends MergeCommand {
8
8
  constructor(i18nPath: string, prefix: string, manifestChanges: ReadonlyArray<IChange>);
9
9
  accept: (filename: string) => boolean;
10
10
  private analyzeAppVariantManifestChanges;
11
- execute(files: Map<string, string>, filename: string, appVariantContent: string): Promise<void>;
11
+ execute(files: Map<string, Buffer>, filename: string, appVariantContent: Buffer): Promise<void>;
12
12
  /**
13
13
  * Filters out specific lines from the given string.
14
14
  * Removes lines matching:
@@ -1,4 +1,4 @@
1
- import { escapeRegex, trimExtension } from "../../util/commonUtil.js";
1
+ import { stringToBuffer, bufferToString, bufferToNormalizedString, escapeRegex, trimExtension } from "../../util/commonUtil.js";
2
2
  import { posix as path } from "path";
3
3
  import { MergeCommand } from "./command.js";
4
4
  export default class I18nPropertiesMergeCommand extends MergeCommand {
@@ -45,11 +45,12 @@ export default class I18nPropertiesMergeCommand extends MergeCommand {
45
45
  // check if file matches with regex in merge/copy
46
46
  const mergePathMatch = this.mergePaths.map(path => filename.match(path)).find(match => match);
47
47
  const copyPathMatch = this.copyPaths.map(path => filename.match(path)).find(match => match);
48
+ const appVariantFileContent = bufferToNormalizedString(appVariantContent);
48
49
  if (mergePathMatch) {
49
- this.mergePropertiesFiles(files, this.i18nPath, appVariantContent, mergePathMatch[1]);
50
+ this.mergePropertiesFiles(files, this.i18nPath, appVariantFileContent, mergePathMatch[1]);
50
51
  }
51
52
  if (copyPathMatch) {
52
- files.set(path.join(this.prefix, filename), appVariantContent);
53
+ files.set(path.join(this.prefix, filename), stringToBuffer(appVariantFileContent));
53
54
  }
54
55
  }
55
56
  /**
@@ -76,12 +77,14 @@ export default class I18nPropertiesMergeCommand extends MergeCommand {
76
77
  */
77
78
  mergePropertiesFiles(files, i18nPath, appVariantFileContent, language = "") {
78
79
  const baseAppI18nPath = i18nPath + language + ".properties";
79
- const baseAppFileContent = files.get(baseAppI18nPath);
80
- const filteredBaseContent = baseAppFileContent ? this.filterTranslationMetaLines(baseAppFileContent) : "";
80
+ const baseAppFileBuffer = files.get(baseAppI18nPath);
81
+ const filteredBaseContent = baseAppFileBuffer
82
+ ? this.filterTranslationMetaLines(bufferToString(baseAppFileBuffer))
83
+ : "";
81
84
  const content = filteredBaseContent
82
85
  ? `${filteredBaseContent}\n\n#App variant specific text file\n\n${appVariantFileContent}`
83
86
  : appVariantFileContent;
84
- files.set(baseAppI18nPath, content);
87
+ files.set(baseAppI18nPath, stringToBuffer(content));
85
88
  }
86
89
  }
87
90
  //# sourceMappingURL=i18nPropertiesMergeCommand.js.map
@@ -6,5 +6,5 @@ export default class OmitDeletedResourcesCommand extends PostCommand {
6
6
  private resources;
7
7
  private projectNamespace;
8
8
  constructor(taskUtil: TaskUtil, movedFiles: Map<string, string>, resources: ReadonlyArray<Resource> | undefined, projectNamespace: string);
9
- execute(files: Map<string, string>): Promise<void>;
9
+ execute(files: Map<string, Buffer>): Promise<void>;
10
10
  }
@@ -21,7 +21,7 @@ export default class OmitDeletedResourcesCommand extends PostCommand {
21
21
  if (newPath) {
22
22
  const renamedContent = files.get(newPath);
23
23
  if (renamedContent) {
24
- resource.setString(renamedContent);
24
+ resource.setBuffer(renamedContent);
25
25
  }
26
26
  }
27
27
  }
@@ -4,6 +4,6 @@ export default class ProcessPreviewResourcesCommand extends PostCommand {
4
4
  private serviceCredentialsPromise;
5
5
  private previewPromise;
6
6
  constructor(serviceCredentialsPromise: Promise<ServiceCredentials | undefined>, previewPromise: Promise<FetchFilesPromise | undefined>);
7
- execute(files: Map<string, string>): Promise<void>;
7
+ execute(files: Map<string, Buffer>): Promise<void>;
8
8
  private collectReuseLibFiles;
9
9
  }
@@ -1,9 +1,9 @@
1
1
  import { PostCommand } from "./command.js";
2
+ import { stringToBuffer, bufferToString } from "../../util/commonUtil.js";
2
3
  import { getLogger } from "@ui5/logger";
3
- import { merge, XSAPP_JSON_FILENAME } from "../../util/cf/xsAppJsonUtil.js";
4
+ import { fetchCredentialsAndEnhanceRoutes, merge, XSAPP_JSON_FILENAME } from "../../util/cf/xsAppJsonUtil.js";
4
5
  import ResourceUtil from "../../util/resourceUtil.js";
5
6
  import { REUSE_DIR } from "../../model/configuration.js";
6
- import XsAppJsonEnhanceRoutesCommand from "./xsAppJsonEnhanceRoutesCommand.js";
7
7
  const log = getLogger("@ui5/task-adaptation::ProcessPreviewResourcesCommand");
8
8
  export default class ProcessPreviewResourcesCommand extends PostCommand {
9
9
  serviceCredentialsPromise;
@@ -15,15 +15,21 @@ export default class ProcessPreviewResourcesCommand extends PostCommand {
15
15
  }
16
16
  async execute(files) {
17
17
  log.verbose(`Downloading reuse libraries to reuse folder`);
18
- const baseAppXsAppJson = files.get(XSAPP_JSON_FILENAME);
18
+ const baseAppXsAppJsonBuffer = files.get(XSAPP_JSON_FILENAME);
19
+ const baseAppXsAppJson = baseAppXsAppJsonBuffer ? bufferToString(baseAppXsAppJsonBuffer) : undefined;
19
20
  const mergedFiles = await this.collectReuseLibFiles(await this.previewPromise, baseAppXsAppJson);
20
- new XsAppJsonEnhanceRoutesCommand(this.serviceCredentialsPromise).execute(mergedFiles);
21
+ const xsAppJson = mergedFiles.get(XSAPP_JSON_FILENAME);
22
+ if (xsAppJson) {
23
+ const enhanced = await fetchCredentialsAndEnhanceRoutes(bufferToString(xsAppJson), this.serviceCredentialsPromise);
24
+ mergedFiles.set(XSAPP_JSON_FILENAME, stringToBuffer(enhanced));
25
+ }
21
26
  if (mergedFiles.size === 0) {
22
27
  return;
23
28
  }
24
29
  await ResourceUtil.writeInProject(REUSE_DIR, mergedFiles);
25
30
  }
26
- async collectReuseLibFiles(fetchLibsPromises, mergedXsAppJson) {
31
+ async collectReuseLibFiles(fetchLibsPromises, baseAppXsAppJson) {
32
+ let mergedXsAppJson = baseAppXsAppJson;
27
33
  const mergedFiles = new Map();
28
34
  if (!fetchLibsPromises) {
29
35
  log.verbose("No reuse libraries defined in ui5AppInfo.json for preview");
@@ -37,13 +43,14 @@ export default class ProcessPreviewResourcesCommand extends PostCommand {
37
43
  }
38
44
  for (const [filename, content] of libFiles) {
39
45
  if (filename.endsWith(XSAPP_JSON_FILENAME)) {
40
- mergedXsAppJson = mergedXsAppJson ? merge([content, mergedXsAppJson]) : content;
46
+ const xsAppText = bufferToString(content);
47
+ mergedXsAppJson = mergedXsAppJson ? merge([xsAppText, mergedXsAppJson]) : xsAppText;
41
48
  }
42
49
  mergedFiles.set(filename, content);
43
50
  }
44
51
  }
45
52
  if (mergedXsAppJson) {
46
- mergedFiles.set(XSAPP_JSON_FILENAME, mergedXsAppJson);
53
+ mergedFiles.set(XSAPP_JSON_FILENAME, stringToBuffer(mergedXsAppJson));
47
54
  }
48
55
  return mergedFiles;
49
56
  }
@@ -2,7 +2,7 @@ import { PostCommand } from "./command.js";
2
2
  export default class RenameFilesCommand extends PostCommand {
3
3
  private references;
4
4
  constructor(references: Map<string, string>);
5
- execute(files: Map<string, string>): Promise<void>;
5
+ execute(files: Map<string, Buffer>): Promise<void>;
6
6
  /**
7
7
  * 1p. i18n.properties are not renamed and property keys are ignored during
8
8
  * the renaming across the files.
@@ -10,11 +10,19 @@ export default class RenameFilesCommand extends PostCommand {
10
10
  * @param references - Reference maps of the app variant
11
11
  * @returns A map of renamed files
12
12
  */
13
- rename(files: Map<string, string>, references: Map<string, string>): void;
13
+ rename(files: Map<string, Buffer>, references: Map<string, string>): void;
14
14
  private getManifestSAPUI5DependencyIds;
15
15
  private getI18nPropertyKeys;
16
16
  }
17
17
  /**
18
18
  * We might rename appVariantIdHierarchy and dependencies, so we restore them after the renaming.
19
+ *
20
+ * The decorated method may receive either a Map of files (filename → Buffer) or
21
+ * a plain JSON object. Each handler is responsible for a single file (via its
22
+ * `accept`), operating on its parsed JSON content:
23
+ * - Map case: every file a handler accepts is parsed, snapshotted before the
24
+ * renaming, then restored and written back after.
25
+ * - JSON case: the object is mutated in-place (its reference is preserved) and
26
+ * every handler is applied to it.
19
27
  */
20
28
  export declare function restoreWhatShouldntBeRenamed(): (_target: any, _propertyKey: string, descriptor: PropertyDescriptor) => void;
@@ -5,8 +5,15 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
7
  import ManifestRenamingHandler from "../../util/renamingHandlers/manifestRenamingHandler.js";
8
+ import { stringToBuffer, bufferToString, bufferToJson, jsonToBuffer } from "../../util/commonUtil.js";
9
+ import { getSAPUI5DependencyIds } from "../../util/manifestUtil.js";
8
10
  import { renameMap } from "../../util/renamingUtil.js";
11
+ import { TEXT_EXTENSIONS } from "../../util/resourceUtil.js";
12
+ import { posix as path } from "path";
9
13
  import { PostCommand } from "./command.js";
14
+ function isTextFile(filename) {
15
+ return TEXT_EXTENSIONS.has(path.extname(filename).slice(1));
16
+ }
10
17
  export default class RenameFilesCommand extends PostCommand {
11
18
  references;
12
19
  constructor(references) {
@@ -31,13 +38,17 @@ export default class RenameFilesCommand extends PostCommand {
31
38
  ];
32
39
  const updates = new Map();
33
40
  for (const [filename, content] of files) {
41
+ if (!isTextFile(filename)) {
42
+ continue;
43
+ }
34
44
  if (!IGNORE_EXTENSIONS.some(ext => filename.endsWith(ext))) {
35
45
  // 5p. We pass replacements as ignores since we don't want to
36
46
  // rename them again. E.g. we replace app.id with
37
47
  // customer.app.id, but if we found customer.app.id somewhere,
38
48
  // because we applied changes or something, we don't want to
39
49
  // rename it again to customer.customer.app.id.
40
- updates.set(filename, renameMap(content, references, [...references.values(), ...ignoreInString]));
50
+ const renamed = renameMap(bufferToString(content), references, [...references.values(), ...ignoreInString]);
51
+ updates.set(filename, stringToBuffer(renamed));
41
52
  }
42
53
  }
43
54
  for (const [filename, content] of updates) {
@@ -46,22 +57,13 @@ export default class RenameFilesCommand extends PostCommand {
46
57
  }
47
58
  getManifestSAPUI5DependencyIds(files) {
48
59
  const manifestFile = files.get("manifest.json");
49
- if (manifestFile) {
50
- const manifest = JSON.parse(manifestFile);
51
- const dependencies = manifest["sap.ui5"]?.dependencies;
52
- if (dependencies) {
53
- const libs = dependencies.libs ? Object.keys(dependencies.libs) : [];
54
- const components = dependencies.components ? Object.keys(dependencies.components) : [];
55
- return [...libs, ...components];
56
- }
57
- }
58
- return [];
60
+ return manifestFile ? getSAPUI5DependencyIds(bufferToJson(manifestFile)) : [];
59
61
  }
60
62
  getI18nPropertyKeys(files) {
61
63
  const keys = new Set();
62
64
  files.forEach((content, filename) => {
63
65
  if (filename.endsWith(".properties")) {
64
- const lines = content.split("\n").filter(line => !line.startsWith("#"));
66
+ const lines = bufferToString(content).split("\n").filter(line => !line.startsWith("#"));
65
67
  for (const line of lines) {
66
68
  const [key] = line.split("=");
67
69
  if (key) {
@@ -78,20 +80,46 @@ __decorate([
78
80
  ], RenameFilesCommand.prototype, "rename", null);
79
81
  /**
80
82
  * We might rename appVariantIdHierarchy and dependencies, so we restore them after the renaming.
83
+ *
84
+ * The decorated method may receive either a Map of files (filename → Buffer) or
85
+ * a plain JSON object. Each handler is responsible for a single file (via its
86
+ * `accept`), operating on its parsed JSON content:
87
+ * - Map case: every file a handler accepts is parsed, snapshotted before the
88
+ * renaming, then restored and written back after.
89
+ * - JSON case: the object is mutated in-place (its reference is preserved) and
90
+ * every handler is applied to it.
81
91
  */
82
92
  export function restoreWhatShouldntBeRenamed() {
83
93
  return function (_target, _propertyKey, descriptor) {
84
94
  const handlers = [new ManifestRenamingHandler()];
85
95
  const originalValue = descriptor.value;
86
96
  descriptor.value = function (...args) {
87
- const files = args[0];
88
- const references = args[1];
89
- handlers.forEach(handler => handler.before(files));
90
- originalValue.apply(this, [files, references]);
91
- handlers.forEach(handler => handler.after(files));
97
+ const renaming = args[0];
98
+ const files = renaming;
99
+ forEachAccepted(files, handlers, (handler, content) => handler.before(bufferToJson(content)));
100
+ originalValue.apply(this, args);
101
+ forEachAccepted(files, handlers, (handler, content, filename) => {
102
+ const json = bufferToJson(content);
103
+ handler.after(json);
104
+ files.set(filename, jsonToBuffer(json));
105
+ });
92
106
  return files;
93
107
  };
94
108
  };
95
109
  }
96
110
  ;
111
+ /**
112
+ * Parses each file that at least one handler accepts, hands the JSON to the
113
+ * given callback along with the accepting handlers, and — when `writeBack` is
114
+ * provided — serializes the (possibly mutated) JSON back into that map.
115
+ */
116
+ function forEachAccepted(files, handlers, callback) {
117
+ for (const [filename, content] of files) {
118
+ for (const handler of handlers) {
119
+ if (handler.accept(filename)) {
120
+ callback(handler, content, filename);
121
+ }
122
+ }
123
+ }
124
+ }
97
125
  //# sourceMappingURL=renameFilesCommand.js.map
@@ -0,0 +1,14 @@
1
+ import { ManifestUpdateCommand } from "./command.js";
2
+ /**
3
+ * Renames app variant references (base app id -> app variant id) inside the
4
+ * manifest.json object. This is the manifest scoped counterpart of
5
+ * {@link RenameFilesCommand}: it operates on the parsed manifest object rather
6
+ * than the raw file map, so it slots into the {@link ManifestUpdateCommandChain}
7
+ * alongside the other manifest updates instead of running as a post step.
8
+ */
9
+ export default class RenameManifestCommand extends ManifestUpdateCommand {
10
+ private references;
11
+ private ignoreInStrings;
12
+ constructor(references: Map<string, string>, ignoreInStrings?: string[]);
13
+ execute(manifest: any): Promise<void>;
14
+ }
@@ -0,0 +1,32 @@
1
+ import { ManifestUpdateCommand } from "./command.js";
2
+ import { renameJson } from "../../util/renamingUtil.js";
3
+ import { getSAPUI5DependencyIds } from "../../util/manifestUtil.js";
4
+ import ManifestRenamingHandler from "../../util/renamingHandlers/manifestRenamingHandler.js";
5
+ /**
6
+ * Renames app variant references (base app id -> app variant id) inside the
7
+ * manifest.json object. This is the manifest scoped counterpart of
8
+ * {@link RenameFilesCommand}: it operates on the parsed manifest object rather
9
+ * than the raw file map, so it slots into the {@link ManifestUpdateCommandChain}
10
+ * alongside the other manifest updates instead of running as a post step.
11
+ */
12
+ export default class RenameManifestCommand extends ManifestUpdateCommand {
13
+ references;
14
+ ignoreInStrings;
15
+ constructor(references, ignoreInStrings = []) {
16
+ super();
17
+ this.references = references;
18
+ this.ignoreInStrings = ignoreInStrings;
19
+ }
20
+ async execute(manifest) {
21
+ const renamingHandler = new ManifestRenamingHandler();
22
+ renamingHandler.snapshot(manifest);
23
+ const ignoreInStrings = [
24
+ ...this.references.values(),
25
+ ...this.ignoreInStrings,
26
+ ...getSAPUI5DependencyIds(manifest)
27
+ ];
28
+ renameJson(manifest, this.references, ignoreInStrings);
29
+ renamingHandler.restore(manifest);
30
+ }
31
+ }
32
+ //# sourceMappingURL=renameManifestCommand.js.map
@@ -3,5 +3,5 @@ export default class WriteResourcesCommand extends PostCommand {
3
3
  private workspace;
4
4
  private projectNamespace;
5
5
  constructor(workspace: any, projectNamespace: string);
6
- execute(files: Map<string, string>): Promise<void>;
6
+ execute(files: Map<string, Buffer>): Promise<void>;
7
7
  }
@@ -3,5 +3,5 @@ import { PostCommand } from "./command.js";
3
3
  export default class XsAppJsonEnhanceRoutesCommand extends PostCommand {
4
4
  private serviceCredentialsPromise;
5
5
  constructor(serviceCredentialsPromise: Promise<ServiceCredentials | undefined>);
6
- execute(files: Map<string, string>): Promise<void>;
6
+ execute(files: Map<string, Buffer>): Promise<void>;
7
7
  }
@@ -1,5 +1,6 @@
1
1
  import { fetchCredentialsAndEnhanceRoutes } from "../../util/cf/xsAppJsonUtil.js";
2
2
  import { PostCommand } from "./command.js";
3
+ import { stringToBuffer, bufferToString } from "../../util/commonUtil.js";
3
4
  export default class XsAppJsonEnhanceRoutesCommand extends PostCommand {
4
5
  serviceCredentialsPromise;
5
6
  constructor(serviceCredentialsPromise) {
@@ -7,10 +8,10 @@ export default class XsAppJsonEnhanceRoutesCommand extends PostCommand {
7
8
  this.serviceCredentialsPromise = serviceCredentialsPromise;
8
9
  }
9
10
  async execute(files) {
10
- let xsAppJson = files.get("xs-app.json");
11
+ const xsAppJson = files.get("xs-app.json");
11
12
  if (xsAppJson) {
12
- xsAppJson = await fetchCredentialsAndEnhanceRoutes(xsAppJson, this.serviceCredentialsPromise);
13
- files.set("xs-app.json", xsAppJson);
13
+ const enhanced = await fetchCredentialsAndEnhanceRoutes(bufferToString(xsAppJson), this.serviceCredentialsPromise);
14
+ files.set("xs-app.json", stringToBuffer(enhanced));
14
15
  }
15
16
  }
16
17
  }