@ui5/task-adaptation 1.1.0 → 1.1.2

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 (80) hide show
  1. package/CHANGELOG.md +9 -1
  2. package/README.md +1 -1
  3. package/dist/annotationManager.d.ts +0 -3
  4. package/dist/annotationManager.js +8 -43
  5. package/dist/annotations/comparator/comparator.d.ts +47 -0
  6. package/dist/annotations/comparator/comparator.js +276 -0
  7. package/dist/annotations/comparator/diffCase.d.ts +4 -0
  8. package/dist/annotations/comparator/diffCase.js +3 -0
  9. package/dist/annotations/comparator/interchangableCase.d.ts +25 -0
  10. package/dist/annotations/comparator/interchangableCase.js +65 -0
  11. package/dist/annotations/converter/metadataJsonReferenceUtil.d.ts +12 -0
  12. package/dist/annotations/converter/metadataJsonReferenceUtil.js +50 -0
  13. package/dist/annotations/converter/metadataJsonUtil.d.ts +30 -0
  14. package/dist/annotations/converter/metadataJsonUtil.js +73 -0
  15. package/dist/annotations/converter/ui5JsonConverter.d.ts +21 -0
  16. package/dist/annotations/converter/ui5JsonConverter.js +253 -0
  17. package/dist/annotations/converter/ui5MetadataJsonUtil.d.ts +3 -0
  18. package/dist/annotations/converter/ui5MetadataJsonUtil.js +13 -0
  19. package/dist/annotations/converter/ui5XmlConverter.d.ts +5 -0
  20. package/dist/annotations/converter/ui5XmlConverter.js +17 -0
  21. package/dist/annotations/dataSource/dataSource.d.ts +34 -0
  22. package/dist/annotations/dataSource/dataSource.js +62 -0
  23. package/dist/annotations/dataSource/dataSourceManager.d.ts +13 -0
  24. package/dist/annotations/dataSource/dataSourceManager.js +58 -0
  25. package/dist/annotations/dataSource/dataSourceOData.d.ts +17 -0
  26. package/dist/annotations/dataSource/dataSourceOData.js +47 -0
  27. package/dist/annotations/dataSource/dataSourceODataAnnotation.d.ts +6 -0
  28. package/dist/annotations/dataSource/dataSourceODataAnnotation.js +14 -0
  29. package/dist/annotations/dataSource/dataSourceODataAnnotationBeta.d.ts +6 -0
  30. package/dist/annotations/dataSource/dataSourceODataAnnotationBeta.js +18 -0
  31. package/dist/annotations/serviceRequestor.d.ts +1 -9
  32. package/dist/annotations/serviceRequestor.js +52 -17
  33. package/dist/annotations/transformers/convertV2ToV4.d.ts +4 -0
  34. package/dist/annotations/transformers/convertV2ToV4.js +16 -0
  35. package/dist/annotations/transformers/makeAnnotationNamespaceUnique.d.ts +6 -0
  36. package/dist/annotations/transformers/makeAnnotationNamespaceUnique.js +44 -0
  37. package/dist/annotations/transformers/removeAllSchemaNodesExceptAnnotations.d.ts +4 -0
  38. package/dist/annotations/transformers/removeAllSchemaNodesExceptAnnotations.js +17 -0
  39. package/dist/annotations/transformers/transformer.d.ts +12 -0
  40. package/dist/annotations/transformers/transformer.js +3 -0
  41. package/dist/annotations/transformers/traverseReferences.d.ts +9 -0
  42. package/dist/annotations/transformers/traverseReferences.js +67 -0
  43. package/dist/appVariantManager.d.ts +4 -2
  44. package/dist/appVariantManager.js +44 -18
  45. package/dist/baseAppManager.d.ts +2 -1
  46. package/dist/baseAppManager.js +26 -31
  47. package/dist/bundle-odata.js +5498 -0
  48. package/dist/bundle.js +1786 -13
  49. package/dist/i18nManager.d.ts +5 -7
  50. package/dist/i18nManager.js +29 -32
  51. package/dist/index.js +4 -3
  52. package/dist/model/annotationDiffStructureError.js +2 -0
  53. package/dist/model/language.js +1 -1
  54. package/dist/model/serverError.d.ts +3 -0
  55. package/dist/model/serverError.js +9 -0
  56. package/dist/model/types.d.ts +13 -2
  57. package/dist/repositories/abapRepoManager.js +2 -2
  58. package/dist/util/commonUtil.d.ts +7 -0
  59. package/dist/util/commonUtil.js +72 -18
  60. package/dist/util/i18nMerger.d.ts +1 -1
  61. package/dist/util/i18nMerger.js +3 -4
  62. package/dist/util/requestUtil.js +4 -0
  63. package/dist/util/resourceUtil.d.ts +3 -0
  64. package/dist/util/resourceUtil.js +14 -1
  65. package/dist/util/urlUtil.d.ts +4 -0
  66. package/dist/util/urlUtil.js +21 -0
  67. package/package.json +9 -6
  68. package/scripts/bundler.ts +4 -33
  69. package/scripts/metadataDownloadHelper.ts +7 -5
  70. package/scripts/rollup/bundleDefinition-odata.js +9 -0
  71. package/scripts/rollup/overrides/sap/ui/performance/Measurement.js +4 -0
  72. package/scripts/rollup/ui5Resolve.ts +34 -5
  73. package/scripts/rollup.ts +12 -3
  74. package/dist/annotations/oDataModel.d.ts +0 -20
  75. package/dist/annotations/oDataModel.js +0 -46
  76. package/dist/annotations/oDataV2Model.d.ts +0 -4
  77. package/dist/annotations/oDataV2Model.js +0 -13
  78. package/dist/util/jsonDiffUtil.d.ts +0 -28
  79. package/dist/util/jsonDiffUtil.js +0 -74
  80. package/scripts/rollup/overrides/sap/ui/thirdparty/URI.js +0 -16
