@ui5/task-adaptation 1.4.3 → 1.5.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.
Files changed (42) hide show
  1. package/CHANGELOG.md +6 -2
  2. package/README.md +16 -12
  3. package/dist/annotationManager.js +1 -3
  4. package/dist/annotations/serviceRequestor.js +3 -15
  5. package/dist/appVariantManager.d.ts +18 -11
  6. package/dist/appVariantManager.js +77 -80
  7. package/dist/baseAppManager.d.ts +16 -16
  8. package/dist/baseAppManager.js +57 -79
  9. package/dist/bundle.js +58 -42
  10. package/dist/cache/cacheHolder.d.ts +18 -0
  11. package/dist/cache/cacheHolder.js +80 -0
  12. package/dist/i18nManager.js +11 -9
  13. package/dist/index.js +26 -9
  14. package/dist/model/appVariantIdHierarchyItem.d.ts +5 -0
  15. package/dist/model/appVariantIdHierarchyItem.js +2 -0
  16. package/dist/model/language.d.ts +3 -3
  17. package/dist/model/language.js +11 -4
  18. package/dist/model/types.d.ts +2 -0
  19. package/dist/processors/abapProcessor.d.ts +4 -4
  20. package/dist/processors/abapProcessor.js +17 -6
  21. package/dist/processors/cfProcessor.d.ts +4 -4
  22. package/dist/processors/cfProcessor.js +21 -5
  23. package/dist/processors/processor.d.ts +4 -2
  24. package/dist/processors/processor.js +2 -4
  25. package/dist/repositories/abapRepoManager.d.ts +3 -1
  26. package/dist/repositories/abapRepoManager.js +24 -5
  27. package/dist/util/cfUtil.js +1 -1
  28. package/dist/util/commonUtil.d.ts +3 -2
  29. package/dist/util/commonUtil.js +17 -9
  30. package/dist/util/i18nMerger.d.ts +15 -20
  31. package/dist/util/i18nMerger.js +46 -64
  32. package/dist/util/resourceUtil.d.ts +3 -1
  33. package/dist/util/resourceUtil.js +15 -2
  34. package/eslint.config.js +2 -5
  35. package/package.json +16 -11
  36. package/types/ui5.d.ts +10 -0
  37. package/dist/cache/annotationsCacheManager.d.ts +0 -8
  38. package/dist/cache/annotationsCacheManager.js +0 -16
  39. package/dist/cache/baseAppFilesCacheManager.d.ts +0 -6
  40. package/dist/cache/baseAppFilesCacheManager.js +0 -12
  41. package/dist/cache/cacheManager.d.ts +0 -16
  42. package/dist/cache/cacheManager.js +0 -65
@@ -1,15 +1,13 @@
1
1
  import AbapProcessor from "./abapProcessor.js";
2
2
  import AbapRepoManager from "../repositories/abapRepoManager.js";
3
3
  import AnnotationManager from "../annotationManager.js";
4
- import BaseAppFilesCacheManager from "../cache/baseAppFilesCacheManager.js";
5
4
  import CFProcessor from "./cfProcessor.js";
