@ui5/task-adaptation 1.6.6 → 1.6.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5 -1
- package/dist/adapters/abapAdapter.d.ts +2 -1
- package/dist/adapters/abapAdapter.js +3 -0
- package/dist/adapters/adapter.d.ts +2 -1
- package/dist/adapters/cfAdapter.d.ts +2 -1
- package/dist/adapters/cfAdapter.js +14 -0
- package/dist/adapters/commands/command.d.ts +7 -7
- package/dist/adapters/commands/command.js +3 -2
- package/dist/adapters/commands/downloadAnnotationsCommand.d.ts +1 -1
- package/dist/adapters/commands/downloadAnnotationsCommand.js +4 -3
- package/dist/adapters/commands/fetchPreviewResourcesCommand.js +4 -2
- package/dist/adapters/commands/filterFilesCommand.d.ts +1 -1
- package/dist/adapters/commands/filterFilesCommand.js +2 -1
- package/dist/adapters/commands/i18nPropertiesMergeCommand.d.ts +1 -1
- package/dist/adapters/commands/i18nPropertiesMergeCommand.js +9 -6
- package/dist/adapters/commands/omitDeletedResourcesCommand.d.ts +1 -1
- package/dist/adapters/commands/omitDeletedResourcesCommand.js +1 -1
- package/dist/adapters/commands/processPreviewResourcesCommand.d.ts +1 -1
- package/dist/adapters/commands/processPreviewResourcesCommand.js +14 -7
- package/dist/adapters/commands/renameFilesCommand.d.ts +10 -2
- package/dist/adapters/commands/renameFilesCommand.js +45 -17
- package/dist/adapters/commands/renameManifestCommand.d.ts +14 -0
- package/dist/adapters/commands/renameManifestCommand.js +32 -0
- package/dist/adapters/commands/writeResourcesCommand.d.ts +1 -1
- package/dist/adapters/commands/xsAppJsonEnhanceRoutesCommand.d.ts +1 -1
- package/dist/adapters/commands/xsAppJsonEnhanceRoutesCommand.js +4 -3
- package/dist/adapters/commands/xsAppJsonMergeCommand.d.ts +1 -1
- package/dist/adapters/commands/xsAppJsonMergeCommand.js +4 -3
- package/dist/adapters/previewAdapter.d.ts +2 -1
- package/dist/adapters/previewAdapter.js +3 -0
- package/dist/annotations/abapAnnotationManager.js +1 -1
- package/dist/annotations/dataSource/dataSourceManager.d.ts +2 -1
- package/dist/annotations/dataSource/dataSourceManager.js +16 -8
- package/dist/appVariant.d.ts +4 -3
- package/dist/appVariant.js +14 -7
- package/dist/baseApp.d.ts +3 -3
- package/dist/baseApp.js +4 -4
- package/dist/bundle.js +24 -8
- package/dist/cache/cacheHolder.d.ts +11 -2
- package/dist/cache/cacheHolder.js +23 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.js +24 -4
- package/dist/landscapeConfiguration.d.ts +3 -3
- package/dist/landscapeConfiguration.js +38 -28
- package/dist/model/types.d.ts +4 -1
- package/dist/repositories/abapProvider.js +2 -2
- package/dist/repositories/abapRepository.d.ts +1 -1
- package/dist/repositories/cacheRepository.d.ts +10 -0
- package/dist/repositories/cacheRepository.js +29 -0
- package/dist/repositories/html5Repository.d.ts +1 -1
- package/dist/repositories/localRepository.d.ts +1 -1
- package/dist/repositories/repository.d.ts +1 -1
- package/dist/util/commonUtil.d.ts +6 -1
- package/dist/util/commonUtil.js +16 -1
- package/dist/util/fsUtil.d.ts +2 -2
- package/dist/util/fsUtil.js +4 -4
- package/dist/util/manifestUtil.d.ts +6 -0
- package/dist/util/manifestUtil.js +15 -0
- package/dist/util/movingHandler/changeFileMoveHandler.d.ts +3 -3
- package/dist/util/movingHandler/changeFileMoveHandler.js +5 -4
- package/dist/util/renamingHandlers/jsonRenamingHandler.d.ts +6 -5
- package/dist/util/renamingHandlers/jsonRenamingHandler.js +15 -15
- package/dist/util/renamingUtil.d.ts +17 -0
- package/dist/util/renamingUtil.js +102 -81
- package/dist/util/resourceUtil.d.ts +15 -6
- package/dist/util/resourceUtil.js +45 -13
- package/dist/util/validator/abapConnectionValidator.d.ts +5 -0
- package/dist/util/validator/abapConnectionValidator.js +22 -0
- package/dist/util/validator/abapValidator.d.ts +2 -4
- package/dist/util/validator/abapValidator.js +4 -16
- package/dist/util/zipUtil.d.ts +1 -1
- package/dist/util/zipUtil.js +1 -1
- package/package.json +7 -7
- package/types/ui5.d.ts +2 -0
- package/dist/util/renamingHandlers/renamingHandler.d.ts +0 -4
- package/dist/util/renamingHandlers/renamingHandler.js +0 -2
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { merge } from "../../util/cf/xsAppJsonUtil.js";
|
|
2
2
|
import { MergeCommand } from "./command.js";
|
|
3
|
+
import { stringToBuffer, bufferToString } from "../../util/commonUtil.js";
|
|
3
4
|
export default class XsAppJsonMergeCommand extends MergeCommand {
|
|
4
5
|
accept = (filename) => filename === "xs-app.json";
|
|
5
6
|
async execute(files, filename, appVariantContent) {
|
|
6
7
|
const baseContent = files.get(filename);
|
|
7
8
|
const xsAppJsonFiles = [
|
|
8
|
-
appVariantContent,
|
|
9
|
-
baseContent // base app xs-app.json comes last
|
|
9
|
+
bufferToString(appVariantContent),
|
|
10
|
+
baseContent ? bufferToString(baseContent) : undefined // base app xs-app.json comes last
|
|
10
11
|
].filter(file => file !== undefined);
|
|
11
12
|
const result = merge(xsAppJsonFiles);
|
|
12
13
|
if (result) {
|
|
13
|
-
files.set(filename, result);
|
|
14
|
+
files.set(filename, stringToBuffer(result));
|
|
14
15
|
}
|
|
15
16
|
}
|
|
16
17
|
}
|
|
@@ -5,7 +5,7 @@ import { UI5BuilderTools } from "../model/types.js";
|
|
|
5
5
|
import IRepository from "../repositories/repository.js";
|
|
6
6
|
import { IAdapter } from "./adapter.js";
|
|
7
7
|
import CFAdapter from "./cfAdapter.js";
|
|
8
|
-
import { AdaptCommandChain, PostCommandChain, SetupCommandChain } from "./commands/command.js";
|
|
8
|
+
import { AdaptCommandChain, ManifestUpdateCommandChain, PostCommandChain, SetupCommandChain } from "./commands/command.js";
|
|
9
9
|
export default class PreviewAdapter implements IAdapter {
|
|
10
10
|
private configuration;
|
|
11
11
|
private cfAdapter;
|
|
@@ -14,5 +14,6 @@ export default class PreviewAdapter implements IAdapter {
|
|
|
14
14
|
constructor(configuration: IConfiguration, cfAdapter?: CFAdapter);
|
|
15
15
|
createSetupCommandChain(appId: string, repository: IRepository): SetupCommandChain;
|
|
16
16
|
createAdaptCommandChain(baseApp: BaseApp, appVariant: AppVariant): AdaptCommandChain;
|
|
17
|
+
createManifestPreviewCommandChain(baseApp: BaseApp, appVariant: AppVariant): ManifestUpdateCommandChain;
|
|
17
18
|
createPostCommandChain(references: Map<string, string>, adaptationProject: AppVariant, ui5BuilderTools: UI5BuilderTools): PostCommandChain;
|
|
18
19
|
}
|
|
@@ -25,6 +25,9 @@ export default class PreviewAdapter {
|
|
|
25
25
|
createAdaptCommandChain(baseApp, appVariant) {
|
|
26
26
|
return this.cfAdapter.createAdaptCommandChain(baseApp, appVariant);
|
|
27
27
|
}
|
|
28
|
+
createManifestPreviewCommandChain(baseApp, appVariant) {
|
|
29
|
+
return this.cfAdapter.createManifestPreviewCommandChain(baseApp, appVariant);
|
|
30
|
+
}
|
|
28
31
|
createPostCommandChain(references, adaptationProject, ui5BuilderTools) {
|
|
29
32
|
const serviceCredentialsPromise = dependsOn(this.fetchEndpointsCommand);
|
|
30
33
|
const previewPromise = dependsOn(this.fetchPreviewResourcesCommand);
|
|
@@ -22,7 +22,7 @@ export default class AbapAnnotationManager {
|
|
|
22
22
|
const i18nManager = new I18nManager(modelName, appVariantId, languages);
|
|
23
23
|
const serviceRequestor = new ServiceRequestor(this.configuration, this.repository);
|
|
24
24
|
const dataSourceManager = new DataSourceManager();
|
|
25
|
-
dataSourceManager.addDataSources(baseAppManifest["sap.app"]?.dataSources);
|
|
25
|
+
await dataSourceManager.addDataSources(baseAppManifest["sap.app"]?.dataSources);
|
|
26
26
|
const annotationFiles = await dataSourceManager.createAnnotationFiles(languages, i18nManager, serviceRequestor);
|
|
27
27
|
const i18nFiles = i18nManager.createFiles(i18nPathName);
|
|
28
28
|
if (i18nManager.hasTranslations()) {
|
|
@@ -3,10 +3,11 @@ import Language from "../../model/language.js";
|
|
|
3
3
|
import ServiceRequestor from "../serviceRequestor.js";
|
|
4
4
|
export default class DataSourceManager {
|
|
5
5
|
private dataSources;
|
|
6
|
+
private shouldDownload;
|
|
6
7
|
/**
|
|
7
8
|
* Parses dataSources from manifest.json.
|
|
8
9
|
* @param dataSourcesJson manifest.json/sap.app/dataSources node
|
|
9
10
|
*/
|
|
10
|
-
addDataSources(dataSourcesJson: any): void
|
|
11
|
+
addDataSources(dataSourcesJson: any): Promise<void>;
|
|
11
12
|
createAnnotationFiles(languages: Language[], i18nManager: I18nManager, serviceRequestor: ServiceRequestor): Promise<Map<string, string>>;
|
|
12
13
|
}
|
|
@@ -1,20 +1,26 @@
|
|
|
1
|
-
import DataSourceOData from "./dataSourceOData.js";
|
|
2
|
-
import DataSourceODataAnnotation from "./dataSourceODataAnnotation.js";
|
|
3
1
|
import path from "path/posix";
|
|
4
2
|
export default class DataSourceManager {
|
|
5
3
|
dataSources = new Array();
|
|
4
|
+
shouldDownload(dataSource, type) {
|
|
5
|
+
// is remote service, not local file
|
|
6
|
+
return dataSource.uri?.startsWith("/") &&
|
|
7
|
+
// no local metadata file and wasn't downloaded yet
|
|
8
|
+
!dataSource.settings?.ignoreAnnotationsFromMetadata &&
|
|
9
|
+
dataSource.type === type;
|
|
10
|
+
}
|
|
6
11
|
/**
|
|
7
12
|
* Parses dataSources from manifest.json.
|
|
8
13
|
* @param dataSourcesJson manifest.json/sap.app/dataSources node
|
|
9
14
|
*/
|
|
10
|
-
addDataSources(dataSourcesJson) {
|
|
15
|
+
async addDataSources(dataSourcesJson) {
|
|
11
16
|
if (!dataSourcesJson) {
|
|
12
17
|
return;
|
|
13
18
|
}
|
|
14
19
|
const odataAnnotationMap = new Map();
|
|
15
20
|
// Loop over OData first to collect linked annotation names
|
|
16
21
|
for (const [name, dataSource] of Object.entries(dataSourcesJson)) {
|
|
17
|
-
if (
|
|
22
|
+
if (this.shouldDownload(dataSource, "OData")) {
|
|
23
|
+
const { default: DataSourceOData } = await import("./dataSourceOData.js");
|
|
18
24
|
const uri = path.normalize(dataSource.uri + "/$metadata");
|
|
19
25
|
const odata = new DataSourceOData(name, uri, dataSource);
|
|
20
26
|
odata.getAnnotations().forEach(annotation => odataAnnotationMap.set(annotation, uri));
|
|
@@ -23,10 +29,12 @@ export default class DataSourceManager {
|
|
|
23
29
|
}
|
|
24
30
|
// If ODataAnnotation is in OData annotations, pass metadata url to it
|
|
25
31
|
for (const [name, dataSource] of Object.entries(dataSourcesJson)) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
32
|
+
if (this.shouldDownload(dataSource, "ODataAnnotation")) {
|
|
33
|
+
const { default: DataSourceODataAnnotation } = await import("./dataSourceODataAnnotation.js");
|
|
34
|
+
const uri = dataSource.uri;
|
|
35
|
+
const metadataUrl = odataAnnotationMap.get(name);
|
|
36
|
+
const odata = new DataSourceODataAnnotation(name, uri, dataSource, metadataUrl);
|
|
37
|
+
this.dataSources.push(odata);
|
|
30
38
|
}
|
|
31
39
|
}
|
|
32
40
|
for (const dataSource of this.dataSources) {
|
package/dist/appVariant.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { IChange } from "./model/types.js";
|
|
2
2
|
export default class AppVariant {
|
|
3
|
-
readonly files: ReadonlyMap<string,
|
|
3
|
+
readonly files: ReadonlyMap<string, Buffer>;
|
|
4
4
|
readonly resources?: ReadonlyArray<Resource>;
|
|
5
5
|
readonly id: string;
|
|
6
6
|
readonly reference: string;
|
|
@@ -10,9 +10,10 @@ export default class AppVariant {
|
|
|
10
10
|
movedFiles: Map<string, string>;
|
|
11
11
|
private renaming;
|
|
12
12
|
static fromWorkspace(workspace: IWorkspace, projectNamespace: string): Promise<AppVariant>;
|
|
13
|
-
static
|
|
13
|
+
static fromProject(): Promise<AppVariant>;
|
|
14
|
+
static fromFiles(files: ReadonlyMap<string, Buffer>): AppVariant;
|
|
14
15
|
private constructor();
|
|
15
|
-
getProcessedFiles(): ReadonlyMap<string,
|
|
16
|
+
getProcessedFiles(): ReadonlyMap<string, Buffer>;
|
|
16
17
|
/**
|
|
17
18
|
* Since we moved files, we need to update paths where they were referenced.
|
|
18
19
|
* To do this we use renameMap function along with renaming ids.
|
package/dist/appVariant.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { dotToUnderscore, isManifestChange } from "./util/commonUtil.js";
|
|
2
|
-
import ResourceUtil from "./util/resourceUtil.js";
|
|
1
|
+
import { bufferToJson, dotToUnderscore, isManifestChange } from "./util/commonUtil.js";
|
|
2
|
+
import ResourceUtil, { TEXT_EXTENSIONS } from "./util/resourceUtil.js";
|
|
3
3
|
import { posix as path } from "path";
|
|
4
4
|
import { moveFile, moveFiles } from "./util/movingHandler/changeFileMoveHandler.js";
|
|
5
5
|
import RenameFilesCommand from "./adapters/commands/renameFilesCommand.js";
|
|
@@ -16,11 +16,18 @@ export default class AppVariant {
|
|
|
16
16
|
movedFiles = new Map();
|
|
17
17
|
renaming = new Map();
|
|
18
18
|
static async fromWorkspace(workspace, projectNamespace) {
|
|
19
|
-
const EXTENSIONS_TO_PROCESS = "
|
|
19
|
+
const EXTENSIONS_TO_PROCESS = Array.from(TEXT_EXTENSIONS).join(",");
|
|
20
20
|
const resources = await workspace.byGlob(`/**/*.{${EXTENSIONS_TO_PROCESS}}`);
|
|
21
21
|
const files = await ResourceUtil.toFileMap(resources, projectNamespace);
|
|
22
22
|
return new AppVariant(files, resources);
|
|
23
23
|
}
|
|
24
|
+
static async fromProject() {
|
|
25
|
+
// previewManifest only merges manifest changes, that is why we
|
|
26
|
+
// just need the app variant descriptor and *.change files from the workspace.
|
|
27
|
+
const EXTENSIONS_TO_PROCESS = "change,appdescr_variant";
|
|
28
|
+
const files = await ResourceUtil.byGlobInProject(`/**/*.{${EXTENSIONS_TO_PROCESS}}`);
|
|
29
|
+
return new AppVariant(files);
|
|
30
|
+
}
|
|
24
31
|
static fromFiles(files) {
|
|
25
32
|
return new AppVariant(files);
|
|
26
33
|
}
|
|
@@ -30,9 +37,9 @@ export default class AppVariant {
|
|
|
30
37
|
}
|
|
31
38
|
this.files = files;
|
|
32
39
|
this.resources = resources;
|
|
33
|
-
const
|
|
34
|
-
this.validateManifest(
|
|
35
|
-
const { reference, id, layer, content } =
|
|
40
|
+
const manifestBuffer = files.get("manifest.appdescr_variant");
|
|
41
|
+
this.validateManifest(manifestBuffer);
|
|
42
|
+
const { reference, id, layer, content } = bufferToJson(manifestBuffer);
|
|
36
43
|
this.reference = reference;
|
|
37
44
|
this.id = id;
|
|
38
45
|
validateAppId(id);
|
|
@@ -70,9 +77,9 @@ export default class AppVariant {
|
|
|
70
77
|
const changeFileChanges = [];
|
|
71
78
|
this.files.forEach((content, filename) => {
|
|
72
79
|
if (filename.endsWith(CHANGES_EXT)) {
|
|
73
|
-
const change = JSON.parse(content);
|
|
74
80
|
if (isManifestChange(filename, content)) {
|
|
75
81
|
const { newFilename } = moveFile(filename, content, this.prefix, this.id);
|
|
82
|
+
const change = bufferToJson(content);
|
|
76
83
|
this.updateRelativePaths(change, newFilename);
|
|
77
84
|
changeFileChanges.push(change);
|
|
78
85
|
}
|
package/dist/baseApp.d.ts
CHANGED
|
@@ -15,13 +15,13 @@ export interface IManifestInfo extends IManifestIdVersion {
|
|
|
15
15
|
* @param files - Map of all files
|
|
16
16
|
* @returns Map with .js files replaced by -dbg.js content where applicable
|
|
17
17
|
*/
|
|
18
|
-
export declare function preProcessFiles(files: ReadonlyMap<string,
|
|
18
|
+
export declare function preProcessFiles(files: ReadonlyMap<string, Buffer>): Map<string, Buffer>;
|
|
19
19
|
export default class BaseApp {
|
|
20
20
|
readonly id: string;
|
|
21
21
|
readonly version: string;
|
|
22
22
|
readonly i18nPath: string;
|
|
23
|
-
readonly files: ReadonlyMap<string,
|
|
24
|
-
static fromFiles(files: ReadonlyMap<string,
|
|
23
|
+
readonly files: ReadonlyMap<string, Buffer>;
|
|
24
|
+
static fromFiles(files: ReadonlyMap<string, Buffer>): BaseApp;
|
|
25
25
|
private constructor();
|
|
26
26
|
private extractI18nPathFromManifest;
|
|
27
27
|
private VALIDATION_RULES;
|
package/dist/baseApp.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { trimExtension } from "./util/commonUtil.js";
|
|
1
|
+
import { bufferToJson, trimExtension } from "./util/commonUtil.js";
|
|
2
2
|
import { validateAppId } from "./util/validator/validator.js";
|
|
3
3
|
const IGNORE_FILES = [
|
|
4
4
|
"manifest-bundle.zip",
|
|
@@ -48,11 +48,11 @@ export default class BaseApp {
|
|
|
48
48
|
throw new Error("Original application sources are empty");
|
|
49
49
|
}
|
|
50
50
|
this.files = preProcessFiles(files);
|
|
51
|
-
const
|
|
52
|
-
if (!
|
|
51
|
+
const manifestBuffer = this.files.get("manifest.json");
|
|
52
|
+
if (!manifestBuffer) {
|
|
53
53
|
throw new Error("Original application should have manifest.json in root folder");
|
|
54
54
|
}
|
|
55
|
-
const manifest =
|
|
55
|
+
const manifest = bufferToJson(manifestBuffer);
|
|
56
56
|
this.id = manifest["sap.app"]?.id;
|
|
57
57
|
this.version = manifest["sap.app"]?.applicationVersion?.version;
|
|
58
58
|
this.validateProperty(this.id, "sap.app/id");
|
package/dist/bundle.js
CHANGED
|
@@ -6323,7 +6323,8 @@ _Helper = {
|
|
|
6323
6323
|
aSegments = sPath.split("/");
|
|
6324
6324
|
aSegments.pop();
|
|
6325
6325
|
while (aSegments.length) {
|
|
6326
|
-
|
|
6326
|
+
const sPrefix = aSegments.join("/");
|
|
6327
|
+
if (aAncestors.includes(sPrefix) || aAncestors.includes(sPrefix + "/*")) {
|
|
6327
6328
|
mChildren[sPath] = true;
|
|
6328
6329
|
break;
|
|
6329
6330
|
}
|
|
@@ -6503,8 +6504,20 @@ _Helper = {
|
|
|
6503
6504
|
for (const sKey in oSource) {
|
|
6504
6505
|
const vSourceProperty = oSource[sKey];
|
|
6505
6506
|
const vTargetProperty = oTarget[sKey];
|
|
6506
|
-
if (vSourceProperty && vTargetProperty
|
|
6507
|
-
|
|
6507
|
+
if (vSourceProperty && vTargetProperty) {
|
|
6508
|
+
if (Array.isArray(vSourceProperty)) {
|
|
6509
|
+
if (vTargetProperty.$byPredicate) {
|
|
6510
|
+
vSourceProperty.forEach(function (oSourceElement) {
|
|
6511
|
+
const sPredicate = _Helper.getPrivateAnnotation(oSourceElement, "predicate");
|
|
6512
|
+
const oTargetElement = vTargetProperty.$byPredicate[sPredicate];
|
|
6513
|
+
if (oTargetElement) {
|
|
6514
|
+
_Helper.copyETags(oSourceElement, oTargetElement);
|
|
6515
|
+
}
|
|
6516
|
+
});
|
|
6517
|
+
}
|
|
6518
|
+
} else if (typeof vSourceProperty === "object") {
|
|
6519
|
+
_Helper.copyETags(vSourceProperty, vTargetProperty);
|
|
6520
|
+
}
|
|
6508
6521
|
}
|
|
6509
6522
|
}
|
|
6510
6523
|
},
|
|
@@ -6583,6 +6596,9 @@ _Helper = {
|
|
|
6583
6596
|
},
|
|
6584
6597
|
createMissing: function (oObject, aSegments) {
|
|
6585
6598
|
aSegments.reduce(function (oCurrent, sSegment, i) {
|
|
6599
|
+
if (oCurrent === null) {
|
|
6600
|
+
return null;
|
|
6601
|
+
}
|
|
6586
6602
|
if (!((sSegment in oCurrent))) {
|
|
6587
6603
|
if (i + 1 < aSegments.length) {
|
|
6588
6604
|
oCurrent[sSegment] = {};
|
|
@@ -7037,7 +7053,7 @@ _Helper = {
|
|
|
7037
7053
|
},
|
|
7038
7054
|
getUsedPaths: function (aPaths, mQueryOptions) {
|
|
7039
7055
|
function isRelated(sPath0, sPath1) {
|
|
7040
|
-
return _Helper.
|
|
7056
|
+
return _Helper.isAffectedBy(sPath0, sPath1) || _Helper.isAffectedBy(sPath1, sPath0);
|
|
7041
7057
|
}
|
|
7042
7058
|
function isUsed(sPath, mQueryOptionsForPath) {
|
|
7043
7059
|
let bPathMatchedExpand = false;
|
|
@@ -7119,15 +7135,15 @@ _Helper = {
|
|
|
7119
7135
|
return i === 0 && bSkipFirstSegment || sSegment === "$count" || fnFetchMetadata(sRootMetaPath + "/" + aSegments.slice(0, i + 1).join("/")).getResult().$kind === "Property";
|
|
7120
7136
|
});
|
|
7121
7137
|
}
|
|
7122
|
-
if (aPaths.
|
|
7138
|
+
if (aPaths.includes("")) {
|
|
7123
7139
|
throw new Error("Unsupported empty navigation property path");
|
|
7124
7140
|
}
|
|
7125
|
-
if (aPaths.
|
|
7141
|
+
if (aPaths.includes("*")) {
|
|
7126
7142
|
aSelects = (mCacheQueryOptions && mCacheQueryOptions.$select || []).slice();
|
|
7127
7143
|
if (sMessagesPath && !aSelects.includes(sMessagesPath)) {
|
|
7128
7144
|
aSelects.push(sMessagesPath);
|
|
7129
7145
|
}
|
|
7130
|
-
} else if (mCacheQueryOptions && mCacheQueryOptions.$select && mCacheQueryOptions.$select.
|
|
7146
|
+
} else if (mCacheQueryOptions && mCacheQueryOptions.$select && !mCacheQueryOptions.$select.includes("*")) {
|
|
7131
7147
|
_Helper.addChildrenWithAncestor(aPaths, mCacheQueryOptions.$select, mSelects);
|
|
7132
7148
|
_Helper.addChildrenWithAncestor(mCacheQueryOptions.$select, aPaths, mSelects);
|
|
7133
7149
|
if (sMessagesPath && aPaths.includes(sMessagesPath)) {
|
|
@@ -7608,7 +7624,7 @@ _Helper = {
|
|
|
7608
7624
|
}
|
|
7609
7625
|
if (fnCheckKeyPredicate && fnCheckKeyPredicate(sPath)) {
|
|
7610
7626
|
sTargetPredicate = _Helper.getPrivateAnnotation(oTarget, "predicate");
|
|
7611
|
-
if (
|
|
7627
|
+
if (sTargetPredicate && sTargetPredicate !== sSourcePredicate) {
|
|
7612
7628
|
throw new Error("Key predicate of '" + sPath + "' changed from " + sTargetPredicate + " to " + sSourcePredicate);
|
|
7613
7629
|
}
|
|
7614
7630
|
} else {
|
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
export default class CacheHolder {
|
|
2
2
|
private static TEMP_TASK_DIR;
|
|
3
3
|
static getTempDir(...paths: string[]): string;
|
|
4
|
-
static read(repoName: string, token: string): Promise<Map<string,
|
|
5
|
-
|
|
4
|
+
static read(repoName: string, token: string): Promise<Map<string, Buffer>>;
|
|
5
|
+
/**
|
|
6
|
+
* Read the most recently cached files for the given repo, without knowing
|
|
7
|
+
* the cachebuster token up front. The @cached() decorator on
|
|
8
|
+
* IRepository.fetch calls delete(repoName) before every write, so there is
|
|
9
|
+
* at most one token subdirectory under <repoName>/ at any time.
|
|
10
|
+
* Returns an empty map if the repo has never been fetched
|
|
11
|
+
* (i.e. no full build has run yet).
|
|
12
|
+
*/
|
|
13
|
+
static readLatest(repoName: string): Promise<Map<string, Buffer>>;
|
|
14
|
+
static write(repoName: string, token: string, files: Map<string, Buffer>): Promise<void>;
|
|
6
15
|
private static isValid;
|
|
7
16
|
/**
|
|
8
17
|
* Clears cached files by repo name and token
|
|
@@ -18,6 +18,28 @@ export default class CacheHolder {
|
|
|
18
18
|
}
|
|
19
19
|
return Promise.resolve(new Map());
|
|
20
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* Read the most recently cached files for the given repo, without knowing
|
|
23
|
+
* the cachebuster token up front. The @cached() decorator on
|
|
24
|
+
* IRepository.fetch calls delete(repoName) before every write, so there is
|
|
25
|
+
* at most one token subdirectory under <repoName>/ at any time.
|
|
26
|
+
* Returns an empty map if the repo has never been fetched
|
|
27
|
+
* (i.e. no full build has run yet).
|
|
28
|
+
*/
|
|
29
|
+
static async readLatest(repoName) {
|
|
30
|
+
if (!this.isValid(repoName, "repoName")) {
|
|
31
|
+
throw new Error(`Cache read requires 'repoName' to be provided`);
|
|
32
|
+
}
|
|
33
|
+
const repoDir = this.getTempDir(repoName);
|
|
34
|
+
if (!fs.existsSync(repoDir)) {
|
|
35
|
+
throw new Error(`No cache found for '${repoName}'. Run a full build first.`);
|
|
36
|
+
}
|
|
37
|
+
const [tokenDir] = await fsPromises.readdir(repoDir);
|
|
38
|
+
if (!tokenDir) {
|
|
39
|
+
throw new Error(`Cache directory for '${repoName}' is empty. Run a full build first.`);
|
|
40
|
+
}
|
|
41
|
+
return ResourceUtil.byGlob(path.join(repoDir, tokenDir), "**/*");
|
|
42
|
+
}
|
|
21
43
|
static async write(repoName, token, files) {
|
|
22
44
|
this.delete(repoName);
|
|
23
45
|
if (this.isValid(repoName, "repoName") && this.isValid(token, "token")) {
|
|
@@ -74,7 +96,7 @@ export function cached() {
|
|
|
74
96
|
let files = await CacheHolder.read(appName, token);
|
|
75
97
|
CacheHolder.clearOutdatedExcept(appName);
|
|
76
98
|
if (files.size === 0) {
|
|
77
|
-
log.verbose(`No cache for repo '${appName}' with token '${token}'. Fetching from
|
|
99
|
+
log.verbose(`No cache for repo '${appName}' with token '${token}'. Fetching from repository.`);
|
|
78
100
|
files = await originalValue.apply(this, args);
|
|
79
101
|
await CacheHolder.write(appName, token, files);
|
|
80
102
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,5 +2,14 @@ import { ITaskParameters } from "./model/types.js";
|
|
|
2
2
|
/**
|
|
3
3
|
* Creates an appVariant bundle from the provided resources.
|
|
4
4
|
*/
|
|
5
|
-
declare const _default: ({ workspace, options, taskUtil }: ITaskParameters) => Promise<ReadonlyMap<string,
|
|
5
|
+
declare const _default: ({ workspace, options, taskUtil }: ITaskParameters) => Promise<ReadonlyMap<string, Buffer<ArrayBufferLike>>>;
|
|
6
6
|
export default _default;
|
|
7
|
+
/**
|
|
8
|
+
* Preview-time entry point (CF only). Produces the same manifest.json a
|
|
9
|
+
* full build would produce, without going to the HTML5 Repo.
|
|
10
|
+
* Precondition is a full build must have run at least once so the base app
|
|
11
|
+
* files are cached by the @cached() decorator on HTML5Repository.fetch. If
|
|
12
|
+
* the cache is empty, this throws with a message directing the user to run
|
|
13
|
+
* a full build first.
|
|
14
|
+
*/
|
|
15
|
+
export declare function previewManifest({ options }: ITaskParameters): Promise<any>;
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as dotenv from "dotenv";
|
|
2
|
-
import { getReferences, logBuilderVersion } from "./util/commonUtil.js";
|
|
2
|
+
import { bufferToString, getReferences, logBuilderVersion } from "./util/commonUtil.js";
|
|
3
3
|
import AppVariant from "./appVariant.js";
|
|
4
4
|
import BaseApp from "./baseApp.js";
|
|
5
5
|
import { initialize } from "./landscapeConfiguration.js";
|
|
@@ -14,7 +14,7 @@ export default async ({ workspace, options, taskUtil }) => {
|
|
|
14
14
|
};
|
|
15
15
|
dotenv.config();
|
|
16
16
|
logBuilderVersion();
|
|
17
|
-
const { repository, adapter } = initialize(options.configuration);
|
|
17
|
+
const { repository, adapter } = await initialize(options.configuration);
|
|
18
18
|
const adaptationProject = await AppVariant.fromWorkspace(workspace, options.projectNamespace);
|
|
19
19
|
const setupCommandChain = adapter.createSetupCommandChain(adaptationProject.reference, repository);
|
|
20
20
|
await setupCommandChain.execute();
|
|
@@ -34,11 +34,31 @@ export default async ({ workspace, options, taskUtil }) => {
|
|
|
34
34
|
return adapter.createAdaptCommandChain(baseApp, appVariant).execute();
|
|
35
35
|
};
|
|
36
36
|
let files = await fetchFilesPromises.shift(); // original app files
|
|
37
|
-
for (const
|
|
38
|
-
|
|
37
|
+
for (const appVariantFilesPromise of fetchFilesPromises) {
|
|
38
|
+
const appVariantFiles = await appVariantFilesPromise;
|
|
39
|
+
files = await adapt(files, AppVariant.fromFiles(appVariantFiles));
|
|
39
40
|
}
|
|
40
41
|
files = await adapt(files, adaptationProject);
|
|
41
42
|
const references = getReferences(appVariants, adaptationProject.id);
|
|
42
43
|
return adapter.createPostCommandChain(references, adaptationProject, ui5BuilderTools).execute(files);
|
|
43
44
|
};
|
|
45
|
+
/**
|
|
46
|
+
* Preview-time entry point (CF only). Produces the same manifest.json a
|
|
47
|
+
* full build would produce, without going to the HTML5 Repo.
|
|
48
|
+
* Precondition is a full build must have run at least once so the base app
|
|
49
|
+
* files are cached by the @cached() decorator on HTML5Repository.fetch. If
|
|
50
|
+
* the cache is empty, this throws with a message directing the user to run
|
|
51
|
+
* a full build first.
|
|
52
|
+
*/
|
|
53
|
+
export async function previewManifest({ options }) {
|
|
54
|
+
const { repository, adapter } = await initialize(options.configuration, { useCacheRepository: true });
|
|
55
|
+
const adaptationProject = await AppVariant.fromProject();
|
|
56
|
+
const [baseAppResource] = await repository.getAppVariantIdHierarchy(adaptationProject.reference);
|
|
57
|
+
const cachedBaseAppFiles = await repository.fetch(baseAppResource);
|
|
58
|
+
const baseApp = BaseApp.fromFiles(cachedBaseAppFiles);
|
|
59
|
+
const files = new Map(cachedBaseAppFiles);
|
|
60
|
+
const manifestPreviewCommandChain = adapter.createManifestPreviewCommandChain(baseApp, adaptationProject);
|
|
61
|
+
await manifestPreviewCommandChain.execute(files, "manifest.json");
|
|
62
|
+
return JSON.parse(bufferToString(files.get("manifest.json")));
|
|
63
|
+
}
|
|
44
64
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { IConfiguration } from "./model/types.js";
|
|
1
|
+
import { IConfiguration, IInitializeOptions } from "./model/types.js";
|
|
2
2
|
import { IAdapter } from "./adapters/adapter.js";
|
|
3
3
|
import IRepository from "./repositories/repository.js";
|
|
4
4
|
import IAnnotationManager from "./annotations/annotationManager.js";
|
|
5
|
-
export declare function initialize(configuration: IConfiguration): {
|
|
5
|
+
export declare function initialize(configuration: IConfiguration, options?: IInitializeOptions): Promise<{
|
|
6
6
|
adapter: IAdapter;
|
|
7
7
|
repository: IRepository;
|
|
8
8
|
annotationManager: IAnnotationManager;
|
|
9
|
-
}
|
|
9
|
+
}>;
|
|
@@ -1,39 +1,31 @@
|
|
|
1
|
-
import AbapAdapter from "./adapters/abapAdapter.js";
|
|
2
|
-
import CFAdapter from "./adapters/cfAdapter.js";
|
|
3
|
-
import PreviewAdapter from "./adapters/previewAdapter.js";
|
|
4
|
-
import AbapRepository from "./repositories/abapRepository.js";
|
|
5
|
-
import HTML5Repository from "./repositories/html5Repository.js";
|
|
6
|
-
import LocalRepository from "./repositories/localRepository.js";
|
|
7
|
-
import AbapAnnotationManager from "./annotations/abapAnnotationManager.js";
|
|
8
|
-
import CFAnnotationManager from "./annotations/cfAnnotationManager.js";
|
|
9
1
|
import CFValidator from "./util/validator/cfValidator.js";
|
|
10
|
-
import AbapValidator from "./util/validator/abapValidator.js";
|
|
11
2
|
import { isOneOf } from "./util/validator/validator.js";
|
|
12
3
|
import { LANDSCAPE_TYPES } from "./model/configuration.js";
|
|
13
4
|
import { getLogger } from "@ui5/logger";
|
|
5
|
+
import AbapValidator from "./util/validator/abapValidator.js";
|
|
14
6
|
import LocalAnnotationManager from "./annotations/localAnnotationManager.js";
|
|
15
7
|
const log = getLogger("@ui5/task-adaptation::LandscapeConfiguration");
|
|
16
|
-
export function initialize(configuration) {
|
|
17
|
-
const type = getTypeByConfiguration(configuration);
|
|
8
|
+
export async function initialize(configuration, options = {}) {
|
|
9
|
+
const type = await getTypeByConfiguration(configuration);
|
|
18
10
|
const enhancedConfig = { ...configuration, type };
|
|
19
|
-
const repository = getRepository(enhancedConfig);
|
|
20
|
-
const annotationManager = getAnnotationManager(enhancedConfig, repository);
|
|
11
|
+
const repository = await getRepository(enhancedConfig, options);
|
|
12
|
+
const annotationManager = await getAnnotationManager(enhancedConfig, repository);
|
|
21
13
|
return {
|
|
22
|
-
adapter: getAdapter(enhancedConfig, annotationManager),
|
|
14
|
+
adapter: await getAdapter(enhancedConfig, annotationManager),
|
|
23
15
|
repository,
|
|
24
16
|
annotationManager
|
|
25
17
|
};
|
|
26
18
|
}
|
|
27
|
-
function getTypeByConfiguration(configuration) {
|
|
28
|
-
const validators = [
|
|
29
|
-
new CFValidator(),
|
|
30
|
-
new AbapValidator(),
|
|
31
|
-
];
|
|
19
|
+
async function getTypeByConfiguration(configuration) {
|
|
32
20
|
if (isOneOf(LANDSCAPE_TYPES, configuration.type)) {
|
|
33
21
|
return configuration.type;
|
|
34
22
|
}
|
|
35
23
|
else {
|
|
36
24
|
log.warn("Deprecated behavior: type is not specified or invalid. Should be either 'cf' or 'abap'. Trying to detect the type based on provided configuration");
|
|
25
|
+
const validators = [
|
|
26
|
+
new CFValidator(),
|
|
27
|
+
new AbapValidator(),
|
|
28
|
+
];
|
|
37
29
|
for (const validator of validators) {
|
|
38
30
|
try {
|
|
39
31
|
validator.validateConfiguration(configuration);
|
|
@@ -46,41 +38,59 @@ function getTypeByConfiguration(configuration) {
|
|
|
46
38
|
throw new Error("'type' should be specified in ui5.yaml configuration: 'cf' or 'abap'");
|
|
47
39
|
}
|
|
48
40
|
}
|
|
49
|
-
function getAdapter(configuration, annotationManager) {
|
|
41
|
+
async function getAdapter(configuration, annotationManager) {
|
|
50
42
|
if (isPreview()) {
|
|
43
|
+
const { default: PreviewAdapter } = await import("./adapters/previewAdapter.js");
|
|
51
44
|
return new PreviewAdapter(configuration);
|
|
52
45
|
}
|
|
53
46
|
switch (configuration.type) {
|
|
54
|
-
case "abap":
|
|
47
|
+
case "abap": {
|
|
48
|
+
const { default: AbapAdapter } = await import("./adapters/abapAdapter.js");
|
|
55
49
|
return new AbapAdapter(annotationManager);
|
|
56
|
-
|
|
50
|
+
}
|
|
51
|
+
case "cf": {
|
|
52
|
+
const { default: CFAdapter } = await import("./adapters/cfAdapter.js");
|
|
57
53
|
return new CFAdapter(configuration);
|
|
54
|
+
}
|
|
58
55
|
default:
|
|
59
56
|
throw new Error(`No adapter found for the given configuration type '${configuration.type}'`);
|
|
60
57
|
}
|
|
61
58
|
}
|
|
62
|
-
function getRepository(configuration) {
|
|
59
|
+
async function getRepository(configuration, options) {
|
|
60
|
+
if (options.useCacheRepository) {
|
|
61
|
+
const { default: CacheRepository } = await import("./repositories/cacheRepository.js");
|
|
62
|
+
return new CacheRepository(configuration);
|
|
63
|
+
}
|
|
63
64
|
if (isLocal()) {
|
|
65
|
+
const { default: LocalRepository } = await import("./repositories/localRepository.js");
|
|
64
66
|
return new LocalRepository();
|
|
65
67
|
}
|
|
66
68
|
switch (configuration.type) {
|
|
67
|
-
case "abap":
|
|
69
|
+
case "abap": {
|
|
70
|
+
const { default: AbapRepository } = await import("./repositories/abapRepository.js");
|
|
68
71
|
return new AbapRepository(configuration);
|
|
69
|
-
|
|
72
|
+
}
|
|
73
|
+
case "cf": {
|
|
74
|
+
const { default: HTML5Repository } = await import("./repositories/html5Repository.js");
|
|
70
75
|
return new HTML5Repository(configuration);
|
|
76
|
+
}
|
|
71
77
|
default:
|
|
72
78
|
throw new Error(`No repository found for the given configuration type '${configuration.type}'`);
|
|
73
79
|
}
|
|
74
80
|
}
|
|
75
|
-
function getAnnotationManager(configuration, repository) {
|
|
81
|
+
async function getAnnotationManager(configuration, repository) {
|
|
76
82
|
if (isLocal()) {
|
|
77
83
|
return new LocalAnnotationManager();
|
|
78
84
|
}
|
|
79
85
|
switch (configuration.type) {
|
|
80
|
-
case "abap":
|
|
86
|
+
case "abap": {
|
|
87
|
+
const { default: AbapAnnotationManager } = await import("./annotations/abapAnnotationManager.js");
|
|
81
88
|
return new AbapAnnotationManager(configuration, repository);
|
|
82
|
-
|
|
89
|
+
}
|
|
90
|
+
case "cf": {
|
|
91
|
+
const { default: CFAnnotationManager } = await import("./annotations/cfAnnotationManager.js");
|
|
83
92
|
return new CFAnnotationManager();
|
|
93
|
+
}
|
|
84
94
|
default:
|
|
85
95
|
throw new Error(`No annotation manager found for the given configuration type '${configuration.type}'`);
|
|
86
96
|
}
|
package/dist/model/types.d.ts
CHANGED
|
@@ -129,5 +129,8 @@ export type ServiceCredentials = {
|
|
|
129
129
|
} | string>;
|
|
130
130
|
"sap.cloud.service"?: string;
|
|
131
131
|
};
|
|
132
|
-
export type FetchFilesPromise = Map<string, Promise<ReadonlyMap<string,
|
|
132
|
+
export type FetchFilesPromise = Map<string, Promise<ReadonlyMap<string, Buffer>>>;
|
|
133
133
|
export { IConfiguration };
|
|
134
|
+
export interface IInitializeOptions {
|
|
135
|
+
useCacheRepository?: boolean;
|
|
136
|
+
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { createAbapServiceProvider } from "@sap-ux/system-access";
|
|
2
2
|
import { getLogger } from "@ui5/logger";
|
|
3
|
-
import
|
|
3
|
+
import AbapConnectionValidator from "../util/validator/abapConnectionValidator.js";
|
|
4
4
|
const log = getLogger("@ui5/task-adaptation::AbapProvider");
|
|
5
5
|
log.debug = (message) => log.verbose(message);
|
|
6
6
|
export default class AbapProvider {
|
|
7
7
|
provider = null;
|
|
8
|
-
abapValidator = new
|
|
8
|
+
abapValidator = new AbapConnectionValidator();
|
|
9
9
|
async get({ target, destination }) {
|
|
10
10
|
if (!this.provider) {
|
|
11
11
|
const abapTarget = this.abapValidator.validateAndGetAbapTarget(target, destination);
|
|
@@ -11,6 +11,6 @@ export default class AbapRepository implements IRepository {
|
|
|
11
11
|
getAnnotationMetadata(uri: string): Promise<IMetadata>;
|
|
12
12
|
downloadAnnotationFile(uri: string): Promise<Map<string, any>>;
|
|
13
13
|
getMetadata(id: string): Promise<IMetadata>;
|
|
14
|
-
fetch(resource: IAbapResource): Promise<Map<string,
|
|
14
|
+
fetch(resource: IAbapResource): Promise<Map<string, Buffer>>;
|
|
15
15
|
}
|
|
16
16
|
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import ICachedResource from "../cache/cachedResource.js";
|
|
2
|
+
import { IConfiguration } from "../model/types.js";
|
|
3
|
+
import IRepository from "./repository.js";
|
|
4
|
+
export default class CacheRepository implements IRepository {
|
|
5
|
+
private configuration;
|
|
6
|
+
constructor(configuration: IConfiguration);
|
|
7
|
+
getAppVariantIdHierarchy(_appId: string): Promise<ICachedResource[]>;
|
|
8
|
+
fetch(resource: ICachedResource): Promise<Map<string, Buffer>>;
|
|
9
|
+
downloadAnnotationFile(uri: string): Promise<Map<string, string>>;
|
|
10
|
+
}
|