@ui5/task-adaptation 1.6.7 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/codeql.yml +35 -0
- package/.github/workflows/release-please.yml +53 -0
- package/.release-please-manifest.json +3 -0
- package/CHANGELOG.md +42 -36
- package/dist/adapters/abapAdapter.d.ts +3 -3
- package/dist/adapters/abapAdapter.js +19 -8
- package/dist/adapters/adapter.d.ts +3 -2
- package/dist/adapters/adapter.js +9 -3
- package/dist/adapters/cfAdapter.d.ts +2 -2
- package/dist/adapters/cfAdapter.js +12 -12
- package/dist/adapters/commands/command.js +0 -27
- package/dist/adapters/commands/downloadAnnotationsCommand.d.ts +3 -4
- package/dist/adapters/commands/downloadAnnotationsCommand.js +4 -4
- package/dist/adapters/commands/fetchPreviewResourcesCommand.js +1 -1
- package/dist/adapters/commands/omitDeletedResourcesCommand.d.ts +1 -1
- package/dist/adapters/commands/renameFilesCommand.d.ts +0 -22
- package/dist/adapters/commands/renameFilesCommand.js +2 -114
- package/dist/adapters/commands/renameManifestCommand.js +2 -2
- package/dist/adapters/previewAdapter.d.ts +2 -2
- package/dist/adapters/previewAdapter.js +4 -4
- package/dist/annotations/abapAnnotationManager.js +1 -3
- package/dist/annotations/dataSource/dataSource.d.ts +6 -5
- package/dist/annotations/dataSource/dataSource.js +36 -12
- package/dist/annotations/dataSource/dataSourceManager.d.ts +2 -2
- package/dist/annotations/dataSource/dataSourceManager.js +2 -2
- package/dist/annotations/dataSource/dataSourceOData.d.ts +2 -2
- package/dist/annotations/transformers/transformer.d.ts +2 -2
- package/dist/annotations/transformers/traverseReferences.d.ts +1 -1
- package/dist/annotations/transformers/traverseReferences.js +2 -2
- package/dist/appVariant.d.ts +5 -7
- package/dist/appVariant.js +9 -23
- package/dist/baseApp.d.ts +1 -0
- package/dist/baseApp.js +10 -0
- package/dist/bundle.js +86 -53
- package/dist/cache/cacheHolder.d.ts +6 -12
- package/dist/cache/cacheHolder.js +27 -39
- package/dist/cache/cachedResource.d.ts +2 -1
- package/dist/index.d.ts +6 -7
- package/dist/index.js +49 -42
- package/dist/landscapeConfiguration.d.ts +4 -4
- package/dist/landscapeConfiguration.js +48 -44
- package/dist/model/configuration.d.ts +0 -1
- package/dist/model/types.d.ts +1 -3
- package/dist/repositories/abapRepository.d.ts +1 -1
- package/dist/repositories/abapRepository.js +3 -3
- package/dist/repositories/cacheRepository.d.ts +4 -5
- package/dist/repositories/cacheRepository.js +10 -18
- package/dist/repositories/html5Repository.d.ts +1 -1
- package/dist/repositories/html5Repository.js +2 -2
- package/dist/repositories/localRepository.d.ts +1 -1
- package/dist/repositories/localRepository.js +2 -2
- package/dist/repositories/repository.d.ts +1 -1
- package/dist/util/cfUtil.d.ts +6 -24
- package/dist/util/cfUtil.js +36 -93
- package/dist/util/commonUtil.d.ts +1 -9
- package/dist/util/commonUtil.js +27 -29
- package/dist/util/fsUtil.js +1 -2
- package/dist/util/movingHandler/changeFileMoveHandler.d.ts +1 -0
- package/dist/util/movingHandler/changeFileMoveHandler.js +11 -3
- package/dist/util/referencesBuilder.d.ts +15 -0
- package/dist/util/referencesBuilder.js +35 -0
- package/dist/util/renaming/fileRenamer.d.ts +23 -0
- package/dist/util/renaming/fileRenamer.js +120 -0
- package/dist/util/{renamingHandlers → renaming/handlers}/jsonRenamingHandler.d.ts +0 -2
- package/dist/util/{renamingHandlers → renaming/handlers}/jsonRenamingHandler.js +0 -6
- package/dist/util/{renamingUtil.d.ts → renaming/referenceRenaming.d.ts} +4 -4
- package/dist/util/{renamingUtil.js → renaming/referenceRenaming.js} +8 -8
- package/dist/util/resourceUtil.js +6 -2
- package/package.json +11 -4
- package/release-please-config.json +66 -0
- package/dist/annotations/serviceRequestor.d.ts +0 -9
- package/dist/annotations/serviceRequestor.js +0 -62
- /package/dist/util/{renamingHandlers → renaming/handlers}/manifestRenamingHandler.d.ts +0 -0
- /package/dist/util/{renamingHandlers → renaming/handlers}/manifestRenamingHandler.js +0 -0
package/dist/util/commonUtil.js
CHANGED
|
@@ -2,10 +2,37 @@ import * as Log from "@ui5/logger";
|
|
|
2
2
|
import * as fs from "fs";
|
|
3
3
|
import { fileURLToPath } from "url";
|
|
4
4
|
import { posix as path } from "path";
|
|
5
|
+
import ServerError from "../model/serverError.js";
|
|
5
6
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
6
7
|
const log = Log.getLogger("rollup-plugin-ui5-resolve-task-adaptation");
|
|
7
8
|
const CHANGES_EXT = ".change";
|
|
8
9
|
const MANIFEST_CHANGE = "appdescr_";
|
|
10
|
+
export function retryOnError(maxRetries) {
|
|
11
|
+
return (_target, _propertyKey, descriptor) => {
|
|
12
|
+
const originalMethod = descriptor.value;
|
|
13
|
+
descriptor.value = async function (...args) {
|
|
14
|
+
let retries = 0;
|
|
15
|
+
while (true) {
|
|
16
|
+
try {
|
|
17
|
+
return await originalMethod.apply(this, args);
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
if (error instanceof ServerError) {
|
|
21
|
+
if (retries === maxRetries) {
|
|
22
|
+
throw new Error(`Error occurred: ${error.message}. Please try again if this is a temporary issue. If not, please create a ticket on CA-UI5-ABA-AIDX`);
|
|
23
|
+
}
|
|
24
|
+
retries++;
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
const message = error?.response?.data ?? error.message;
|
|
28
|
+
throw new Error(`Failed to fetch annotation by '${args[0]}': ${message}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
return descriptor;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
9
36
|
export function dotToUnderscore(value) {
|
|
10
37
|
return value.replace(/\./g, "_");
|
|
11
38
|
}
|
|
@@ -40,18 +67,6 @@ export function escapeRegex(update) {
|
|
|
40
67
|
export function insertInArray(array, index, insert) {
|
|
41
68
|
array.splice(index, 0, insert);
|
|
42
69
|
}
|
|
43
|
-
export function writeTempAnnotations({ writeTempFiles }, name, language, content) {
|
|
44
|
-
const TEMP_DIST_FOLDER = path.join(process.cwd(), "dist-debug", name);
|
|
45
|
-
if (writeTempFiles) {
|
|
46
|
-
if (!fs.existsSync(TEMP_DIST_FOLDER)) {
|
|
47
|
-
fs.mkdirSync(TEMP_DIST_FOLDER, { recursive: true });
|
|
48
|
-
}
|
|
49
|
-
if (language) {
|
|
50
|
-
name += "-" + language.i18n;
|
|
51
|
-
}
|
|
52
|
-
fs.writeFileSync(path.join(TEMP_DIST_FOLDER, name + ".xml"), content);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
70
|
export function trimExtension(filePath) {
|
|
56
71
|
return filePath.replace(/\.[^/.]+$/, "");
|
|
57
72
|
}
|
|
@@ -113,21 +128,4 @@ export function isManifestChange(filename, content) {
|
|
|
113
128
|
}
|
|
114
129
|
return false;
|
|
115
130
|
}
|
|
116
|
-
/**
|
|
117
|
-
* 4p. Reference map contains searchTerm as key and replacement as value. Base
|
|
118
|
-
* id and app variant ids are renamed to adaptation project id.
|
|
119
|
-
*/
|
|
120
|
-
export function getReferences(appVariants, adaptationProjectId) {
|
|
121
|
-
const references = new Map();
|
|
122
|
-
appVariants.forEach((variant, i) => {
|
|
123
|
-
if (i === 0) {
|
|
124
|
-
references.set(variant.reference, adaptationProjectId);
|
|
125
|
-
}
|
|
126
|
-
if (variant.id !== adaptationProjectId) {
|
|
127
|
-
references.set(variant.id, adaptationProjectId);
|
|
128
|
-
}
|
|
129
|
-
variant.getRenamingForMovedFiles().forEach((value, key) => references.set(key, value));
|
|
130
|
-
});
|
|
131
|
-
return references;
|
|
132
|
-
}
|
|
133
131
|
//# sourceMappingURL=commonUtil.js.map
|
package/dist/util/fsUtil.js
CHANGED
|
@@ -41,8 +41,7 @@ export default class FsUtil {
|
|
|
41
41
|
const fileReadTasks = entries
|
|
42
42
|
.filter(entry => entry.isFile())
|
|
43
43
|
.map(async (entry) => {
|
|
44
|
-
const
|
|
45
|
-
const entryPath = path.join(parentPath, entry.name);
|
|
44
|
+
const entryPath = path.join(entry.parentPath, entry.name);
|
|
46
45
|
const relativeFilePath = path.relative(rootDirectory, entryPath).replaceAll("\\", "/");
|
|
47
46
|
const content = await fs.readFile(entryPath);
|
|
48
47
|
return [relativeFilePath, content];
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export declare const moveFiles: (inputFiles: ReadonlyMap<string, Buffer>, prefix: string, id: string) => {
|
|
2
2
|
files: Map<string, Buffer<ArrayBufferLike>>;
|
|
3
3
|
renamingPaths: Map<string, string>;
|
|
4
|
+
movedFiles: Map<string, string>;
|
|
4
5
|
};
|
|
5
6
|
export declare const moveFile: (filename: string, content: Buffer, prefix: string, id: string) => {
|
|
6
7
|
newFilename: string;
|
|
@@ -49,13 +49,21 @@ function getPathWithoutExtensions(filename) {
|
|
|
49
49
|
}
|
|
50
50
|
export const moveFiles = (inputFiles, prefix, id) => {
|
|
51
51
|
const files = new Map();
|
|
52
|
-
|
|
52
|
+
const renamingPaths = new Map();
|
|
53
|
+
// Maps original filename -> new filename for files that were actually
|
|
54
|
+
// moved, so callers can resolve the new location of an omitted resource.
|
|
55
|
+
const movedFiles = new Map();
|
|
53
56
|
inputFiles.forEach((content, filename) => {
|
|
54
57
|
const { newFilename, renamingPath } = moveFile(filename, content, prefix, id);
|
|
55
58
|
files.set(newFilename, content);
|
|
56
|
-
|
|
59
|
+
for (const [from, to] of renamingPath) {
|
|
60
|
+
renamingPaths.set(from, to);
|
|
61
|
+
}
|
|
62
|
+
if (newFilename !== filename) {
|
|
63
|
+
movedFiles.set(filename, newFilename);
|
|
64
|
+
}
|
|
57
65
|
});
|
|
58
|
-
return { files, renamingPaths };
|
|
66
|
+
return { files, renamingPaths, movedFiles };
|
|
59
67
|
};
|
|
60
68
|
export const moveFile = (filename, content, prefix, id) => {
|
|
61
69
|
let newFilename = filename;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fluent builder for the reference map (old id → adaptation project id) used to
|
|
3
|
+
* rename files. Chain `addReferences` and finish with `build`.
|
|
4
|
+
*/
|
|
5
|
+
export default class ReferencesBuilder {
|
|
6
|
+
private readonly references;
|
|
7
|
+
/**
|
|
8
|
+
* Adds the references derived from the app variant id hierarchy stored in
|
|
9
|
+
* the given files' manifest.
|
|
10
|
+
*/
|
|
11
|
+
addReferences(files: ReadonlyMap<string, Buffer>, adaptationProjectId: string): this;
|
|
12
|
+
addReference(from: string, to: string): this;
|
|
13
|
+
build(): Map<string, string>;
|
|
14
|
+
private getReferences;
|
|
15
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import BaseApp from "../baseApp.js";
|
|
2
|
+
/**
|
|
3
|
+
* Fluent builder for the reference map (old id → adaptation project id) used to
|
|
4
|
+
* rename files. Chain `addReferences` and finish with `build`.
|
|
5
|
+
*/
|
|
6
|
+
export default class ReferencesBuilder {
|
|
7
|
+
references = new Map();
|
|
8
|
+
/**
|
|
9
|
+
* Adds the references derived from the app variant id hierarchy stored in
|
|
10
|
+
* the given files' manifest.
|
|
11
|
+
*/
|
|
12
|
+
addReferences(files, adaptationProjectId) {
|
|
13
|
+
const hierarchy = BaseApp.getAppVariantHierarchy(files);
|
|
14
|
+
const references = this.getReferences(hierarchy, adaptationProjectId);
|
|
15
|
+
references.forEach((value, key) => this.references.set(key, value));
|
|
16
|
+
return this;
|
|
17
|
+
}
|
|
18
|
+
addReference(from, to) {
|
|
19
|
+
this.references.set(from, to);
|
|
20
|
+
return this;
|
|
21
|
+
}
|
|
22
|
+
build() {
|
|
23
|
+
return this.references;
|
|
24
|
+
}
|
|
25
|
+
getReferences(appVariantIdHierarchy, adaptationProjectId) {
|
|
26
|
+
const references = new Map();
|
|
27
|
+
for (const appVariantId of appVariantIdHierarchy) {
|
|
28
|
+
if (appVariantId !== adaptationProjectId && !references.has(appVariantId)) {
|
|
29
|
+
references.set(appVariantId, adaptationProjectId);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return references;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=referencesBuilder.js.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Renames references (old id → adaptation project id) across all text files in
|
|
3
|
+
* place, leaving i18n .properties files, their keys and SAPUI5 dependency ids
|
|
4
|
+
* untouched.
|
|
5
|
+
*/
|
|
6
|
+
export default class FileRenamer {
|
|
7
|
+
/**
|
|
8
|
+
* 1p. i18n.properties are not renamed and property keys are ignored during
|
|
9
|
+
* the renaming across the files. Stateless: does not use `this`.
|
|
10
|
+
* @param files - all files both base and appVariants
|
|
11
|
+
* @param references - Reference maps of the app variant
|
|
12
|
+
*/
|
|
13
|
+
static rename(files: Map<string, Buffer>, references: Map<string, string>): void;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Snapshots the JSON paths that must survive renaming (e.g.
|
|
17
|
+
* sap.ui5/appVariantIdHierarchy, dependencies), runs the decorated method, then
|
|
18
|
+
* restores them. The decorated method receives a Map of files (filename →
|
|
19
|
+
* Buffer): every file a handler `accept`s is parsed, snapshotted before the
|
|
20
|
+
* renaming and restored + written back after. Each matching file gets its own
|
|
21
|
+
* handler instance so one file's snapshot can't clobber another's.
|
|
22
|
+
*/
|
|
23
|
+
export declare function restoreWhatShouldntBeRenamed(): (_target: any, _propertyKey: string, descriptor: PropertyDescriptor) => void;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import ManifestRenamingHandler from "./handlers/manifestRenamingHandler.js";
|
|
8
|
+
import { stringToBuffer, bufferToString, bufferToJson, jsonToBuffer } from "../commonUtil.js";
|
|
9
|
+
import { getSAPUI5DependencyIds } from "../manifestUtil.js";
|
|
10
|
+
import { renameMap } from "./referenceRenaming.js";
|
|
11
|
+
import { TEXT_EXTENSIONS } from "../resourceUtil.js";
|
|
12
|
+
import { posix as path } from "path";
|
|
13
|
+
function isTextFile(filename) {
|
|
14
|
+
return TEXT_EXTENSIONS.has(path.extname(filename).slice(1));
|
|
15
|
+
}
|
|
16
|
+
function getManifestSAPUI5DependencyIds(files) {
|
|
17
|
+
const manifestFile = files.get("manifest.json");
|
|
18
|
+
return manifestFile ? getSAPUI5DependencyIds(bufferToJson(manifestFile)) : [];
|
|
19
|
+
}
|
|
20
|
+
function getI18nPropertyKeys(files) {
|
|
21
|
+
const keys = new Set();
|
|
22
|
+
files.forEach((content, filename) => {
|
|
23
|
+
if (filename.endsWith(".properties")) {
|
|
24
|
+
const lines = bufferToString(content).split("\n").filter(line => !line.startsWith("#"));
|
|
25
|
+
for (const line of lines) {
|
|
26
|
+
const [key] = line.split("=");
|
|
27
|
+
if (key) {
|
|
28
|
+
keys.add(key);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
return [...keys];
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Renames references (old id → adaptation project id) across all text files in
|
|
37
|
+
* place, leaving i18n .properties files, their keys and SAPUI5 dependency ids
|
|
38
|
+
* untouched.
|
|
39
|
+
*/
|
|
40
|
+
export default class FileRenamer {
|
|
41
|
+
/**
|
|
42
|
+
* 1p. i18n.properties are not renamed and property keys are ignored during
|
|
43
|
+
* the renaming across the files. Stateless: does not use `this`.
|
|
44
|
+
* @param files - all files both base and appVariants
|
|
45
|
+
* @param references - Reference maps of the app variant
|
|
46
|
+
*/
|
|
47
|
+
static rename(files, references) {
|
|
48
|
+
const IGNORE_EXTENSIONS = [".properties"];
|
|
49
|
+
const ignoreInString = [
|
|
50
|
+
...getI18nPropertyKeys(files),
|
|
51
|
+
...getManifestSAPUI5DependencyIds(files)
|
|
52
|
+
];
|
|
53
|
+
const updates = new Map();
|
|
54
|
+
for (const [filename, content] of files) {
|
|
55
|
+
if (!isTextFile(filename)) {
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (!IGNORE_EXTENSIONS.some(ext => filename.endsWith(ext))) {
|
|
59
|
+
// 5p. We pass replacements as ignores since we don't want to
|
|
60
|
+
// rename them again. E.g. we replace app.id with
|
|
61
|
+
// customer.app.id, but if we found customer.app.id somewhere,
|
|
62
|
+
// because we applied changes or something, we don't want to
|
|
63
|
+
// rename it again to customer.customer.app.id.
|
|
64
|
+
const renamed = renameMap(bufferToString(content), references, [...references.values(), ...ignoreInString]);
|
|
65
|
+
updates.set(filename, stringToBuffer(renamed));
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
for (const [filename, content] of updates) {
|
|
69
|
+
files.set(filename, content);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
__decorate([
|
|
74
|
+
restoreWhatShouldntBeRenamed()
|
|
75
|
+
], FileRenamer, "rename", null);
|
|
76
|
+
/**
|
|
77
|
+
* Snapshots the JSON paths that must survive renaming (e.g.
|
|
78
|
+
* sap.ui5/appVariantIdHierarchy, dependencies), runs the decorated method, then
|
|
79
|
+
* restores them. The decorated method receives a Map of files (filename →
|
|
80
|
+
* Buffer): every file a handler `accept`s is parsed, snapshotted before the
|
|
81
|
+
* renaming and restored + written back after. Each matching file gets its own
|
|
82
|
+
* handler instance so one file's snapshot can't clobber another's.
|
|
83
|
+
*/
|
|
84
|
+
export function restoreWhatShouldntBeRenamed() {
|
|
85
|
+
return function (_target, _propertyKey, descriptor) {
|
|
86
|
+
const handlerFactories = [() => new ManifestRenamingHandler()];
|
|
87
|
+
const originalValue = descriptor.value;
|
|
88
|
+
descriptor.value = function (...args) {
|
|
89
|
+
const files = args[0];
|
|
90
|
+
// Snapshot the protected paths with a dedicated handler instance per
|
|
91
|
+
// file, so one file's snapshot can't clobber another's. Multiple
|
|
92
|
+
// files can match a handler (e.g. the root manifest.json and a
|
|
93
|
+
// nested cards/.../manifest.json both end with "manifest.json"); a
|
|
94
|
+
// shared handler would let the last-snapshotted file (which may lack
|
|
95
|
+
// appVariantIdHierarchy) wipe the root manifest's value on restore.
|
|
96
|
+
const snapshots = [];
|
|
97
|
+
for (const [filename, content] of files) {
|
|
98
|
+
for (const createHandler of handlerFactories) {
|
|
99
|
+
const handler = createHandler();
|
|
100
|
+
if (handler.accept(filename)) {
|
|
101
|
+
handler.snapshot(bufferToJson(content));
|
|
102
|
+
snapshots.push({ filename, handler });
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
originalValue.apply(this, args);
|
|
107
|
+
for (const { filename, handler } of snapshots) {
|
|
108
|
+
const content = files.get(filename);
|
|
109
|
+
if (content) {
|
|
110
|
+
const json = bufferToJson(content);
|
|
111
|
+
handler.restore(json);
|
|
112
|
+
files.set(filename, jsonToBuffer(json));
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return files;
|
|
116
|
+
};
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
;
|
|
120
|
+
//# sourceMappingURL=fileRenamer.js.map
|
|
@@ -3,8 +3,6 @@ export default abstract class JsonRenamingHandler {
|
|
|
3
3
|
protected abstract filePath: string;
|
|
4
4
|
protected abstract jsonPathsToRestore: string[];
|
|
5
5
|
accept(filename: string): boolean;
|
|
6
|
-
before(json: any): void;
|
|
7
|
-
after(json: any): void;
|
|
8
6
|
snapshot(json: any): void;
|
|
9
7
|
restore(obj: any): void;
|
|
10
8
|
protected store(obj: any, path: string): void;
|
|
@@ -3,12 +3,6 @@ export default class JsonRenamingHandler {
|
|
|
3
3
|
accept(filename) {
|
|
4
4
|
return filename.endsWith(this.filePath);
|
|
5
5
|
}
|
|
6
|
-
before(json) {
|
|
7
|
-
this.jsonPathsToRestore.forEach(path => this.store(json, path));
|
|
8
|
-
}
|
|
9
|
-
after(json) {
|
|
10
|
-
this.restore(json);
|
|
11
|
-
}
|
|
12
6
|
snapshot(json) {
|
|
13
7
|
this.jsonPathsToRestore.forEach(path => this.store(json, path));
|
|
14
8
|
}
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
export declare function rename(content: string, references: string[], replacement: string): string;
|
|
2
2
|
/**
|
|
3
|
-
* A precompiled
|
|
3
|
+
* A precompiled replacer: the regex, replacement lookup and ignore set are built
|
|
4
4
|
* once and can be applied to many strings via `replace` without recompilation.
|
|
5
5
|
*/
|
|
6
|
-
export interface
|
|
6
|
+
export interface CompiledReplacer {
|
|
7
7
|
replace(content: string): string;
|
|
8
8
|
}
|
|
9
9
|
/**
|
|
10
|
-
* Builds a reusable {@link
|
|
10
|
+
* Builds a reusable {@link CompiledReplacer} from the given references and ignore list.
|
|
11
11
|
* The expensive work (regex compilation, lookup construction) happens here once;
|
|
12
12
|
* the returned `replace` is a cheap single pass over each input string. Prefer
|
|
13
13
|
* this over calling {@link renameMap} repeatedly with the same references.
|
|
14
14
|
*
|
|
15
15
|
* Note: mutates `references` by dropping entries whose dot-count doesn't match.
|
|
16
16
|
*/
|
|
17
|
-
export declare function
|
|
17
|
+
export declare function compileReplacer(references: Map<string, string>, ignoreInStrings: string[]): CompiledReplacer;
|
|
18
18
|
export declare function renameMap(content: string, references: Map<string, string>, ignoreInStrings: string[]): string;
|
|
19
19
|
export declare function renameJson(json: Record<string, unknown>, references: Map<string, string>, ignoreInStrings: string[]): void;
|
|
20
20
|
export declare function renameResources(files: ReadonlyMap<string, string>, search: string[], replacement: string): Map<string, string>;
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { getLogger } from "@ui5/logger";
|
|
2
|
-
const log = getLogger("@ui5/task-adaptation::
|
|
2
|
+
const log = getLogger("@ui5/task-adaptation::ReferenceRenaming");
|
|
3
3
|
const dotToSlash = (string) => string.replaceAll(".", "/");
|
|
4
4
|
const escapeRegex = (string) => string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
5
5
|
export function rename(content, references, replacement) {
|
|
6
6
|
return renameMap(content, new Map(references.map(ref => [ref, replacement])), [replacement]);
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
|
-
* Builds a reusable {@link
|
|
9
|
+
* Builds a reusable {@link CompiledReplacer} from the given references and ignore list.
|
|
10
10
|
* The expensive work (regex compilation, lookup construction) happens here once;
|
|
11
11
|
* the returned `replace` is a cheap single pass over each input string. Prefer
|
|
12
12
|
* this over calling {@link renameMap} repeatedly with the same references.
|
|
13
13
|
*
|
|
14
14
|
* Note: mutates `references` by dropping entries whose dot-count doesn't match.
|
|
15
15
|
*/
|
|
16
|
-
export function
|
|
16
|
+
export function compileReplacer(references, ignoreInStrings) {
|
|
17
17
|
const ignoredReferenceKeys = [];
|
|
18
18
|
for (const [key, value] of references) {
|
|
19
19
|
if (value.includes(".") !== key.includes(".")) {
|
|
@@ -96,13 +96,13 @@ export function compileRenamer(references, ignoreInStrings) {
|
|
|
96
96
|
};
|
|
97
97
|
}
|
|
98
98
|
export function renameMap(content, references, ignoreInStrings) {
|
|
99
|
-
return
|
|
99
|
+
return compileReplacer(references, ignoreInStrings).replace(content);
|
|
100
100
|
}
|
|
101
101
|
export function renameJson(json, references, ignoreInStrings) {
|
|
102
|
-
const
|
|
102
|
+
const replacer = compileReplacer(references, ignoreInStrings);
|
|
103
103
|
function processObject(obj) {
|
|
104
104
|
for (const key of Object.keys(obj)) {
|
|
105
|
-
const renamedKey =
|
|
105
|
+
const renamedKey = replacer.replace(key);
|
|
106
106
|
const value = obj[key];
|
|
107
107
|
if (renamedKey !== key) {
|
|
108
108
|
obj[renamedKey] = value;
|
|
@@ -115,7 +115,7 @@ export function renameJson(json, references, ignoreInStrings) {
|
|
|
115
115
|
const target = container;
|
|
116
116
|
const value = target[index];
|
|
117
117
|
if (typeof value === "string") {
|
|
118
|
-
target[index] =
|
|
118
|
+
target[index] = replacer.replace(value);
|
|
119
119
|
}
|
|
120
120
|
else if (Array.isArray(value)) {
|
|
121
121
|
value.forEach((_, i) => processValue(value, i));
|
|
@@ -129,4 +129,4 @@ export function renameJson(json, references, ignoreInStrings) {
|
|
|
129
129
|
export function renameResources(files, search, replacement) {
|
|
130
130
|
return new Map([...files].map(([filepath, content]) => [filepath, rename(content, search, replacement)]));
|
|
131
131
|
}
|
|
132
|
-
//# sourceMappingURL=
|
|
132
|
+
//# sourceMappingURL=referenceRenaming.js.map
|
|
@@ -126,9 +126,13 @@ export default class ResourceUtil {
|
|
|
126
126
|
}
|
|
127
127
|
static async toFileMap(resources, projectNamespace) {
|
|
128
128
|
const files = new Map();
|
|
129
|
-
const
|
|
129
|
+
const rootFolder = projectNamespace ? ResourceUtil.getRootFolder(projectNamespace) : undefined;
|
|
130
130
|
for (const resource of resources) {
|
|
131
|
-
|
|
131
|
+
const resourcePath = resource.getPath();
|
|
132
|
+
const filename = rootFolder && resourcePath.startsWith(rootFolder)
|
|
133
|
+
? resourcePath.substring(rootFolder.length + 1)
|
|
134
|
+
: resourcePath.substring(1);
|
|
135
|
+
files.set(filename, await resource.getBuffer());
|
|
132
136
|
}
|
|
133
137
|
return files;
|
|
134
138
|
}
|
package/package.json
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ui5/task-adaptation",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"description": "Custom task for ui5-builder which allows building UI5 Flexibility Adaptation Projects for SAP BTP, Cloud Foundry environment",
|
|
5
|
-
"main": "index.js",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"import": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
6
12
|
"scripts": {
|
|
7
|
-
"test": "npm run lint && npm run build && npm run coverage",
|
|
13
|
+
"test": "npm run lint && npm run build && npm run typecheck:test && npm run coverage",
|
|
8
14
|
"lint": "eslint ./src ./test/lib",
|
|
15
|
+
"typecheck:test": "tsc -p ./test/lib/tsconfig.json --noEmit",
|
|
9
16
|
"dev": "mocha --no-timeouts --no-warnings --import=tsx \"test/lib/**/*.spec.ts\"",
|
|
10
17
|
"perf": "mocha --no-timeouts --no-warnings --import=tsx \"test/lib/**/*.perf.ts\"",
|
|
11
18
|
"coverage": "c8 npm run dev",
|
|
@@ -126,4 +133,4 @@
|
|
|
126
133
|
"@rollup/rollup-linux-x64-gnu": "^4.28.1",
|
|
127
134
|
"@rollup/rollup-linux-x64-musl": "^4.28.1"
|
|
128
135
|
}
|
|
129
|
-
}
|
|
136
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"packages": {
|
|
3
|
+
".": {
|
|
4
|
+
"pull-request-header": ":tractor: New release prepared",
|
|
5
|
+
"pull-request-title-pattern": "release: v${version}",
|
|
6
|
+
"include-component-in-tag": false,
|
|
7
|
+
"changelog-sections": [
|
|
8
|
+
{
|
|
9
|
+
"type": "feat",
|
|
10
|
+
"section": "Features"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"type": "fix",
|
|
14
|
+
"section": "Bug Fixes"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"type": "perf",
|
|
18
|
+
"section": "Performance Improvements"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"type": "deps",
|
|
22
|
+
"section": "Dependencies"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"type": "revert",
|
|
26
|
+
"section": "Reverts"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"type": "docs",
|
|
30
|
+
"section": "Documentation",
|
|
31
|
+
"hidden": true
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"type": "style",
|
|
35
|
+
"section": "Styles",
|
|
36
|
+
"hidden": true
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"type": "refactor",
|
|
40
|
+
"section": "Code Refactoring",
|
|
41
|
+
"hidden": true
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"type": "test",
|
|
45
|
+
"section": "Tests",
|
|
46
|
+
"hidden": true
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"type": "build",
|
|
50
|
+
"section": "Automation",
|
|
51
|
+
"hidden": true
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"type": "ci",
|
|
55
|
+
"section": "Continuous Integration",
|
|
56
|
+
"hidden": true
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"type": "release",
|
|
60
|
+
"section": "Release",
|
|
61
|
+
"hidden": true
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { IConfiguration } from "../model/types.js";
|
|
2
|
-
import Language from "../model/language.js";
|
|
3
|
-
import IRepository from "../repositories/repository.js";
|
|
4
|
-
export default class ServiceRequestor {
|
|
5
|
-
private repository;
|
|
6
|
-
private configuration;
|
|
7
|
-
constructor(configuration: IConfiguration, repository: IRepository);
|
|
8
|
-
downloadAnnotation(uri: string, name: string, language: Language): Promise<string>;
|
|
9
|
-
}
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
-
};
|
|
7
|
-
import ServerError from "../model/serverError.js";
|
|
8
|
-
import { getLogger } from "@ui5/logger";
|
|
9
|
-
import { writeTempAnnotations } from "../util/commonUtil.js";
|
|
10
|
-
const log = getLogger("@ui5/task-adaptation::ServiceRequestor");
|
|
11
|
-
function retryOnError(maxRetries) {
|
|
12
|
-
return (_target, _propertyKey, descriptor) => {
|
|
13
|
-
const originalMethod = descriptor.value;
|
|
14
|
-
descriptor.value = async function (...args) {
|
|
15
|
-
let retries = 0;
|
|
16
|
-
while (true) {
|
|
17
|
-
try {
|
|
18
|
-
return await originalMethod.apply(this, args);
|
|
19
|
-
}
|
|
20
|
-
catch (error) {
|
|
21
|
-
if (error instanceof ServerError) {
|
|
22
|
-
if (retries === maxRetries) {
|
|
23
|
-
throw new Error(`Error occurred: ${error.message}. Please try again if this is a temporary issue. If not, please create a ticket on CA-UI5-ABA-AIDX`);
|
|
24
|
-
}
|
|
25
|
-
retries++;
|
|
26
|
-
}
|
|
27
|
-
else {
|
|
28
|
-
const message = error?.response?.data ?? error.message;
|
|
29
|
-
throw new Error(`Failed to fetch annotation by '${args[0]}': ${message}`);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
};
|
|
34
|
-
return descriptor;
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
export default class ServiceRequestor {
|
|
38
|
-
repository;
|
|
39
|
-
configuration;
|
|
40
|
-
constructor(configuration, repository) {
|
|
41
|
-
this.repository = repository;
|
|
42
|
-
this.configuration = configuration;
|
|
43
|
-
}
|
|
44
|
-
//@ts-ignore tsx (esbuild) is not yet implemented the new decorators, but
|
|
45
|
-
//old decorators are already subject of compiler error, but it works. So we
|
|
46
|
-
//wait till esbuild implement it correctly.
|
|
47
|
-
async downloadAnnotation(uri, name, language) {
|
|
48
|
-
uri += `?sap-language=${language.sap}`;
|
|
49
|
-
log.verbose(`Getting annotation '${name}' ${language} by '${uri}'`);
|
|
50
|
-
let files = await this.repository.downloadAnnotationFile(uri);
|
|
51
|
-
if (!files || files.size === 0) {
|
|
52
|
-
throw new Error(`No files were fetched for '${name}' by '${uri}'`);
|
|
53
|
-
}
|
|
54
|
-
const xml = [...files][0][1];
|
|
55
|
-
writeTempAnnotations(this.configuration, name, language, xml);
|
|
56
|
-
return xml;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
__decorate([
|
|
60
|
-
retryOnError(1)
|
|
61
|
-
], ServiceRequestor.prototype, "downloadAnnotation", null);
|
|
62
|
-
//# sourceMappingURL=serviceRequestor.js.map
|
|
File without changes
|
|
File without changes
|