6
5
  export function determineProcessor(configuration) {
7
- const cacheManager = new BaseAppFilesCacheManager(configuration);
8
6
  const abapRepoManager = new AbapRepoManager(configuration);
9
7
  const annotationManager = new AnnotationManager(configuration, abapRepoManager);
10
8
  const processors = [
11
- new CFProcessor(configuration, cacheManager),
12
- new AbapProcessor(configuration, cacheManager, abapRepoManager, annotationManager)
9
+ new CFProcessor(configuration),
10
+ new AbapProcessor(configuration, abapRepoManager, annotationManager)
13
11
  ];
14
12
  let processor = processors.find(processor => processor.getConfigurationType() === configuration.type);
15
13
  if (processor) {
@@ -1,11 +1,13 @@
1
1
  import { IConfiguration, IMetadata } from "../model/types.js";
2
2
  import AbapProvider from "./abapProvider.js";
3
+ import IAppVariantIdHierarchyItem from "../model/appVariantIdHierarchyItem.js";
3
4
  export default class AbapRepoManager {
4
5
  private configuration;
5
6
  private abapProvider;
6
7
  constructor(configuration: IConfiguration, abapProvider?: AbapProvider);
8
+ getAppVariantIdHierarchy(id: string): Promise<IAppVariantIdHierarchyItem[]>;
7
9
  getAnnotationMetadata(uri: string): Promise<IMetadata>;
8
10
  downloadAnnotationFile(uri: string): Promise<Map<string, any>>;
9
11
  getMetadata(id: string): Promise<IMetadata>;
10
- downloadBaseAppFiles(): Promise<Map<string, string>>;
12
+ fetch(repoName: string): Promise<Map<string, string>>;
11
13
  }
@@ -20,6 +20,26 @@ export default class AbapRepoManager {
20
20
  this.configuration = configuration;
21
21
  this.abapProvider = abapProvider ? abapProvider : new AbapProvider();
22
22
  }
23
+ async getAppVariantIdHierarchy(id) {
24
+ const provider = await this.abapProvider.get(this.configuration);
25
+ const lrep = provider.getLayeredRepository();
26
+ const response = await lrep.get("/dta_folder/app_info", {
27
+ params: { id }
28
+ });
29
+ if (response.status === 200) {
30
+ return JSON.parse(response.data)?.appVariantIdHierarchy;
31
+ }
32
+ else if (this.configuration.appName) {
33
+ // Fallback to old API on old ABAP backend or CF for backward compatibility
34
+ const metadataResponse = await this.getMetadata(id);
35
+ return [{
36
+ repoName: this.configuration.appName,
37
+ appVariantId: id,
38
+ cachebusterToken: metadataResponse.changedOn
39
+ }];
40
+ }
41
+ throw new Error(`App variant id hierarchy for app id '${id}' is not provided`);
42
+ }
23
43
  async getAnnotationMetadata(uri) {
24
44
  const provider = await this.abapProvider.get(this.configuration);
25
45
  const response = await provider.head(uri);
@@ -48,12 +68,11 @@ export default class AbapRepoManager {
48
68
  id
49
69
  };
50
70
  }
51
- async downloadBaseAppFiles() {
52
- const { destination, appName } = this.configuration;
53
- const encodedAppName = encodeURIComponent(appName);
71
+ async fetch(repoName) {
72
+ const encodedRepoName = encodeURIComponent(repoName);
54
73
  const provider = await this.abapProvider.get(this.configuration);
55
74
  const ui5Repo = provider.getUi5AbapRepository();
56
- const response = await ui5Repo.get(`/Repositories('${encodedAppName}')`, {
75
+ const response = await ui5Repo.get(`/Repositories('${encodedRepoName}')`, {
57
76
  params: {
58
77
  DownloadFiles: "RUNTIME",
59
78
  CodePage: "UTF8",
@@ -65,7 +84,7 @@ export default class AbapRepoManager {
65
84
  const buffer = Buffer.from(data.d.ZipArchive, "base64");
66
85
  return unzipZipEntries(buffer);
67
86
  }
68
- throw new Error(`App '${appName}' from '${destination}' doesn't contain files`);
87
+ throw new Error(`App '${repoName}' doesn't contain files`);
69
88
  }
70
89
  }
71
90
  //# sourceMappingURL=abapRepoManager.js.map
@@ -78,7 +78,7 @@ export default class CFUtil {
78
78
  return this.cfExecute(["create-service-key", serviceInstanceName, serviceKeyName]);
79
79
  }
80
80
  catch (error) {
81
- throw new Error(`Couldn't create a service key for instance ${serviceInstanceName}: ${error.message}`);
81
+ throw new Error(`Couldn't create a service key for instance: ${serviceInstanceName}: ${error}`);
82
82
  }
83
83
  }
84
84
  static async getServiceInstance(params) {
@@ -3,10 +3,11 @@ import Language from "../model/language.js";
3
3
  export declare function dotToUnderscore(value: string): string;
4
4
  export declare function validateObject<T extends object>(options: T, properties: Array<keyof T>, message: string): void;
5
5
  export declare function escapeRegex(update: string): string;
6
- export declare function renameResources(files: Map<string, string>, search: string, replacement: string): Map<string, string>;
6
+ export declare function renameResources(files: ReadonlyMap<string, string>, search: string, replacement: string): Map<string, string>;
7
+ export declare function rename(content: string, search: string, replacement: string): string;
7
8
  export declare function insertInArray<T>(array: T[], index: number, insert: T): void;
8
9
  export declare function writeTempAnnotations({ writeTempFiles }: IConfiguration, name: string, language: Language, content: string): void;
9
- export declare function removePropertiesExtension(filePath: string): string;
10
+ export declare function trimExtension(filePath: string): string;
10
11
  export declare function traverse(json: any, paths: string[], callback: (json: any, key: string | number, paths: string[]) => void): void;
11
12
  export declare function logBuilderVersion(): void;
12
13
  export declare function logBetaUsage(): void;
@@ -18,6 +18,14 @@ export function escapeRegex(update) {
18
18
  return update.replaceAll(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
19
19
  }
20
20
  export function renameResources(files, search, replacement) {
21
+ const replaces = getReplaceRegex(search, replacement);
22
+ const renamedFiles = new Map();
23
+ files.forEach((content, filepath) => {
24
+ renamedFiles.set(filepath, replaces.reduce((p, c) => p.replace(c.regexp, c.replacement), content));
25
+ });
26
+ return renamedFiles;
27
+ }
28
+ function getReplaceRegex(search, replacement) {
21
29
  // The current regex works if the old Id is contained in the new Id, given
22
30
  // that they do not have the same beginning.
23
31
  // more complete alternative: /((?<!newIdStart)|(?!newIdEnd))oldId/g
@@ -34,7 +42,7 @@ export function renameResources(files, search, replacement) {
34
42
  escapedSearch = escapeRegex(search);
35
43
  }
36
44
  const dotToSlash = (update) => update.replaceAll(".", "\/");
37
- const replaces = [
45
+ return [
38
46
  {
39
47
  regexp: new RegExp(escapedSearch, "g"),
40
48
  replacement
@@ -44,10 +52,10 @@ export function renameResources(files, search, replacement) {
44
52
  replacement: dotToSlash(replacement)
45
53
  }
46
54
  ];
47
- files.forEach((content, filepath, map) => {
48
- map.set(filepath, replaces.reduce((p, c) => p.replace(c.regexp, c.replacement), content));
49
- });
50
- return files;
55
+ }
56
+ export function rename(content, search, replacement) {
57
+ const replaces = getReplaceRegex(search, replacement);
58
+ return replaces.reduce((p, c) => p.replace(c.regexp, c.replacement), content);
51
59
  }
52
60
  export function insertInArray(array, index, insert) {
53
61
  array.splice(index, 0, insert);
@@ -64,9 +72,8 @@ export function writeTempAnnotations({ writeTempFiles }, name, language, content
64
72
  fs.writeFileSync(path.join(TEMP_DIST_FOLDER, name + ".xml"), content);
65
73
  }
66
74
  }
67
- export function removePropertiesExtension(filePath) {
68
- const lastIndexOf = filePath.lastIndexOf(".properties");
69
- return filePath.substring(0, lastIndexOf);
75
+ export function trimExtension(filePath) {
76
+ return filePath.replace(/\.[^/.]+$/, "");
70
77
  }
71
78
  export function traverse(json, paths, callback) {
72
79
  if (!json) {
@@ -101,8 +108,9 @@ export function logBuilderVersion() {
101
108
  const packageJson = fs.readFileSync(path.join(__dirname, "../../package.json"), { encoding: "utf-8" });
102
109
  const packageJsonVersion = JSON.parse(packageJson).version;
103
110
  log.info(`Running app-variant-bundler-build with version ${packageJsonVersion}`);
111
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
104
112
  }
105
- catch (_error) {
113
+ catch (e) {
106
114
  // do nothing
107
115
  }
108
116
  }
@@ -1,12 +1,19 @@
1
- import * as Resource from "@ui5/fs/Resource";
2
- import { IAppVariantInfo } from "../model/types.js";
3
- type Resource = typeof Resource;
4
- export default class I18NMerger {
5
- static analyzeAppVariantManifestChanges(rootFolder: string, tranlsationRegexPattern: string, { changes }: IAppVariantInfo): {
6
- mergePathsRegex: RegExp[];
7
- copyPathsRegex: RegExp[];
1
+ import AppVariant from "../appVariantManager.js";
2
+ import { IChange } from "../model/types.js";
3
+ export default class FileMerger {
4
+ static analyzeAppVariantManifestChanges(manifestChanges: ReadonlyArray<IChange>): {
5
+ mergePaths: RegExp[];
6
+ copyPaths: RegExp[];
8
7
  };
9
- static mergeI18NFiles(baseAppResources: any[], appVariantResources: any[], projectNamespace: string, baseAppManifestI18NPath: string, appVariantInfo: IAppVariantInfo, taskUtil: any): Promise<(typeof Resource)[]>;
8
+ static merge(baseAppFiles: ReadonlyMap<string, string>, i18nPath: string, appVariant: AppVariant): Map<string, string>;
9
+ /**
10
+ * Filters out specific lines from the given string.
11
+ * Removes lines matching:
12
+ * - __ldi.translation.uuid\s*=\s*(.*)
13
+ * - ABAP_TRANSLATION
14
+ * - SAPUI5 TRANSLATION-KEY
15
+ */
16
+ private static filterTranslationMetaLines;
10
17
  /**
11
18
  * Merge/Append base property file with property file from app variant
12
19
  * FIXME Currently merge could duplicate keys which causes undefined
@@ -16,16 +23,4 @@ export default class I18NMerger {
16
23
  * existing overwritten keys (as there should be none)
17
24
  */
18
25
  private static mergePropertiesFiles;
19
- /**
20
- * update the path of app variant property file so it will be copied into
21
- <app_variant_id> folder
22
- */
23
- private static moveToAppVarSubfolder;
24
- /**
25
- * create new i18n file in case e.g. translation file does not exist in base
26
- * app but in variant and copy of translation file is needed
27
- */
28
- private static createFile;
29
- private static mergeFiles;
30
26
  }
31
- export {};
@@ -1,19 +1,18 @@
1
- import { dotToUnderscore, escapeRegex, removePropertiesExtension } from "./commonUtil.js";
2
- import ResourceUtil from "./resourceUtil.js";
1
+ import { dotToUnderscore, escapeRegex, trimExtension } from "./commonUtil.js";
3
2
  import { posix as path } from "path";
4
- export default class I18NMerger {
5
- static analyzeAppVariantManifestChanges(rootFolder, tranlsationRegexPattern, { changes }) {
3
+ export default class FileMerger {
4
+ static analyzeAppVariantManifestChanges(manifestChanges) {
6
5
  // check which files need to be copied and which files need to be merged and copied
7
6
  // this is necessary because lrep does not support multiple enhanceWith with multiple locations
7
+ const TRANSLATION_REGEX_PATTERN = "((_[a-z]{2,3})?(_[a-zA-Z]{2,3}(_[a-zA-Z]{2,20})?)?)\.properties$";
8
8
  const mergePaths = new Set();
9
9
  const copyPaths = new Set();
10
- changes.forEach((change) => {
10
+ manifestChanges.forEach((change) => {
11
11
  const i18nPathWithExtension = change.content?.bundleUrl || change.texts?.i18n;
12
12
  if (i18nPathWithExtension) {
13
13
  // build regex to match specific + language related files
14
- const i18nPath = removePropertiesExtension(i18nPathWithExtension);
15
- const resourcePath = path.join(rootFolder, i18nPath);
16
- const regex = new RegExp(escapeRegex(resourcePath) + tranlsationRegexPattern);
14
+ const i18nPath = trimExtension(i18nPathWithExtension);
15
+ const regex = new RegExp("^" + escapeRegex(i18nPath) + TRANSLATION_REGEX_PATTERN);
17
16
  if (change.changeType.includes("addNewModelEnhanceWith")) {
18
17
  copyPaths.add(regex);
19
18
  }
@@ -22,36 +21,44 @@ export default class I18NMerger {
22
21
  }
23
22
  }
24
23
  });
25
- return { mergePathsRegex: [...mergePaths.values()], copyPathsRegex: [...copyPaths.values()] };
24
+ return { mergePaths: Array.from(mergePaths), copyPaths: Array.from(copyPaths) };
26
25
  }
27
- static async mergeI18NFiles(baseAppResources, appVariantResources, projectNamespace, baseAppManifestI18NPath, appVariantInfo, taskUtil) {
28
- const aggregatedResourceFilesMap = new Map(baseAppResources.map(baseAppResource => [baseAppResource.getPath(), baseAppResource]));
29
- const i18nTargetFolder = dotToUnderscore(appVariantInfo.id);
30
- const rootFolder = ResourceUtil.getRootFolder(projectNamespace);
31
- const tranlsationRegexPattern = "((_[a-z]{2,3})?(_[a-zA-Z]{2,3}(_[a-zA-Z]{2,20})?)?)\.properties$";
32
- const { copyPathsRegex: copyPathsValues, mergePathsRegex: mergePathsValues } = this.analyzeAppVariantManifestChanges(rootFolder, tranlsationRegexPattern, appVariantInfo);
33
- for (const appVariantResource of appVariantResources) {
34
- const appVariantResourcePath = appVariantResource.getPath();
35
- if (appVariantResourcePath.endsWith(".properties")) {
26
+ static merge(baseAppFiles, i18nPath, appVariant) {
27
+ const i18nTargetFolder = dotToUnderscore(appVariant.id);
28
+ const { copyPaths, mergePaths } = this.analyzeAppVariantManifestChanges(appVariant.getProcessedManifestChanges());
29
+ const files = new Map(baseAppFiles);
30
+ for (const [filename, content] of Array.from(appVariant.getProcessedFiles())) {
31
+ if (filename.endsWith(".properties")) {
36
32
  // merge/copy logic
37
33
  // check if file matches with regex in merge/copy
38
- const mergePathMatch = mergePathsValues.map(path => appVariantResourcePath.match(path)).find(match => match);
39
- const shouldMergeFile = !!mergePathMatch;
40
- const shouldCopyFile = copyPathsValues.map(path => appVariantResourcePath.match(path)).find(match => match);
41
- if (shouldMergeFile) {
42
- let baseAppI18NPath = `${rootFolder}/${baseAppManifestI18NPath}${mergePathMatch[1] || ""}.properties`;
43
- await this.mergePropertiesFiles(aggregatedResourceFilesMap, appVariantResource, baseAppI18NPath);
34
+ const mergePathMatch = mergePaths.map(path => filename.match(path)).find(match => match);
35
+ const copyPathMatch = copyPaths.map(path => filename.match(path)).find(match => match);
36
+ if (mergePathMatch) {
37
+ this.mergePropertiesFiles(files, i18nPath, content, mergePathMatch[1]);
44
38
  }
45
- // Resource for to be copied file already exists so we only have to adjust path
46
- // Otherwise we have to omit it. We always change the path to avoid omitting a base app file
47
- this.moveToAppVarSubfolder(appVariantResource, rootFolder, i18nTargetFolder);
48
- if (!shouldCopyFile) {
49
- taskUtil.setTag(appVariantResource, taskUtil.STANDARD_TAGS.OmitFromBuildResult, true);
39
+ if (copyPathMatch) {
40
+ files.set(path.join(i18nTargetFolder, filename), content);
50
41
  }
51
42
  }
52
- aggregatedResourceFilesMap.set(appVariantResource.getPath(), appVariantResource);
43
+ else {
44
+ files.set(filename, content);
45
+ }
53
46
  }
54
- return Array.from(aggregatedResourceFilesMap.values());
47
+ return files;
48
+ }
49
+ /**
50
+ * Filters out specific lines from the given string.
51
+ * Removes lines matching:
52
+ * - __ldi.translation.uuid\s*=\s*(.*)
53
+ * - ABAP_TRANSLATION
54
+ * - SAPUI5 TRANSLATION-KEY
55
+ */
56
+ static filterTranslationMetaLines(content) {
57
+ const lines = content.split('\n');
58
+ const filtered = lines.filter(line => !/^# __ldi\.translation\.uuid\s*=/.test(line) &&
59
+ !line.startsWith("# ABAP_TRANSLATION") &&
60
+ !line.startsWith("# SAPUI5 TRANSLATION-KEY"));
61
+ return filtered.join('\n');
55
62
  }
56
63
  /**
57
64
  * Merge/Append base property file with property file from app variant
@@ -61,39 +68,14 @@ export default class I18NMerger {
61
68
  * app variant Id as prefix => If we filter on them we do not need to remove
62
69
  * existing overwritten keys (as there should be none)
63
70
  */
64
- static async mergePropertiesFiles(aggregatedResourceFilesMap, variantResource, baseAppI18NPath) {
65
- const baseAppI18NFile = aggregatedResourceFilesMap.get(baseAppI18NPath);
66
- if (baseAppI18NFile) {
67
- await this.mergeFiles(baseAppI18NFile, variantResource);
68
- }
69
- else {
70
- // create the merge target file if it missing in base app. Maybe the language does not exist in the base app.
71
- // Since the file might also be copied we do not just change the path of it but create another resource
72
- await this.createFile(aggregatedResourceFilesMap, baseAppI18NPath, variantResource);
73
- }
74
- }
75
- /**
76
- * update the path of app variant property file so it will be copied into
77
- <app_variant_id> folder
78
- */
79
- static moveToAppVarSubfolder(variantResource, rootFolder, i18nBundleName) {
80
- const relativeFilePath = variantResource.getPath().substring(rootFolder.length);
81
- const newResourcePath = path.join(rootFolder, i18nBundleName, relativeFilePath);
82
- variantResource.setPath(newResourcePath);
83
- }
84
- /**
85
- * create new i18n file in case e.g. translation file does not exist in base
86
- * app but in variant and copy of translation file is needed
87
- */
88
- static async createFile(aggregatedResourceFilesMap, path, resource) {
89
- const createdFile = await resource.clone();
90
- createdFile.setPath(path);
91
- aggregatedResourceFilesMap.set(path, createdFile);
92
- }
93
- static async mergeFiles(baseFile, variantFile) {
94
- const variantFileContent = await variantFile.getString();
95
- const mergedFileContent = await baseFile.getString();
96
- baseFile.setString(`${mergedFileContent}\n\n#App variant specific text file\n\n${variantFileContent}`);
71
+ static mergePropertiesFiles(files, i18nPath, appVariantFileContent, language = "") {
72
+ const baseAppI18nPath = i18nPath + language + ".properties";
73
+ const baseAppFileContent = files.get(baseAppI18nPath);
74
+ const filteredBaseContent = baseAppFileContent ? this.filterTranslationMetaLines(baseAppFileContent) : "";
75
+ const content = filteredBaseContent
76
+ ? `${filteredBaseContent}\n\n#App variant specific text file\n\n${appVariantFileContent}`
77
+ : appVariantFileContent;
78
+ files.set(baseAppI18nPath, content);
97
79
  }
98
80
  }
99
81
  //# sourceMappingURL=i18nMerger.js.map
@@ -3,9 +3,11 @@ export default class ResourceUtil {
3
3
  static relativeToRoot(resourcePath: string, projectNamespace?: string): string;
4
4
  static getResourcePath(projectNamespace?: string, ...paths: string[]): string;
5
5
  static write(dir: string, files: Map<string, string>): Promise<void[]>;
6
- static read(rootFolder: string, folder: string, files: Map<string, string>, exclude?: string[]): void;
6
+ private static _read;
7
+ static read(folder: string): Map<string, string>;
7
8
  static getString(resource: any): Promise<string>;
8
9
  static getJson(resource: any): Promise<any>;
9
10
  static setString(resource: any, str: string): void;
10
11
  static createResource(filename: string, projectNamespace: string, content: string): any;
12
+ static toFileMap(resources: ReadonlyArray<Resource>, projectNamespace: string): Promise<Map<string, string>>;
11
13
  }
@@ -29,7 +29,7 @@ export default class ResourceUtil {
29
29
  });
30
30
  return Promise.all(promises);
31
31
  }
32
- static read(rootFolder, folder, files, exclude = []) {
32
+ static _read(rootFolder, folder, files, exclude = []) {
33
33
  const entries = fs.readdirSync(folder);
34
34
  for (let entry of entries) {
35
35
  const entryPath = path.join(folder, entry);
@@ -39,10 +39,15 @@ export default class ResourceUtil {
39
39
  files.set(normalized, fs.readFileSync(entryPath, { encoding: "utf-8" }));
40
40
  }
41
41
  else if (stats.isDirectory()) {
42
- this.read(rootFolder, entryPath, files, exclude);
42
+ this._read(rootFolder, entryPath, files, exclude);
43
43
  }
44
44
  }
45
45
  }
46
+ static read(folder) {
47
+ const files = new Map();
48
+ this._read(folder, folder, files);
49
+ return files;
50
+ }
46
51
  static getString(resource) {
47
52
  return resource.getBuffer().then((buffer) => buffer.toString(UTF8));
48
53
  }
@@ -58,5 +63,13 @@ export default class ResourceUtil {
58
63
  string: content
59
64
  });
60
65
  }
66
+ static async toFileMap(resources, projectNamespace) {
67
+ const files = new Map();
68
+ const rootFolderLength = ResourceUtil.getRootFolder(projectNamespace).length;
69
+ for (const resource of resources) {
70
+ files.set(resource.getPath().substring(rootFolderLength + 1), await ResourceUtil.getString(resource));
71
+ }
72
+ return files;
73
+ }
61
74
  }
62
75
  //# sourceMappingURL=resourceUtil.js.map
package/eslint.config.js CHANGED
@@ -11,7 +11,7 @@ export default tseslint.config(
11
11
  parserOptions: {
12
12
  project: [
13
13
  "./tsconfig.json",
14
- "./test/tsconfig.json",
14
+ "./test/lib/tsconfig.json",
15
15
  "./scripts/tsconfig.json"
16
16
  ],
17
17
  tsconfigRootDir: import.meta.dirname,
@@ -64,8 +64,5 @@ export default tseslint.config(
64
64
  rules: {
65
65
  "@typescript-eslint/no-unused-expressions": "off"
66
66
  },
67
- },
68
- {
69
- ignores: ["test/resources/**"]
70
67
  }
71
- );
68
+ );
package/package.json CHANGED
@@ -1,12 +1,14 @@
1
1
  {
2
2
  "name": "@ui5/task-adaptation",
3
- "version": "1.4.3",
3
+ "version": "1.5.1",
4
4
  "description": "Custom task for ui5-builder which allows building UI5 Flexibility Adaptation Projects for SAP BTP, Cloud Foundry environment",
5
5
  "main": "index.js",
6
6
  "scripts": {
7
7
  "test": "npm run lint && npm run build && npm run coverage",
8
- "lint": "eslint ./src ./test",
9
- "dev": "UI5_LOG_LVL=error mocha --no-timeouts --no-warnings --import=tsx --loader=esmock 'test/**/*.spec.ts'",
8
+ "lint": "eslint ./src ./test/lib",
9
+ "dev": "UI5_LOG_LVL=error mocha --no-timeouts --no-warnings --import=tsx --loader=esmock 'test/lib/**/*.spec.ts'",
10
+ "perf": "UI5_LOG_LVL=error mocha --no-timeouts --no-warnings --import=tsx --loader=esmock 'test/lib/**/*.perf.ts'",
11
+ "integration": "UI5_LOG_LVL=error mocha --reporter-option maxDiffSize=0 --no-timeouts --no-warnings --import=tsx --loader=esmock 'test/lib/**/*.int.ts'",
10
12
  "coverage": "c8 npm run dev",
11
13
  "preversion": "npm test",
12
14
  "version": "git-chglog --next-tag v$npm_package_version -o CHANGELOG.md && git add CHANGELOG.md",
@@ -43,9 +45,10 @@
43
45
  "axios": "^1.8.3",
44
46
  "crc": "^4.3.2",
45
47
  "dotenv": "^16.0.3",
48
+ "filenamify": "^6.0.0",
46
49
  "jsdom": "^23.0.1",
47
- "meriyah": "^6.0.3",
48
50
  "temp-dir": "^2.0.0",
51
+ "transliteration": "^2.3.5",
49
52
  "xml-js": "^1.6.11"
50
53
  },
51
54
  "devDependencies": {
@@ -60,19 +63,19 @@
60
63
  "@types/mocha": "^9.1.0",
61
64
  "@types/semver": "^7.3.8",
62
65
  "@types/sinon": "^10.0.16",
66
+ "@ui5/builder": "^4.0.3",
63
67
  "@ui5/project": "^4.0.3",
64
68
  "amdextract": "^3.0.0",
65
69
  "builtin-modules": "^3.2.0",
66
70
  "c8": "^10.1.3",
67
71
  "chai": "^4.3.4",
68
72
  "chai-as-promised": "^7.1.1",
69
- "chalk": "^4.1.2",
70
73
  "eslint": "^9.22.0",
71
74
  "eslint-plugin-import": "^2.31.0",
72
75
  "esmock": "^2.6.3",
73
76
  "glob": "^10.3.10",
74
77
  "js-yaml": "^4.1.0",
75
- "lodash": "^4.17.21",
78
+ "meriyah": "^6.0.3",
76
79
  "minimatch": "^9.0.3",
77
80
  "mocha": "^11.1.0",
78
81
  "mock-require": "^3.0.3",
@@ -84,9 +87,6 @@
84
87
  "typescript": "^5.4.2",
85
88
  "typescript-eslint": "^8.26.1"
86
89
  },
87
- "optionalDependencies": {
88
- "@rollup/rollup-linux-x64-gnu": "4.39.0"
89
- },
90
90
  "c8": {
91
91
  "src": "./src",
92
92
  "all": true,
@@ -110,7 +110,8 @@
110
110
  "*/**/*.d.ts",
111
111
  "src/annotations/comparator/diffCase.ts",
112
112
  "src/annotations/transformers/transformer.ts",
113
- "src/model/configuration.ts"
113
+ "src/model/configuration.ts",
114
+ "src/model/appVariantIdHierarchyItem.ts"
114
115
  ],
115
116
  "check-coverage": true,
116
117
  "statements": 85,
@@ -119,5 +120,9 @@
119
120
  "lines": 85
120
121
  },
121
122
  "types": "dist/index.d.ts",
122
- "type": "module"
123
+ "type": "module",
124
+ "optionalDependencies": {
125
+ "@rollup/rollup-linux-x64-gnu": "^4.28.1",
126
+ "@rollup/rollup-linux-x64-musl": "^4.28.1"
127
+ }
123
128
  }
package/types/ui5.d.ts CHANGED
@@ -18,6 +18,11 @@ declare class Resource {
18
18
  setString(string: string): void;
19
19
  }
20
20
 
21
+ declare interface IWorkspace {
22
+ write(resource: Resource): Promise<void>;
23
+ byGlob(pattern: string): Promise<Resource[]>;
24
+ }
25
+
21
26
  declare module "@ui5/fs/Resource" {
22
27
  export function getPath(): string;
23
28
  export function clone(): Resource;
@@ -39,6 +44,11 @@ declare module "@ui5/project/build/helpers/BuildContext" {
39
44
 
40
45
  declare module "@ui5/project/build/helpers/TaskUtil" {
41
46
  export default class TaskUtil {
47
+ STANDARD_TAGS: any;
48
+ setTag(resource: Resource, OmitFromBuildResult: any, omit: boolean);
42
49
  constructor(options: any);
43
50
  }
44
51
  }
52
+
53
+ declare module "@ui5/builder/internal/taskRepository" {
54
+ }
@@ -1,8 +0,0 @@
1
- import CacheManager from "./cacheManager.js";
2
- import { IConfiguration } from "../model/types.js";
3
- export default class AnnotationsCacheManager extends CacheManager {
4
- private tempSubFolder;
5
- constructor(configuration: IConfiguration, tempSubFolder: string);
6
- protected getTempId(): string;
7
- getMetadataFilename(): string;
8
- }
@@ -1,16 +0,0 @@
1
- import CacheManager from "./cacheManager.js";
2
- export default class AnnotationsCacheManager extends CacheManager {
3
- tempSubFolder;
4
- constructor(configuration, tempSubFolder) {
5
- super(configuration);
6
- this.tempSubFolder = tempSubFolder;
7
- }
8
- getTempId() {
9
- const { destination, appName } = this.configuration;
10
- return super.normalizeId(`ui5-${destination}-${appName}-${this.tempSubFolder}`);
11
- }
12
- getMetadataFilename() {
13
- return "annotationsmetadata.json";
14
- }
15
- }
16
- //# sourceMappingURL=annotationsCacheManager.js.map
@@ -1,6 +0,0 @@
1
- import CacheManager from "./cacheManager.js";
2
- export default class BaseAppFilesCacheManager extends CacheManager {
3
- static METADATA_FILENAME: string;
4
- protected getTempId(): string;
5
- getMetadataFilename(): string;
6
- }
@@ -1,12 +0,0 @@
1
- import CacheManager from "./cacheManager.js";
2
- export default class BaseAppFilesCacheManager extends CacheManager {
3
- static METADATA_FILENAME = "html5metadata.json";
4
- getTempId() {
5
- const { appHostId, appName, appVersion } = this.configuration;
6
- return super.normalizeId(`ui5-${appHostId}-${appName}-${appVersion}`);
7
- }
8
- getMetadataFilename() {
9
- return BaseAppFilesCacheManager.METADATA_FILENAME;
10
- }
11
- }
12
- //# sourceMappingURL=baseAppFilesCacheManager.js.map
@@ -1,16 +0,0 @@
1
- import { IConfiguration, IMetadata } from "../model/types.js";
2
- export default abstract class CacheManager {
3
- protected configuration: IConfiguration;
4
- constructor(configuration: IConfiguration);
5
- protected abstract getMetadataFilename(): string;
6
- protected abstract getTempId(): string;
7
- protected getTempFolder(): string;
8
- getFiles(fetchMetadata: () => Promise<IMetadata>, fetchFiles: () => Promise<Map<string, string>>): Promise<Map<string, string>>;
9
- isMetadataSame(tempMetadata: IMetadata, metadata: IMetadata): boolean;
10
- readTempMetadata(): any;
11
- writeTemp(files: Map<string, string>, metadata: any): Promise<void[]>;
12
- readTemp(): Promise<Map<string, string>>;
13
- deleteTemp(): void;
14
- protected normalizeId(id: string): string;
15
- private getFilesToCache;
16
- }