@@ -1,4 +1,5 @@
1
- import { IDiffProperty, IJsonContent } from "./util/jsonDiffUtil";
1
+ import { IDiffProperty } from "./annotations/comparator/comparator";
2
+ import { IJsonPerLanguage, IJsonPromisePerLanguage } from "./model/types";
2
3
  import Language from "./model/language";
3
4
  export declare class PropertyValue {
4
5
  value: string;
@@ -31,12 +32,9 @@ export default class I18nManager {
31
32
  constructor(modelName: string, appVariantId: string, languages: Language[]);
32
33
  processDiff(properties: Set<IDiffProperty>, previousLanguage: Language, currentLanguage: Language): void;
33
34
  createFiles(i18nPathName: string): Map<string, string>;
34
- populateTranslations(annotationJsons: Map<Language, any>): IJsonContent;
35
- populate(annotationJsons: [Language, any][], defaultAnnotation: IJsonContent): {
36
- language: Language;
37
- json: any;
38
- };
39
- static extractDefaultLanguageAnnotation(annotationJsons: Map<Language, any>): IJsonContent;
35
+ populateTranslations(annotationJsons: Map<Language, Promise<any>>): Promise<IJsonPromisePerLanguage>;
36
+ populate(annotationJsons: [Language, Promise<any>][], defaultAnnotation: IJsonPerLanguage): Promise<IJsonPerLanguage>;
37
+ static extractDefaultLanguageAnnotation(annotationJsons: Map<Language, Promise<any>>): IJsonPromisePerLanguage;
40
38
  private replaceWithModelReference;
41
39
  private createReference;
42
40
  getUniqueKeyForValue(value: string): string;
@@ -1,8 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.I18nFileContent = exports.PropertyValue = void 0;
4
- const jsonDiffUtil_1 = require("./util/jsonDiffUtil");
4
+ const comparator_1 = require("./annotations/comparator/comparator");
5
5
  const annotationDiffStructureError_1 = require("./model/annotationDiffStructureError");
6
+ const commonUtil_1 = require("./util/commonUtil");
6
7
  const posix_1 = require("path/posix"); // Ensure standardized dir separators to ensure Windows compatibility
7
8
  // To generate keys, english language is more common, so compare all other
8
9
  // languages with it
@@ -103,7 +104,7 @@ class I18nManager {
103
104
  createFiles(i18nPathName) {
104
105
  return this.i18nFileContent.createFiles(i18nPathName);
105
106
  }
106
- populateTranslations(annotationJsons) {
107
+ async populateTranslations(annotationJsons) {
107
108
  /* We compare annotations. Diff gives us:
108
109
  {
109
110
  "string": {
@@ -127,26 +128,27 @@ class I18nManager {
127
128
  and so on */
128
129
  let defaultAnnotation = I18nManager.extractDefaultLanguageAnnotation(annotationJsons);
129
130
  if (annotationJsons.size > 0 && defaultAnnotation) {
130
- defaultAnnotation = this.populate([...annotationJsons], defaultAnnotation);
131
+ defaultAnnotation = await this.populate([...annotationJsons], defaultAnnotation);
131
132
  }
132
133
  return defaultAnnotation;
133
134
  }
134
- populate(annotationJsons, defaultAnnotation) {
135
- return annotationJsons
136
- .map(([language, json]) => ({ language, json }))
137
- .reduce((p, c) => {
135
+ async populate(annotationJsons, defaultAnnotation) {
136
+ let p = defaultAnnotation;
137
+ for (const c of annotationJsons.map(([language, json]) => ({ language, json }))) {
138
138
  try {
139
- const pDiff = jsonDiffUtil_1.default.diff(p.json, c.json);
139
+ const comparator = new comparator_1.default(await p.json, await c.json);
140
+ const pDiff = comparator.compare();
140
141
  this.processDiff(pDiff.properties, p.language, c.language);
141
- return { json: pDiff.json, language: p.language };
142
+ p.json = pDiff.json;
142
143
  }
143
144
  catch (error) {
144
145
  if (error instanceof annotationDiffStructureError_1.default) {
145
- throw new Error(`The structure of the oData annotation xml of language '${p.language.sap}' is different from xml of language '${c.language.sap}' near element: ${error.message}`);
146
+ throw new Error(`The structure of the OData annotation xml of language '${p.language}' is different from xml of language '${c.language}' near element: ${error.message}`);
146
147
  }
147
148
  throw error;
148
149
  }
149
- }, defaultAnnotation);
150
+ }
151
+ return p;
150
152
  }
151
153
  static extractDefaultLanguageAnnotation(annotationJsons) {
152
154
  let json = null;
@@ -161,20 +163,18 @@ class I18nManager {
161
163
  annotationJsons.delete(language);
162
164
  return { json, language };
163
165
  }
164
- replaceWithModelReference({ object, property, type }, propertyValues) {
165
- if (type === jsonDiffUtil_1.DiffTypeEnum.DELTA) {
166
- const diff = object[property];
167
- this.initPropertyValues(diff, propertyValues);
168
- // If there are already generated key, like on step 3. above comment, we
169
- // take it (from __old), so we don't need to generate new
170
- const propReference = propertyValues.find(prop => prop.isReference);
171
- let reference = propReference?.value ?? this.createReference(diff.__old);
172
- object[property] = reference;
173
- // Other values, which are not references, are extracted to .properties
174
- const key = this.references.get(reference);
175
- if (key) {
176
- propertyValues.filter(prop => !prop.isReference).forEach(prop => this.i18nFileContent.add(prop, key));
177
- }
166
+ replaceWithModelReference({ object, property }, propertyValues) {
167
+ const diff = object[property];
168
+ this.initPropertyValues(diff, propertyValues);
169
+ // If there are already generated key, like on step 3. above comment, we
170
+ // take it (from __old), so we don't need to generate new
171
+ const propReference = propertyValues.find(prop => prop.isReference);
172
+ let reference = propReference?.value ?? this.createReference(diff.__old);
173
+ object[property] = reference;
174
+ // Other values, which are not references, are extracted to .properties
175
+ const key = this.references.get(reference);
176
+ if (key) {
177
+ propertyValues.filter(prop => !prop.isReference).forEach(prop => this.i18nFileContent.add(prop, key));
178
178
  }
179
179
  }
180
180
  createReference(value) {
@@ -184,14 +184,11 @@ class I18nManager {
184
184
  return reference;
185
185
  }
186
186
  getUniqueKeyForValue(value) {
187
+ if (typeof value !== "string") {
188
+ throw new Error("Failed to create unique key from: " + JSON.stringify(value));
189
+ }
187
190
  const propertyName = value.replace(/\W/gi, "_").toUpperCase();
188
- let suffix = -1;
189
- let suffixString;
190
- do {
191
- suffixString = suffix === -1 ? "" : suffix;
192
- suffix++;
193
- } while (this.existingKeys.has(propertyName + suffixString));
194
- const key = propertyName + suffixString;
191
+ const key = (0, commonUtil_1.getUniqueName)([...this.existingKeys.keys()], propertyName);
195
192
  this.existingKeys.add(key);
196
193
  return key;
197
194
  }
package/dist/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const dotenv = require("dotenv");
4
+ const commonUtil_1 = require("./util/commonUtil");
4
5
  const appVariantManager_1 = require("./appVariantManager");
5
6
  const baseAppManager_1 = require("./baseAppManager");
6
- const processor_1 = require("./processors/processor");
7
7
  const i18nMerger_1 = require("./util/i18nMerger");
8
- const commonUtil_1 = require("./util/commonUtil");
8
+ const processor_1 = require("./processors/processor");
9
9
  /**
10
10
  * Creates an appVariant bundle from the provided resources.
11
11
  */
@@ -13,8 +13,9 @@ module.exports = ({ workspace, options, taskUtil }) => {
13
13
  dotenv.config();
14
14
  async function process(workspace, taskUtil) {
15
15
  await (0, commonUtil_1.logBuilderVersion)();
16
+ (0, commonUtil_1.logBetaUsage)();
16
17
  const processor = (0, processor_1.determineProcessor)(options.configuration);
17
- const appVariantResources = await appVariantManager_1.default.getAppVariantResources(workspace);
18
+ const appVariantResources = await appVariantManager_1.default.getAppVariantResourcesToProcess(workspace);
18
19
  const appVariantInfo = await appVariantManager_1.default.process(appVariantResources, options.projectNamespace, taskUtil);
19
20
  const baseAppFiles = await processor.getBaseAppFiles(appVariantInfo.reference);
20
21
  const { resources, manifestInfo } = await baseAppManager_1.default.process(baseAppFiles, appVariantInfo, options, processor);
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  class AnnotationDiffStructureError extends Error {
4
4
  constructor(json) {
5
5
  super(JSON.stringify(json));
6
+ this.name = "AnnotationDiffStructureError";
7
+ this.message = `The structure of the OData annotation xml is different near element: ${JSON.stringify(json)}`;
6
8
  }
7
9
  }
8
10
  exports.default = AnnotationDiffStructureError;
@@ -17,7 +17,7 @@ class Language {
17
17
  let configLanguages = [];
18
18
  if (languages !== undefined) {
19
19
  configLanguages = languages.map(item => {
20
- if (typeof item === 'string') {
20
+ if (typeof item === "string") {
21
21
  // For legacy language format support which is just a string and doesn't contain i18n
22
22
  return new Language(item, item.toLowerCase());
23
23
  }
@@ -0,0 +1,3 @@
1
+ export default class ServerError extends Error {
2
+ constructor(uri: string, error: any);
3
+ }
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ class ServerError extends Error {
4
+ constructor(uri, error) {
5
+ super(`Request ${uri} failed with Server error: ${error.response.status}${error.response.data ?? ""}`);
6
+ }
7
+ }
8
+ exports.default = ServerError;
9
+ //# sourceMappingURL=serverError.js.map
@@ -1,4 +1,6 @@
1
+ import Language from "./language";
1
2
  export interface IConfiguration {
3
+ writeTempFiles?: any;
2
4
  appHostId?: string;
3
5
  appId?: string;
4
6
  appName?: string;
@@ -11,6 +13,7 @@ export interface IConfiguration {
11
13
  type?: "cf" | "abap";
12
14
  languages?: any[] | undefined;
13
15
  enableAnnotationCache?: boolean;
16
+ enableBetaFeatures?: boolean;
14
17
  }
15
18
  export interface IProjectOptions {
16
19
  configuration: IConfiguration;
@@ -58,8 +61,8 @@ export interface IUaa {
58
61
  export interface IAppVariantInfo {
59
62
  id: string;
60
63
  reference: string;
61
- manifest: IAppVariantManifest;
62
- manifestChanges: Array<IChange>;
64
+ layer?: string;
65
+ changes: IChange[];
63
66
  }
64
67
  export interface IAppVariantManifest {
65
68
  id: string;
@@ -106,3 +109,11 @@ export interface IMetadata {
106
109
  export type KeyedMap<T, K extends keyof T, V> = {
107
110
  [k in K]: V;
108
111
  };
112
+ export interface IJsonPerLanguage {
113
+ language: Language;
114
+ json: any;
115
+ }
116
+ export interface IJsonPromisePerLanguage {
117
+ language: Language;
118
+ json: Promise<any>;
119
+ }
@@ -6,12 +6,12 @@ const log = require("@ui5/logger").getLogger("@ui5/task-adaptation::AbapRepoMana
6
6
  const REQUEST_OPTIONS_XML = {
7
7
  responseType: "text",
8
8
  headers: {
9
- "Content-Type": "text/xml"
9
+ "Accept": "text/html,application/xhtml+xml,application/xml"
10
10
  }
11
11
  };
12
12
  const REQUEST_OPTIONS_JSON = {
13
13
  headers: {
14
- "Content-Type": "application/json"
14
+ "Accept": "application/json"
15
15
  }
16
16
  };
17
17
  class AbapRepoManager {
@@ -1,6 +1,13 @@
1
+ import { IConfiguration } from "../model/types";
2
+ import Language from "../model/language";
1
3
  export declare function dotToUnderscore(value: string): string;
2
4
  export declare function validateObject<T extends Object>(options: T, properties: Array<keyof T>, message: string): void;
3
5
  export declare function escapeRegex(update: string): string;
4
6
  export declare function renameResources(files: Map<string, string>, search: string, replacement: string): Map<string, string>;
7
+ export declare function insertInArray<T>(array: T[], index: number, insert: T): void;
8
+ export declare function writeTempAnnotations({ writeTempFiles }: IConfiguration, name: string, language: Language, content: string): void;
5
9
  export declare function removePropertiesExtension(filePath: string): string;
10
+ export declare function traverse(json: any, paths: string[], callback: (json: any, key: string | number, paths: string[]) => void): void;
6
11
  export declare function logBuilderVersion(): Promise<void>;
12
+ export declare function logBetaUsage(): Promise<void>;
13
+ export declare function getUniqueName(existingNames: string[], template: string): string;
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.logBuilderVersion = exports.removePropertiesExtension = exports.renameResources = exports.escapeRegex = exports.validateObject = exports.dotToUnderscore = void 0;
3
+ exports.getUniqueName = exports.logBetaUsage = exports.logBuilderVersion = exports.traverse = exports.removePropertiesExtension = exports.writeTempAnnotations = exports.insertInArray = exports.renameResources = exports.escapeRegex = exports.validateObject = exports.dotToUnderscore = void 0;
4
+ const fs = require("fs");
5
+ const path_1 = require("path");
4
6
  const log = require("@ui5/logger").getLogger("rollup-plugin-ui5-resolve-task-adaptation");
5
7
  function dotToUnderscore(value) {
6
8
  return value.replace(/\./g, "_");
@@ -35,32 +37,70 @@ function renameResources(files, search, replacement) {
35
37
  escapedSearch = escapeRegex(search);
36
38
  }
37
39
  const dotToSlash = (update) => update.replaceAll(".", "\/");
38
- const replace = (content) => content.replace(new RegExp(escapedSearch, "g"), replacement);
39
- const replaceWithSlashesOnly = (content) => {
40
- if (!search.includes(".")) {
41
- return content;
40
+ const replaces = [
41
+ {
42
+ regexp: new RegExp(escapedSearch, "g"),
43
+ replacement
44
+ },
45
+ {
46
+ regexp: new RegExp(dotToSlash(escapedSearch), "g"),
47
+ replacement: dotToSlash(replacement)
42
48
  }
43
- let searchWithSlashes = dotToSlash(escapedSearch);
44
- return content.replace(new RegExp(searchWithSlashes, "g"), dotToSlash(replacement));
45
- };
46
- const renamed = new Map();
47
- files.forEach((content, filepath) => {
48
- // Finds the id with dots (test.id) or without dots (id) and replaces it
49
- content = replace(content);
50
- // Only if the id has dots, these dots will be replaced with slashes
51
- // first, and then it will search for the id with slashes and replace
52
- // with the appVariantId also with slashes
53
- content = replaceWithSlashesOnly(content);
54
- renamed.set(filepath, content);
49
+ ];
50
+ files.forEach((content, filepath, map) => {
51
+ map.set(filepath, replaces.reduce((p, c) => p.replace(c.regexp, c.replacement), content));
55
52
  });
56
- return renamed;
53
+ return files;
57
54
  }
58
55
  exports.renameResources = renameResources;
56
+ function insertInArray(array, index, insert) {
57
+ array.splice(index, 0, insert);
58
+ }
59
+ exports.insertInArray = insertInArray;
60
+ function writeTempAnnotations({ writeTempFiles }, name, language, content) {
61
+ const TEMP_DIST_FOLDER = path_1.posix.join(process.cwd(), "dist-debug", name);
62
+ if (writeTempFiles) {
63
+ if (!fs.existsSync(TEMP_DIST_FOLDER)) {
64
+ fs.mkdirSync(TEMP_DIST_FOLDER, { recursive: true });
65
+ }
66
+ if (language) {
67
+ name += "-" + language.i18n;
68
+ }
69
+ fs.writeFileSync(path_1.posix.join(TEMP_DIST_FOLDER, name + ".xml"), content);
70
+ }
71
+ }
72
+ exports.writeTempAnnotations = writeTempAnnotations;
59
73
  function removePropertiesExtension(filePath) {
60
74
  const lastIndexOf = filePath.lastIndexOf(".properties");
61
75
  return filePath.substring(0, lastIndexOf);
62
76
  }
63
77
  exports.removePropertiesExtension = removePropertiesExtension;
78
+ function traverse(json, paths, callback) {
79
+ for (const key of Object.keys(json)) {
80
+ const internPaths = [...paths];
81
+ internPaths.push(key);
82
+ if (typeof json[key] === "object") {
83
+ if (Array.isArray(json[key])) {
84
+ const array = json[key];
85
+ for (let i = 0; i < array.length; i++) {
86
+ if (typeof array[i] === "object") {
87
+ traverse(array[i], internPaths, callback);
88
+ }
89
+ else {
90
+ callback(array, i, internPaths);
91
+ }
92
+ }
93
+ }
94
+ else {
95
+ traverse(json[key], internPaths, callback);
96
+ }
97
+ }
98
+ else {
99
+ callback(json, key, internPaths);
100
+ }
101
+ }
102
+ }
103
+ exports.traverse = traverse;
64
104
  async function logBuilderVersion() {
65
105
  try {
66
106
  // @ts-ignore
@@ -72,4 +112,18 @@ async function logBuilderVersion() {
72
112
  }
73
113
  }
74
114
  exports.logBuilderVersion = logBuilderVersion;
115
+ async function logBetaUsage() {
116
+ log.info("Beta features enabled");
117
+ }
118
+ exports.logBetaUsage = logBetaUsage;
119
+ function getUniqueName(existingNames, template) {
120
+ let suffix = -1;
121
+ let suffixString;
122
+ do {
123
+ suffixString = suffix === -1 ? "" : suffix;
124
+ suffix++;
125
+ } while (existingNames.includes(template + suffixString));
126
+ return template + suffixString;
127
+ }
128
+ exports.getUniqueName = getUniqueName;
75
129
  //# sourceMappingURL=commonUtil.js.map
@@ -1,6 +1,6 @@
1
1
  import { IAppVariantInfo } from "../model/types";
2
2
  export default class I18NMerger {
3
- static analyzeAppVariantManifestChanges(rootFolder: string, tranlsationRegexPattern: string, appVariantInfo: IAppVariantInfo): {
3
+ static analyzeAppVariantManifestChanges(rootFolder: string, tranlsationRegexPattern: string, { changes }: IAppVariantInfo): {
4
4
  mergePathsRegex: RegExp[];
5
5
  copyPathsRegex: RegExp[];
6
6
  };
@@ -5,13 +5,12 @@ const resourceUtil_1 = require("./resourceUtil");
5
5
  const path_1 = require("path");
6
6
  const Resource = require("@ui5/fs/lib/Resource");
7
7
  class I18NMerger {
8
- static analyzeAppVariantManifestChanges(rootFolder, tranlsationRegexPattern, appVariantInfo) {
8
+ static analyzeAppVariantManifestChanges(rootFolder, tranlsationRegexPattern, { changes }) {
9
9
  // check which files need to be copied and which files need to be merged and copied
10
10
  // this is necessary because lrep does not support multiple enhanceWith with multiple locations
11
11
  const mergePaths = new Set();
12
12
  const copyPaths = new Set();
13
- const { manifest, manifestChanges } = appVariantInfo;
14
- manifestChanges.concat(manifest.content).forEach((change) => {
13
+ changes.forEach((change) => {
15
14
  const i18nPathWithExtension = change.content?.bundleUrl || change.texts?.i18n;
16
15
  if (i18nPathWithExtension) {
17
16
  // build regex to match specific + language related files
@@ -46,7 +45,7 @@ class I18NMerger {
46
45
  let baseAppI18NPath = `${rootFolder}/${baseAppManifestI18NPath}${mergePathMatch[1] || ""}.properties`;
47
46
  await this.mergePropertiesFiles(aggregatedResourceFilesMap, appVariantResource, baseAppI18NPath);
48
47
  }
49
- // Resource for to be copied file already exists so we only have to adjust path
48
+ // Resource for to be copied file already exists so we only have to adjust path
50
49
  // Otherwise we have to omit it. We always change the path to avoid omitting a base app file
51
50
  this.moveToAppVarSubfolder(appVariantResource, rootFolder, i18nTargetFolder);
52
51
  if (!shouldCopyFile) {
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const axios_1 = require("axios");
4
4
  const noAuthorizationProvidedError_1 = require("../model/noAuthorizationProvidedError");
5
+ const serverError_1 = require("../model/serverError");
5
6
  class RequestUtil {
6
7
  static async head(url, auth) {
7
8
  return this.request(url, axios_1.default.head, auth);
@@ -24,6 +25,9 @@ class RequestUtil {
24
25
  if (error.response.status === 401) {
25
26
  throw new noAuthorizationProvidedError_1.default(uri);
26
27
  }
28
+ else if (error.response.status >= 500) {
29
+ throw new serverError_1.default(uri, error);
30
+ }
27
31
  else {
28
32
  throw new Error(`Unexpected response received from '${uri}': ${error.response.status} ${error.response.data ?? ""}`);
29
33
  }
@@ -1,8 +1,11 @@
1
1
  export default class ResourceUtil {
2
2
  static getRootFolder(projectNamespace?: string): string;
3
+ static relativeToRoot(resourcePath: string, projectNamespace?: string): string;
3
4
  static getResourcePath(projectNamespace?: string, ...paths: string[]): string;
4
5
  static write(dir: string, files: Map<string, string>): Promise<void[]>;
5
6
  static read(rootFolder: string, folder: string, files: Map<string, string>, exclude?: string[]): void;
6
7
  static getString(resource: any): Promise<string>;
8
+ static getJson(resource: any): Promise<any>;
7
9
  static setString(resource: any, str: string): void;
10
+ static createResource(filename: string, projectNamespace: string, content: string): any;
8
11
  }
@@ -12,6 +12,10 @@ class ResourceUtil {
12
12
  }
13
13
  return path_1.posix.join(...newPath);
14
14
  }
15
+ static relativeToRoot(resourcePath, projectNamespace) {
16
+ const rootFolder = ResourceUtil.getRootFolder(projectNamespace);
17
+ return path_1.posix.relative(rootFolder, resourcePath);
18
+ }
15
19
  static getResourcePath(projectNamespace, ...paths) {
16
20
  return path_1.posix.join(this.getRootFolder(projectNamespace), ...paths);
17
21
  }
@@ -33,7 +37,7 @@ class ResourceUtil {
33
37
  const entryPath = path_1.posix.join(folder, entry);
34
38
  const stats = fs.lstatSync(entryPath);
35
39
  if (stats.isFile() && !exclude.some(filepath => entryPath.endsWith(filepath))) {
36
- const normalized = entryPath.substring(rootFolder.length);
40
+ const normalized = entryPath.substring(rootFolder.length + 1);
37
41
  files.set(normalized, fs.readFileSync(entryPath, { encoding: "utf-8" }));
38
42
  }
39
43
  else if (stats.isDirectory()) {
@@ -44,9 +48,18 @@ class ResourceUtil {
44
48
  static getString(resource) {
45
49
  return resource.getBuffer().then((buffer) => buffer.toString(UTF8));
46
50
  }
51
+ static getJson(resource) {
52
+ return resource.getBuffer().then((buffer) => JSON.parse(buffer.toString(UTF8)));
53
+ }
47
54
  static setString(resource, str) {
48
55
  resource.setBuffer(Buffer.from(str, UTF8));
49
56
  }
57
+ static createResource(filename, projectNamespace, content) {
58
+ return resourceFactory.createResource({
59
+ path: this.getResourcePath(projectNamespace, filename),
60
+ string: content
61
+ });
62
+ }
50
63
  }
51
64
  exports.default = ResourceUtil;
52
65
  //# sourceMappingURL=resourceUtil.js.map
@@ -0,0 +1,4 @@
1
+ export default class UrlUtil {
2
+ static join(relativeUrl: string, parentUrl: string): any;
3
+ static getResourcePath(url: string | undefined): any;
4
+ }
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const { URI } = require("../../dist/bundle-odata");
4
+ class UrlUtil {
5
+ static join(relativeUrl, parentUrl) {
6
+ // Remove trailing slash, otherwise url join can be incorrect Remove
7
+ // trailing slash, otherwise url join can be incorrect Annotation URLs
8
+ // defined in manifest might end with .../$value/ or .../$value and both
9
+ // are accepted by Gateway and produce the same content with same
10
+ // relative URLs. The first case is actually incorrect and we have to
11
+ // sanitize the same way as UI5. We also trim urls domain/host, because
12
+ // we need to substitute it with destination to download later.
13
+ return new URI(relativeUrl).absoluteTo(parentUrl.replace(/\/$/, "")).toString();
14
+ }
15
+ static getResourcePath(url) {
16
+ // Trim urls domain/host.
17
+ return url && URI.parse(url).path;
18
+ }
19
+ }
20
+ exports.default = UrlUtil;
21
+ //# sourceMappingURL=urlUtil.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ui5/task-adaptation",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
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": {
@@ -14,7 +14,7 @@
14
14
  "prepublishOnly": "git push --follow-tags",
15
15
  "release-note": "git-chglog -c .chglog/release-config.yml v$npm_package_version",
16
16
  "rollup": "npx ts-node scripts/rollup.ts",
17
- "build": "npm run rollup && tsc -p ./",
17
+ "build": "npm run rollup && rimraf dist/resources && tsc -p ./",
18
18
  "download-metadata": "npx ts-node scripts/metadataDownloadHelper.ts"
19
19
  },
20
20
  "repository": {
@@ -43,10 +43,12 @@
43
43
  "amdextract": "^3.0.0",
44
44
  "axios": "^1.6.2",
45
45
  "builtin-modules": "^3.2.0",
46
+ "crc": "^4.3.2",
46
47
  "dotenv": "^16.0.3",
48
+ "glob": "^10.3.10",
47
49
  "js-yaml": "^4.1.0",
48
- "json-diff": "^1.0.6",
49
- "rimraf": "^3.0.2",
50
+ "jsdom": "^23.0.1",
51
+ "rimraf": "^5.0.5",
50
52
  "rollup": "^2.56.3",
51
53
  "semver": "^7.3.5",
52
54
  "temp-dir": "^2.0.0",
@@ -58,15 +60,16 @@
58
60
  "@types/chai": "^4.2.21",
59
61
  "@types/chai-as-promised": "^7.1.4",
60
62
  "@types/js-yaml": "^4.0.3",
61
- "@types/json-diff": "^0.9.1",
63
+ "@types/jsdom": "^21.1.6",
62
64
  "@types/lodash": "^4.14.196",
63
65
  "@types/mocha": "^9.1.0",
64
- "@types/rimraf": "^3.0.2",
66
+ "@types/rimraf": "^4.0.5",
65
67
  "@types/semver": "^7.3.8",
66
68
  "@types/sinon": "^10.0.16",
67
69
  "chai": "^4.3.4",
68
70
  "chai-as-promised": "^7.1.1",
69
71
  "chalk": "^4.1.2",
72
+ "minimatch": "^9.0.3",
70
73
  "mocha": "^9.2.0",
71
74
  "mock-require": "^3.0.3",
72
75
  "nyc": "^15.1.0",
@@ -1,16 +1,12 @@
1
- import * as fs from "fs";
2
- import { posix as path } from "path";
3
- import * as semver from "semver";
4
1
  import * as rollup from "rollup";
5
2
  import * as builtins from "builtin-modules";
6
3
  import ui5 from "./rollup/ui5Resolve";
7
4
  import { nodeResolve } from "@rollup/plugin-node-resolve";
8
5
 
9
- const log = require("@ui5/logger").getLogger("rollup-plugin-ui5-resolve-task-adaptation");
10
6
 
11
7
  export default abstract class Bundler {
12
8
 
13
- static async run(project: any, input: string, output: string, namespace: string,
9
+ static async run(project: any, input: string, output: string,
14
10
  assets: string[], skipTransformation?: string[]): Promise<void> {
15
11
  if (skipTransformation == null) {
16
12
  skipTransformation = [];
@@ -18,20 +14,11 @@ export default abstract class Bundler {
18
14
  if (skipTransformation.includes(input) === false) {
19
15
  skipTransformation.push(input);
20
16
  }
21
- const bundledUI5Version = this.getBundledUI5Version(output);
22
- const ui5version = this.getVersion(project, namespace);
23
- if (bundledUI5Version == null || ui5version && semver.neq(bundledUI5Version, ui5version)) {
24
- if (ui5version) {
25
- log.info(`Using UI5 version ${ui5version.toString()} to bundle`);
26
- }
27
- await this.bundle(project, input, output, assets, skipTransformation, ui5version);
28
- } else {
29
- log.info(`UI5 version ${bundledUI5Version!.toString()} is already bundled`);
30
- }
17
+ await this.bundle(project, input, output, assets, skipTransformation);
31
18
  }
32
19
 
33
20
  private static async bundle(project: any, input: string, output: string,
34
- assets: string[], skipTransformation: string[], ui5version: string): Promise<void> {
21
+ assets: string[], skipTransformation: string[]): Promise<void> {
35
22
  const inputOptions = <rollup.RollupOptions>{
36
23
  input,
37
24
  plugins: [
@@ -39,8 +26,7 @@ export default abstract class Bundler {
39
26
  assets,
40
27
  skipTransformation,
41
28
  output,
42
- project,
43
- ui5version
29
+ project
44
30
  }),
45
31
  nodeResolve({
46
32
  preferBuiltins: true
@@ -57,19 +43,4 @@ export default abstract class Bundler {
57
43
  await bundle.write(outputOptions);
58
44
  await bundle.close();
59
45
  }
60
-
61
- private static getBundledUI5Version(output: string) {
62
- const bundleFilePath = path.join(process.cwd(), output);
63
- if (fs.existsSync(bundleFilePath)) {
64
- const bundle = fs.readFileSync(bundleFilePath, { encoding: "utf-8" });
65
- const version = bundle.substring(2, bundle.indexOf("\n"));
66
- return semver.coerce(version);
67
- }
68
- }
69
-
70
- private static getVersion(project: any, namespace: string): string {
71
- const isModule = (dependency: any) => dependency.id.endsWith(namespace);
72
- const sapUiFlDependency = project.dependencies.find(isModule);
73
- return sapUiFlDependency && sapUiFlDependency.version;
74
- }
75
46
  }