@ui5/task-adaptation 1.0.15 → 1.0.16
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/CHANGELOG.md +4 -4
- package/README.md +1 -1
- package/dist/annotationManager.d.ts +32 -0
- package/dist/annotationManager.js +276 -0
- package/dist/appVariantManager.js +18 -32
- package/dist/baseAppManager.d.ts +8 -4
- package/dist/baseAppManager.js +37 -62
- package/dist/buildStrategy.js +3 -0
- package/dist/bundle-resourceBundle.js +692 -0
- package/dist/bundle.js +245 -102
- package/dist/cache/annotationsCacheManager.d.ts +8 -0
- package/dist/cache/annotationsCacheManager.js +18 -0
- package/dist/cache/baseAppFilesCacheManager.d.ts +6 -0
- package/dist/cache/baseAppFilesCacheManager.js +15 -0
- package/dist/cache/cacheManager.d.ts +16 -0
- package/dist/cache/cacheManager.js +67 -0
- package/dist/index.js +10 -18
- package/dist/model/noAuthorizationProvidedError.d.ts +3 -0
- package/dist/model/noAuthorizationProvidedError.js +9 -0
- package/dist/model/types.d.ts +12 -0
- package/dist/processors/abapProcessor.d.ts +21 -0
- package/dist/processors/abapProcessor.js +36 -0
- package/dist/processors/cfProcessor.d.ts +17 -0
- package/dist/processors/cfProcessor.js +46 -0
- package/dist/processors/processor.d.ts +7 -0
- package/dist/processors/processor.js +36 -0
- package/dist/repositories/abapRepoManager.d.ts +13 -0
- package/dist/repositories/abapRepoManager.js +81 -0
- package/dist/{html5RepoManager.d.ts → repositories/html5RepoManager.d.ts} +2 -2
- package/dist/repositories/html5RepoManager.js +89 -0
- package/dist/util/cfUtil.js +109 -138
- package/dist/util/commonUtil.js +1 -1
- package/dist/util/requestUtil.d.ts +6 -3
- package/dist/util/requestUtil.js +43 -24
- package/dist/util/resourceUtil.d.ts +2 -10
- package/dist/util/resourceUtil.js +6 -49
- package/dist/util/zipUtil.d.ts +2 -0
- package/dist/util/zipUtil.js +20 -0
- package/package.json +8 -3
- package/scripts/bundler.ts +75 -0
- package/scripts/rollup/bundleDefinition-resourceBundle.js +5 -0
- package/scripts/rollup/overrides/sap/base/i18n/Localization.js +1 -0
- package/scripts/rollup/overrides/sap/base/string/formatMessage.js +1 -0
- package/scripts/rollup/overrides/sap/base/util/Properties.js +1 -0
- package/scripts/rollup/overrides/sap/base/util/merge.js +1 -0
- package/scripts/rollup/project/ui5.yaml +1 -1
- package/scripts/rollup.ts +26 -50
- package/dist/html5RepoManager.js +0 -113
- package/dist/updateCache.d.ts +0 -5
- package/dist/updateCache.js +0 -36
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const resourceUtil_1 = require("../util/resourceUtil");
|
|
6
|
+
const rimraf = require("rimraf");
|
|
7
|
+
const tempFolder = require('temp-dir');
|
|
8
|
+
class CacheManager {
|
|
9
|
+
constructor(configuration) {
|
|
10
|
+
this.configuration = configuration;
|
|
11
|
+
}
|
|
12
|
+
getTempFolder() {
|
|
13
|
+
return path.join(tempFolder, this.getTempId());
|
|
14
|
+
}
|
|
15
|
+
async getFiles(fetchMetadata, fetchFiles) {
|
|
16
|
+
const tempMetadata = this.readTempMetadata();
|
|
17
|
+
const metadata = await fetchMetadata();
|
|
18
|
+
if (this.isMetadataSame(tempMetadata, metadata)) {
|
|
19
|
+
return this.readTemp();
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
const files = await fetchFiles();
|
|
23
|
+
if (files?.size > 0) {
|
|
24
|
+
await this.writeTemp(files, metadata);
|
|
25
|
+
}
|
|
26
|
+
return files;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
isMetadataSame(tempMetadata, metadata) {
|
|
30
|
+
return tempMetadata && metadata && tempMetadata.changedOn === metadata.changedOn;
|
|
31
|
+
}
|
|
32
|
+
readTempMetadata() {
|
|
33
|
+
const tempFolder = this.getTempFolder();
|
|
34
|
+
const filename = this.getMetadataFilename();
|
|
35
|
+
const metadataPath = path.resolve(tempFolder, filename);
|
|
36
|
+
if (fs.existsSync(metadataPath)) {
|
|
37
|
+
return JSON.parse(fs.readFileSync(metadataPath, { encoding: "utf-8" }));
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
writeTemp(files, metadata) {
|
|
41
|
+
this.deleteTemp();
|
|
42
|
+
const filesToCache = this.getFilesToCache(files, metadata);
|
|
43
|
+
return resourceUtil_1.default.write(this.getTempFolder(), filesToCache);
|
|
44
|
+
}
|
|
45
|
+
async readTemp() {
|
|
46
|
+
const files = new Map();
|
|
47
|
+
const tempFolder = this.getTempFolder();
|
|
48
|
+
if (fs.existsSync(tempFolder)) {
|
|
49
|
+
resourceUtil_1.default.read(tempFolder, tempFolder, files, [this.getMetadataFilename()]);
|
|
50
|
+
}
|
|
51
|
+
return files;
|
|
52
|
+
}
|
|
53
|
+
deleteTemp() {
|
|
54
|
+
rimraf.sync(this.getTempFolder());
|
|
55
|
+
}
|
|
56
|
+
normalizeId(id) {
|
|
57
|
+
return id.replace(/\/\\/g, "_");
|
|
58
|
+
}
|
|
59
|
+
getFilesToCache(files, metadata) {
|
|
60
|
+
const filename = this.getMetadataFilename();
|
|
61
|
+
const filesClone = new Map([...files]);
|
|
62
|
+
filesClone.set(filename, JSON.stringify(metadata));
|
|
63
|
+
return filesClone;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
exports.default = CacheManager;
|
|
67
|
+
//# sourceMappingURL=cacheManager.js.map
|
package/dist/index.js
CHANGED
|
@@ -1,29 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const dotenv = require("dotenv");
|
|
12
4
|
const appVariantManager_1 = require("./appVariantManager");
|
|
13
5
|
const baseAppManager_1 = require("./baseAppManager");
|
|
14
|
-
const
|
|
6
|
+
const processor_1 = require("./processors/processor");
|
|
15
7
|
/**
|
|
16
8
|
* Creates an appVariant bundle from the provided resources.
|
|
17
9
|
*/
|
|
18
10
|
module.exports = ({ workspace, options, taskUtil }) => {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
11
|
+
dotenv.config();
|
|
12
|
+
async function process(workspace, taskUtil) {
|
|
13
|
+
const processor = processor_1.determineProcessor(options.configuration);
|
|
14
|
+
const appVariantResources = await appVariantManager_1.default.getAppVariantResources(workspace);
|
|
15
|
+
const appVariantInfo = await appVariantManager_1.default.process(appVariantResources, options.projectNamespace, taskUtil);
|
|
16
|
+
const baseAppFiles = await processor.getBaseAppFiles(appVariantInfo.reference);
|
|
17
|
+
const baseAppResources = await baseAppManager_1.default.process(baseAppFiles, appVariantInfo, options, processor);
|
|
18
|
+
await Promise.all(appVariantResources.concat(baseAppResources).map(resource => workspace.write(resource)));
|
|
27
19
|
}
|
|
28
20
|
return process(workspace, taskUtil);
|
|
29
21
|
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
class NoAuthorizationProvidedError extends Error {
|
|
4
|
+
constructor(uri) {
|
|
5
|
+
super(`Request requires authorization: '${uri}'`);
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
exports.default = NoAuthorizationProvidedError;
|
|
9
|
+
//# sourceMappingURL=noAuthorizationProvidedError.js.map
|
package/dist/model/types.d.ts
CHANGED
|
@@ -6,6 +6,10 @@ export interface IConfiguration {
|
|
|
6
6
|
spaceGuid?: string;
|
|
7
7
|
orgGuid?: string;
|
|
8
8
|
sapCloudService?: string;
|
|
9
|
+
destination?: string;
|
|
10
|
+
credentials?: IAuth;
|
|
11
|
+
type?: "cf" | "abap";
|
|
12
|
+
languages?: string[];
|
|
9
13
|
}
|
|
10
14
|
export interface IProjectOptions {
|
|
11
15
|
configuration: IConfiguration;
|
|
@@ -82,6 +86,14 @@ export interface IHTML5RepoInfo {
|
|
|
82
86
|
token: string;
|
|
83
87
|
baseUri: string;
|
|
84
88
|
}
|
|
89
|
+
export interface IAuth {
|
|
90
|
+
username: string;
|
|
91
|
+
password: string;
|
|
92
|
+
}
|
|
93
|
+
export interface IMetadata {
|
|
94
|
+
changedOn: string;
|
|
95
|
+
id?: string;
|
|
96
|
+
}
|
|
85
97
|
export declare type KeyedMap<T, K extends keyof T, V> = {
|
|
86
98
|
[k in K]: V;
|
|
87
99
|
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import AbapRepoManager from "../repositories/abapRepoManager";
|
|
2
|
+
import AnnotationManager from "../annotationManager";
|
|
3
|
+
import BaseAppFilesCacheManager from "../cache/baseAppFilesCacheManager";
|
|
4
|
+
import { IConfiguration } from "../model/types";
|
|
5
|
+
import IProcessor from "./processor";
|
|
6
|
+
export default class AbapProcessor implements IProcessor {
|
|
7
|
+
private abapRepoManager;
|
|
8
|
+
private configuration;
|
|
9
|
+
private cacheManager;
|
|
10
|
+
private annotationManager;
|
|
11
|
+
constructor(configuration: IConfiguration, cacheManager: BaseAppFilesCacheManager, abapRepoManager: AbapRepoManager, annotationManager: AnnotationManager);
|
|
12
|
+
getBaseAppFiles(baseAppId: string): Promise<Map<string, string>>;
|
|
13
|
+
validateConfiguration(): void;
|
|
14
|
+
updateLandscapeSpecificContent(renamedBaseAppManifest: any, baseAppFiles?: Map<string, string>): Promise<void>;
|
|
15
|
+
getConfigurationType(): string;
|
|
16
|
+
createAppVariantHierarchyItem(appVariantId: string, version: string): {
|
|
17
|
+
appVariantId: string;
|
|
18
|
+
version: string;
|
|
19
|
+
layer: string;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const commonUtil_1 = require("../util/commonUtil");
|
|
4
|
+
class AbapProcessor {
|
|
5
|
+
constructor(configuration, cacheManager, abapRepoManager, annotationManager) {
|
|
6
|
+
this.configuration = configuration;
|
|
7
|
+
this.abapRepoManager = abapRepoManager;
|
|
8
|
+
this.cacheManager = cacheManager;
|
|
9
|
+
this.annotationManager = annotationManager;
|
|
10
|
+
}
|
|
11
|
+
getBaseAppFiles(baseAppId) {
|
|
12
|
+
return this.cacheManager.getFiles(() => this.abapRepoManager.getMetadata(baseAppId), () => this.abapRepoManager.downloadBaseAppFiles());
|
|
13
|
+
}
|
|
14
|
+
validateConfiguration() {
|
|
15
|
+
commonUtil_1.validateObject(this.configuration, ["destination", "appName"], "should be specified in ui5.yaml configuration");
|
|
16
|
+
}
|
|
17
|
+
async updateLandscapeSpecificContent(renamedBaseAppManifest, baseAppFiles) {
|
|
18
|
+
const { languages } = this.configuration;
|
|
19
|
+
const files = await this.annotationManager.process(renamedBaseAppManifest, ["", ...(languages ?? ["EN"])]);
|
|
20
|
+
if (baseAppFiles) {
|
|
21
|
+
files.forEach((value, key) => baseAppFiles.set(key, value));
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
getConfigurationType() {
|
|
25
|
+
return "abap";
|
|
26
|
+
}
|
|
27
|
+
createAppVariantHierarchyItem(appVariantId, version) {
|
|
28
|
+
return {
|
|
29
|
+
appVariantId,
|
|
30
|
+
version,
|
|
31
|
+
layer: "VENDOR"
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.default = AbapProcessor;
|
|
36
|
+
//# sourceMappingURL=abapProcessor.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import BaseAppFilesCacheManager from "../cache/baseAppFilesCacheManager";
|
|
2
|
+
import { IConfiguration } from "../model/types";
|
|
3
|
+
import IProcessor from "./processor";
|
|
4
|
+
export default class CFProcessor implements IProcessor {
|
|
5
|
+
private configuration;
|
|
6
|
+
private cacheManager;
|
|
7
|
+
constructor(configuration: IConfiguration, cacheManager: BaseAppFilesCacheManager);
|
|
8
|
+
getBaseAppFiles(): Promise<Map<string, string>>;
|
|
9
|
+
validateConfiguration(): void;
|
|
10
|
+
updateLandscapeSpecificContent(renamedBaseAppManifest: any): Promise<void>;
|
|
11
|
+
private updateCloudPlatform;
|
|
12
|
+
getConfigurationType(): string;
|
|
13
|
+
createAppVariantHierarchyItem(appVariantId: string, version: string): {
|
|
14
|
+
appVariantId: string;
|
|
15
|
+
version: string;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const html5RepoManager_1 = require("../repositories/html5RepoManager");
|
|
4
|
+
const commonUtil_1 = require("../util/commonUtil");
|
|
5
|
+
class CFProcessor {
|
|
6
|
+
constructor(configuration, cacheManager) {
|
|
7
|
+
this.configuration = configuration;
|
|
8
|
+
this.cacheManager = cacheManager;
|
|
9
|
+
}
|
|
10
|
+
async getBaseAppFiles() {
|
|
11
|
+
return this.cacheManager.getFiles(() => html5RepoManager_1.default.getMetadata(this.configuration), () => html5RepoManager_1.default.getBaseAppFiles(this.configuration));
|
|
12
|
+
}
|
|
13
|
+
validateConfiguration() {
|
|
14
|
+
commonUtil_1.validateObject(this.configuration, ["appHostId", "appName", "appVersion"], "should be specified in ui5.yaml configuration");
|
|
15
|
+
}
|
|
16
|
+
async updateLandscapeSpecificContent(renamedBaseAppManifest) {
|
|
17
|
+
this.updateCloudPlatform(renamedBaseAppManifest);
|
|
18
|
+
}
|
|
19
|
+
updateCloudPlatform(renamedBaseAppManifest) {
|
|
20
|
+
const sapCloudService = renamedBaseAppManifest["sap.cloud"]?.service;
|
|
21
|
+
const sapPlatformCf = renamedBaseAppManifest["sap.platform.cf"];
|
|
22
|
+
if (sapPlatformCf && sapCloudService) {
|
|
23
|
+
sapPlatformCf.oAuthScopes = sapPlatformCf.oAuthScopes.map((scope) => scope.replace(`$XSAPPNAME.`, `$XSAPPNAME('${sapCloudService}').`));
|
|
24
|
+
}
|
|
25
|
+
if (this.configuration.sapCloudService) {
|
|
26
|
+
if (renamedBaseAppManifest["sap.cloud"] == null) {
|
|
27
|
+
renamedBaseAppManifest["sap.cloud"] = {};
|
|
28
|
+
}
|
|
29
|
+
renamedBaseAppManifest["sap.cloud"].service = this.configuration.sapCloudService;
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
delete renamedBaseAppManifest["sap.cloud"];
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
getConfigurationType() {
|
|
36
|
+
return "cf";
|
|
37
|
+
}
|
|
38
|
+
createAppVariantHierarchyItem(appVariantId, version) {
|
|
39
|
+
return {
|
|
40
|
+
appVariantId,
|
|
41
|
+
version
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
exports.default = CFProcessor;
|
|
46
|
+
//# sourceMappingURL=cfProcessor.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { IConfiguration } from "../model/types";
|
|
2
|
+
export default interface IProcessor {
|
|
3
|
+
createAppVariantHierarchyItem(appVariantId: string, version: string): void;
|
|
4
|
+
getBaseAppFiles(baseAppId: string): Promise<Map<string, string>>;
|
|
5
|
+
updateLandscapeSpecificContent(renamedBaseAppManifest: any, baseAppFiles?: Map<string, string>): Promise<void>;
|
|
6
|
+
}
|
|
7
|
+
export declare function determineProcessor(configuration: IConfiguration): IProcessor;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.determineProcessor = void 0;
|
|
4
|
+
const abapProcessor_1 = require("./abapProcessor");
|
|
5
|
+
const abapRepoManager_1 = require("../repositories/abapRepoManager");
|
|
6
|
+
const annotationManager_1 = require("../annotationManager");
|
|
7
|
+
const baseAppFilesCacheManager_1 = require("../cache/baseAppFilesCacheManager");
|
|
8
|
+
const cfProcessor_1 = require("./cfProcessor");
|
|
9
|
+
function determineProcessor(configuration) {
|
|
10
|
+
const cacheManager = new baseAppFilesCacheManager_1.default(configuration);
|
|
11
|
+
const abapRepoManager = new abapRepoManager_1.default(configuration);
|
|
12
|
+
const annotationManager = new annotationManager_1.default(configuration, abapRepoManager);
|
|
13
|
+
const processors = [
|
|
14
|
+
new cfProcessor_1.default(configuration, cacheManager),
|
|
15
|
+
new abapProcessor_1.default(configuration, cacheManager, abapRepoManager, annotationManager)
|
|
16
|
+
];
|
|
17
|
+
let processor = processors.find(processor => processor.getConfigurationType() === configuration.type);
|
|
18
|
+
if (processor) {
|
|
19
|
+
processor.validateConfiguration();
|
|
20
|
+
return processor;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
for (const processor of processors) {
|
|
24
|
+
try {
|
|
25
|
+
processor.validateConfiguration();
|
|
26
|
+
return processor;
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
throw new Error("ui5.yaml configuration should correspond either ABAP or SAP BTP landscape");
|
|
34
|
+
}
|
|
35
|
+
exports.determineProcessor = determineProcessor;
|
|
36
|
+
//# sourceMappingURL=processor.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { IConfiguration, IMetadata } from "../model/types";
|
|
2
|
+
export default class AbapRepoManager {
|
|
3
|
+
private auth?;
|
|
4
|
+
private configuration;
|
|
5
|
+
constructor(configuration: IConfiguration);
|
|
6
|
+
getAnnotationMetadata(uri: string): Promise<IMetadata>;
|
|
7
|
+
downloadAnnotationFile(uri: string): Promise<Map<string, string>>;
|
|
8
|
+
getMetadata(baseAppId: string): Promise<IMetadata>;
|
|
9
|
+
downloadBaseAppFiles(): Promise<Map<string, string>>;
|
|
10
|
+
private getMetadataRequest;
|
|
11
|
+
private downloadBaseAppFilesRequest;
|
|
12
|
+
private getAuth;
|
|
13
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const requestUtil_1 = require("../util/requestUtil");
|
|
4
|
+
const zipUtil_1 = require("../util/zipUtil");
|
|
5
|
+
const log = require("@ui5/logger").getLogger("@ui5/task-adaptation::AbapRepoManager");
|
|
6
|
+
const REQUEST_OPTIONS_XML = {
|
|
7
|
+
responseType: "text",
|
|
8
|
+
headers: {
|
|
9
|
+
"Content-Type": "text/xml"
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
const REQUEST_OPTIONS_JSON = {
|
|
13
|
+
headers: {
|
|
14
|
+
"Content-Type": "application/json"
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
class AbapRepoManager {
|
|
18
|
+
constructor(configuration) {
|
|
19
|
+
this.configuration = configuration;
|
|
20
|
+
}
|
|
21
|
+
async getAnnotationMetadata(uri) {
|
|
22
|
+
const header = await requestUtil_1.default.retryWithAuth(() => requestUtil_1.default.head(uri), () => requestUtil_1.default.head(uri, this.getAuth()));
|
|
23
|
+
return { changedOn: header.modified };
|
|
24
|
+
}
|
|
25
|
+
async downloadAnnotationFile(uri) {
|
|
26
|
+
const annotation = await requestUtil_1.default.retryWithAuth(() => requestUtil_1.default.get(uri, REQUEST_OPTIONS_XML), () => requestUtil_1.default.get(uri, REQUEST_OPTIONS_XML, this.getAuth()));
|
|
27
|
+
return new Map([["annotation.xml", annotation]]);
|
|
28
|
+
}
|
|
29
|
+
getMetadata(baseAppId) {
|
|
30
|
+
return requestUtil_1.default.retryWithAuth(() => this.getMetadataRequest(baseAppId), () => this.getMetadataRequest(baseAppId, this.getAuth()));
|
|
31
|
+
}
|
|
32
|
+
downloadBaseAppFiles() {
|
|
33
|
+
return requestUtil_1.default.retryWithAuth(() => this.downloadBaseAppFilesRequest(), () => this.downloadBaseAppFilesRequest(this.getAuth()));
|
|
34
|
+
}
|
|
35
|
+
async getMetadataRequest(id, auth) {
|
|
36
|
+
let uri = `https://${this.configuration.destination}.dest/sap/bc/ui2/app_index/ui5_app_info_json?id=${id}`;
|
|
37
|
+
const data = await requestUtil_1.default.get(uri, REQUEST_OPTIONS_JSON, auth);
|
|
38
|
+
if (data && data[id]) {
|
|
39
|
+
return {
|
|
40
|
+
changedOn: data[id].url,
|
|
41
|
+
id
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
log.warn(`UI5AppInfoJson request doesn't contain cache buster token for sap.app/id '${id}'. Fallback to download.`);
|
|
45
|
+
}
|
|
46
|
+
async downloadBaseAppFilesRequest(auth) {
|
|
47
|
+
const { destination, appName } = this.configuration;
|
|
48
|
+
const encodedAppName = encodeURIComponent(appName);
|
|
49
|
+
const uri = `https://${destination}.dest/sap/opu/odata/UI5/ABAP_REPOSITORY_SRV/Repositories('${encodedAppName}')?DownloadFiles=RUNTIME&CodePage=UTF8`;
|
|
50
|
+
const data = await requestUtil_1.default.get(uri, REQUEST_OPTIONS_XML, auth);
|
|
51
|
+
if (data?.d?.ZipArchive.length > 0) {
|
|
52
|
+
const buffer = Buffer.from(data.d.ZipArchive, "base64");
|
|
53
|
+
return zipUtil_1.unzipZipEntries(buffer);
|
|
54
|
+
}
|
|
55
|
+
throw new Error(`App '${appName}' from destination '${destination}' doesn't contain files`);
|
|
56
|
+
}
|
|
57
|
+
getAuth() {
|
|
58
|
+
if (!this.auth) {
|
|
59
|
+
if (this.configuration?.credentials) {
|
|
60
|
+
let { username, password } = this.configuration?.credentials;
|
|
61
|
+
if (username && password) {
|
|
62
|
+
const ENV_PREFIX = "env:";
|
|
63
|
+
username = username.substring(ENV_PREFIX.length);
|
|
64
|
+
password = password.substring(ENV_PREFIX.length);
|
|
65
|
+
if (process.env[username] && process.env[password]) {
|
|
66
|
+
this.auth = {
|
|
67
|
+
username: process.env[username],
|
|
68
|
+
password: process.env[password]
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (!this.auth) {
|
|
75
|
+
throw new Error("Please provide ABAP System credentials in .env file of the project: https://help.sap.com/docs/SAP_FIORI_tools/17d50220bcd848aa854c9c182d65b699/1c859274b511435ab6bd45f70e7f9af2.html.");
|
|
76
|
+
}
|
|
77
|
+
return this.auth;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
exports.default = AbapRepoManager;
|
|
81
|
+
//# sourceMappingURL=abapRepoManager.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IConfiguration } from "
|
|
1
|
+
import { IConfiguration } from "./../model/types";
|
|
2
2
|
export default class HTML5RepoManager {
|
|
3
3
|
static getBaseAppFiles(configuration: IConfiguration): Promise<Map<string, string>>;
|
|
4
4
|
static getMetadata(configuration: IConfiguration): Promise<any>;
|
|
@@ -7,5 +7,5 @@ export default class HTML5RepoManager {
|
|
|
7
7
|
private static getToken;
|
|
8
8
|
private static requestMetadata;
|
|
9
9
|
private static getBaseAppZipEntries;
|
|
10
|
-
private static
|
|
10
|
+
private static download;
|
|
11
11
|
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const cfUtil_1 = require("./../util/cfUtil");
|
|
4
|
+
const requestUtil_1 = require("./../util/requestUtil");
|
|
5
|
+
const zipUtil_1 = require("./../util/zipUtil");
|
|
6
|
+
const log = require("@ui5/logger").getLogger("@ui5/task-adaptation::HTML5RepoManager");
|
|
7
|
+
class HTML5RepoManager {
|
|
8
|
+
static async getBaseAppFiles(configuration) {
|
|
9
|
+
const { token, baseUri } = await this.getHtml5RepoInfo(configuration);
|
|
10
|
+
return this.getBaseAppZipEntries(configuration, baseUri, token);
|
|
11
|
+
}
|
|
12
|
+
static async getMetadata(configuration) {
|
|
13
|
+
const { token, baseUri } = await this.getHtml5RepoInfo(configuration);
|
|
14
|
+
return this.requestMetadata(configuration, baseUri, token);
|
|
15
|
+
}
|
|
16
|
+
static async getHtml5RepoInfo(configuration) {
|
|
17
|
+
const spaceGuid = await cfUtil_1.default.getSpaceGuid(configuration?.spaceGuid);
|
|
18
|
+
const credentials = await this.getHTML5Credentials(spaceGuid);
|
|
19
|
+
const token = await this.getToken(credentials);
|
|
20
|
+
return {
|
|
21
|
+
token,
|
|
22
|
+
baseUri: credentials.uri
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
static async getHTML5Credentials(spaceGuid) {
|
|
26
|
+
log.verbose("Getting HTML5 Repo Runtime credentials from space " + spaceGuid);
|
|
27
|
+
const PLAN_NAME = "app-runtime";
|
|
28
|
+
const SERVIСE_INSTANCE_NAME = "html5-apps-repo-runtime";
|
|
29
|
+
const getParams = {
|
|
30
|
+
spaceGuids: [spaceGuid],
|
|
31
|
+
planNames: [PLAN_NAME],
|
|
32
|
+
names: [SERVIСE_INSTANCE_NAME]
|
|
33
|
+
};
|
|
34
|
+
const createParams = {
|
|
35
|
+
spaceGuid,
|
|
36
|
+
planName: PLAN_NAME,
|
|
37
|
+
serviceName: SERVIСE_INSTANCE_NAME,
|
|
38
|
+
tags: ["html5-apps-repo-rt"]
|
|
39
|
+
};
|
|
40
|
+
const serviceKeys = await cfUtil_1.default.getServiceInstanceKeys(getParams, createParams);
|
|
41
|
+
return serviceKeys.credentials;
|
|
42
|
+
}
|
|
43
|
+
static async getToken({ uaa }) {
|
|
44
|
+
log.verbose("Getting HTML5 Repo token");
|
|
45
|
+
const auth = Buffer.from(uaa.clientid + ":" + uaa.clientsecret);
|
|
46
|
+
const options = {
|
|
47
|
+
headers: {
|
|
48
|
+
"Content-Type": "application/json",
|
|
49
|
+
"Authorization": "Basic " + auth.toString("base64")
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
const uri = `${uaa.url}/oauth/token?grant_type=client_credentials`;
|
|
53
|
+
return requestUtil_1.default.get(uri, options).then((json) => json["access_token"]);
|
|
54
|
+
}
|
|
55
|
+
static async requestMetadata(options, html5RepoBaseUri, token) {
|
|
56
|
+
const { appHostId, appName, appVersion } = options;
|
|
57
|
+
const uri = `${html5RepoBaseUri}/applications/metadata/`;
|
|
58
|
+
const requestOptions = {
|
|
59
|
+
headers: {
|
|
60
|
+
"Content-Type": "application/json",
|
|
61
|
+
"Authorization": "Bearer " + token,
|
|
62
|
+
"x-app-host-id": appHostId
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
const metadata = await requestUtil_1.default.get(uri, requestOptions);
|
|
66
|
+
return metadata.find((item) => item.appHostId === appHostId && item.applicationName === appName && item.applicationVersion === appVersion);
|
|
67
|
+
}
|
|
68
|
+
static async getBaseAppZipEntries(options, html5RepoBaseUri, token) {
|
|
69
|
+
const { appHostId, appName, appVersion } = options;
|
|
70
|
+
const uri = `${html5RepoBaseUri}/applications/content/${appName}-${appVersion}/`;
|
|
71
|
+
const zip = await this.download(token, appHostId, uri);
|
|
72
|
+
return zipUtil_1.unzipZipEntries(zip);
|
|
73
|
+
}
|
|
74
|
+
static async download(token, appHostId, uri) {
|
|
75
|
+
if (!token) {
|
|
76
|
+
throw new Error("HTML5 token is undefined");
|
|
77
|
+
}
|
|
78
|
+
return requestUtil_1.default.get(uri, {
|
|
79
|
+
responseType: "arraybuffer",
|
|
80
|
+
headers: {
|
|
81
|
+
"Content-Type": "application/json",
|
|
82
|
+
"Authorization": "Bearer " + token,
|
|
83
|
+
"x-app-host-id": appHostId
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
exports.default = HTML5RepoManager;
|
|
89
|
+
//# sourceMappingURL=html5RepoManager.js.map
|