@ui5/task-adaptation 1.6.8 → 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 +41 -39
- 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 -6
- package/dist/appVariant.js +9 -16
- package/dist/baseApp.d.ts +1 -0
- package/dist/baseApp.js +10 -0
- package/dist/bundle.js +39 -27
- 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 +5 -6
- package/dist/index.js +47 -40
- 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 +0 -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/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/package.json +4 -3
- 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/bundle.js
CHANGED
|
@@ -4342,8 +4342,9 @@ _KeyPredicateParser.prototype.parse = function (sKeyPredicate) {
|
|
|
4342
4342
|
this.finish();
|
|
4343
4343
|
return oKeyProperties;
|
|
4344
4344
|
};
|
|
4345
|
-
function _SystemQueryOptionParser() {
|
|
4345
|
+
function _SystemQueryOptionParser(bParseFilter) {
|
|
4346
4346
|
_Parser.apply(this, arguments);
|
|
4347
|
+
this.oFilterParser = bParseFilter ? new _FilterParser() : undefined;
|
|
4347
4348
|
}
|
|
4348
4349
|
_SystemQueryOptionParser.prototype = Object.create(_Parser.prototype);
|
|
4349
4350
|
_SystemQueryOptionParser.prototype.parse = function (sOption) {
|
|
@@ -4429,10 +4430,17 @@ _SystemQueryOptionParser.prototype.parseSelect = function () {
|
|
|
4429
4430
|
};
|
|
4430
4431
|
};
|
|
4431
4432
|
_SystemQueryOptionParser.prototype.parseSystemQueryOption = function () {
|
|
4432
|
-
|
|
4433
|
+
const oToken = this.advance("OPTION");
|
|
4433
4434
|
switch (oToken.value) {
|
|
4434
4435
|
case "$expand":
|
|
4435
4436
|
return this.parseExpand();
|
|
4437
|
+
case "$filter":
|
|
4438
|
+
{
|
|
4439
|
+
const oRaw = this.parseAnythingWithBrackets(oToken);
|
|
4440
|
+
return this.oFilterParser ? {
|
|
4441
|
+
$filter: this.oFilterParser.parse(oRaw.$filter)
|
|
4442
|
+
} : oRaw;
|
|
4443
|
+
}
|
|
4436
4444
|
case "$select":
|
|
4437
4445
|
return this.parseSelect();
|
|
4438
4446
|
default:
|
|
@@ -4567,8 +4575,8 @@ var _Parser$1 = {
|
|
|
4567
4575
|
parseKeyPredicate: function (sKeyPredicate) {
|
|
4568
4576
|
return new _KeyPredicateParser().parse(sKeyPredicate);
|
|
4569
4577
|
},
|
|
4570
|
-
parseSystemQueryOption: function (sOption) {
|
|
4571
|
-
return new _SystemQueryOptionParser().parse(sOption);
|
|
4578
|
+
parseSystemQueryOption: function (sOption, bParseFilter) {
|
|
4579
|
+
return new _SystemQueryOptionParser(bParseFilter).parse(sOption);
|
|
4572
4580
|
},
|
|
4573
4581
|
sODataIdentifier: sODataIdentifier,
|
|
4574
4582
|
sWhitespace: sWhitespace
|
|
@@ -5151,7 +5159,7 @@ class LanguageTag {
|
|
|
5151
5159
|
this.variant = (aResult[4] && aResult[4].slice(1)) || null; // remove leading hyphen from capturing group
|
|
5152
5160
|
this.variantSubtags = this.variant ? this.variant.split('-') : [];
|
|
5153
5161
|
this.extension = (aResult[5] && aResult[5].slice(1)) || null; // remove leading hyphen from capturing group
|
|
5154
|
-
this.extensionSubtags = this.
|
|
5162
|
+
this.extensionSubtags = this.extension ? this.extension.split('-') : [];
|
|
5155
5163
|
this.privateUse = aResult[6] || null;
|
|
5156
5164
|
this.privateUseSubtags = this.privateUse ? this.privateUse.slice(2).split('-') : [];
|
|
5157
5165
|
// convert subtags according to the BCP47 recommendations
|
|
@@ -6847,7 +6855,7 @@ _Helper = {
|
|
|
6847
6855
|
});
|
|
6848
6856
|
_Helper.fireChange(mChangeListeners, sPath, bRemoved ? undefined : oValue);
|
|
6849
6857
|
},
|
|
6850
|
-
formatLiteral: function (vValue, sType) {
|
|
6858
|
+
formatLiteral: function (vValue, sType, oTypeMetadata) {
|
|
6851
6859
|
if (vValue === undefined) {
|
|
6852
6860
|
throw new Error("Illegal value: undefined");
|
|
6853
6861
|
}
|
|
@@ -6877,6 +6885,9 @@ _Helper = {
|
|
|
6877
6885
|
case "Edm.String":
|
|
6878
6886
|
return "'" + String(vValue).replace(rSingleQuote, "''") + "'";
|
|
6879
6887
|
default:
|
|
6888
|
+
if (oTypeMetadata?.$kind === "EnumType") {
|
|
6889
|
+
return sType + "'" + vValue + "'";
|
|
6890
|
+
}
|
|
6880
6891
|
throw new Error("Unsupported type: " + sType);
|
|
6881
6892
|
}
|
|
6882
6893
|
},
|
|
@@ -7007,7 +7018,7 @@ _Helper = {
|
|
|
7007
7018
|
return sPath.replace(rNotMetaContext, "").slice(1);
|
|
7008
7019
|
},
|
|
7009
7020
|
getMissingPropertyPaths: function (vEntityOrCollection, mQueryOptions) {
|
|
7010
|
-
return (mQueryOptions.$select
|
|
7021
|
+
return (mQueryOptions.$select ?? []).concat(Object.keys(mQueryOptions.$expand ?? ({}))).filter(function (sPath) {
|
|
7011
7022
|
return _Helper.isMissingProperty(vEntityOrCollection, sPath);
|
|
7012
7023
|
});
|
|
7013
7024
|
},
|
|
@@ -7044,7 +7055,7 @@ _Helper = {
|
|
|
7044
7055
|
}
|
|
7045
7056
|
});
|
|
7046
7057
|
}
|
|
7047
|
-
return mQueryOptions
|
|
7058
|
+
return mQueryOptions ?? ({});
|
|
7048
7059
|
},
|
|
7049
7060
|
getRelativePath: function (sPath, sBasePath) {
|
|
7050
7061
|
if (sBasePath.length) {
|
|
@@ -7078,8 +7089,8 @@ _Helper = {
|
|
|
7078
7089
|
}
|
|
7079
7090
|
function isUsed(sPath, mQueryOptionsForPath) {
|
|
7080
7091
|
let bPathMatchedExpand = false;
|
|
7081
|
-
const aSelect = mQueryOptionsForPath.$select
|
|
7082
|
-
const mExpand = mQueryOptionsForPath.$expand
|
|
7092
|
+
const aSelect = mQueryOptionsForPath.$select ?? ["*"];
|
|
7093
|
+
const mExpand = mQueryOptionsForPath.$expand ?? ({});
|
|
7083
7094
|
return sPath === "*" || (sPath in mExpand) || aSelect.includes(sPath) || aSelect.some(sSelect => isRelated(sPath, sSelect)) || Object.keys(mExpand).some(sExpand => {
|
|
7084
7095
|
if (_Helper.hasPathPrefix(sPath, sExpand)) {
|
|
7085
7096
|
bPathMatchedExpand = true;
|
|
@@ -7160,7 +7171,7 @@ _Helper = {
|
|
|
7160
7171
|
throw new Error("Unsupported empty navigation property path");
|
|
7161
7172
|
}
|
|
7162
7173
|
if (aPaths.includes("*")) {
|
|
7163
|
-
aSelects =
|
|
7174
|
+
aSelects = mCacheQueryOptions?.$select?.slice() ?? [];
|
|
7164
7175
|
if (sMessagesPath && !aSelects.includes(sMessagesPath)) {
|
|
7165
7176
|
aSelects.push(sMessagesPath);
|
|
7166
7177
|
}
|
|
@@ -7188,7 +7199,7 @@ _Helper = {
|
|
|
7188
7199
|
if (fnFetchMetadata(sMetaPath).getResult().$isCollection) {
|
|
7189
7200
|
throw new Error("Unsupported collection-valued navigation property " + sMetaPath);
|
|
7190
7201
|
}
|
|
7191
|
-
mChildQueryOptions = _Helper.intersectQueryOptions(mCacheQueryOptions.$expand[sNavigationPropertyPath]
|
|
7202
|
+
mChildQueryOptions = _Helper.intersectQueryOptions(mCacheQueryOptions.$expand[sNavigationPropertyPath] ?? ({}), aStrippedPaths, fnFetchMetadata, sMetaPath, sPrefixedNavigationPropertyPath);
|
|
7192
7203
|
if (mChildQueryOptions) {
|
|
7193
7204
|
mExpands[sNavigationPropertyPath] = mChildQueryOptions;
|
|
7194
7205
|
}
|
|
@@ -7421,14 +7432,14 @@ _Helper = {
|
|
|
7421
7432
|
return mHeaders;
|
|
7422
7433
|
},
|
|
7423
7434
|
restoreUpdatingProperties: function (oOld, oNew) {
|
|
7424
|
-
|
|
7425
|
-
Object.keys(oOld || ({})).forEach(function (sProperty) {
|
|
7435
|
+
for (const sProperty in oOld) {
|
|
7426
7436
|
if (sProperty.startsWith("@")) {
|
|
7427
|
-
|
|
7437
|
+
continue;
|
|
7428
7438
|
}
|
|
7429
7439
|
if (Array.isArray(oOld[sProperty])) {
|
|
7430
|
-
|
|
7440
|
+
continue;
|
|
7431
7441
|
}
|
|
7442
|
+
const oTempNew = oNew ?? ({});
|
|
7432
7443
|
if (typeof oOld[sProperty] === "object") {
|
|
7433
7444
|
oTempNew[sProperty] = _Helper.restoreUpdatingProperties(oOld[sProperty], oTempNew[sProperty]);
|
|
7434
7445
|
}
|
|
@@ -7437,7 +7448,7 @@ _Helper = {
|
|
|
7437
7448
|
oTempNew[sProperty + "@$ui5.updating"] = oOld[sProperty + "@$ui5.updating"];
|
|
7438
7449
|
oNew = oTempNew;
|
|
7439
7450
|
}
|
|
7440
|
-
}
|
|
7451
|
+
}
|
|
7441
7452
|
return oNew;
|
|
7442
7453
|
},
|
|
7443
7454
|
selectKeyProperties: function (mQueryOptions, oType) {
|
|
@@ -7506,7 +7517,7 @@ _Helper = {
|
|
|
7506
7517
|
oTarget[sProperty] = vSourceProperty;
|
|
7507
7518
|
_Helper.fireChange(mChangeListeners, sPropertyPath, vSourceProperty, false, true);
|
|
7508
7519
|
} else if (vSourceProperty && typeof vSourceProperty === "object") {
|
|
7509
|
-
vTargetProperty = oTarget[sProperty] = _Helper.updateAll(mChangeListeners, sPropertyPath, vTargetProperty
|
|
7520
|
+
vTargetProperty = oTarget[sProperty] = _Helper.updateAll(mChangeListeners, sPropertyPath, vTargetProperty ?? ({}), vSourceProperty);
|
|
7510
7521
|
_Helper.fireChange(mChangeListeners, sPropertyPath, vTargetProperty);
|
|
7511
7522
|
} else if (vTargetProperty !== vSourceProperty) {
|
|
7512
7523
|
oTarget[sProperty] = vSourceProperty;
|
|
@@ -7560,19 +7571,20 @@ _Helper = {
|
|
|
7560
7571
|
updateNestedCreates: function (mChangeListeners, mQueryOptions, sPath, oTargetEntity, oCreatedEntity, mSelectForMetaPath) {
|
|
7561
7572
|
let bDeepCreate = false;
|
|
7562
7573
|
const mQueryOptionsForEntity = _Helper.getQueryOptionsForPath(mQueryOptions, sPath);
|
|
7563
|
-
|
|
7574
|
+
for (const sExpandPath in mQueryOptionsForEntity.$expand) {
|
|
7564
7575
|
const oNestedTargetEntity = _Helper.drillDown(oTargetEntity, sExpandPath);
|
|
7565
7576
|
if (oNestedTargetEntity && !Array.isArray(oNestedTargetEntity)) {
|
|
7566
7577
|
bDeepCreate = true;
|
|
7567
7578
|
}
|
|
7568
|
-
}
|
|
7569
|
-
|
|
7570
|
-
|
|
7571
|
-
|
|
7579
|
+
}
|
|
7580
|
+
for (const sSegment in mSelectForMetaPath) {
|
|
7581
|
+
if (sSegment.includes("/")) {
|
|
7582
|
+
continue;
|
|
7583
|
+
}
|
|
7572
7584
|
const aNestedCreatedEntities = oCreatedEntity[sSegment];
|
|
7573
7585
|
if (!aNestedCreatedEntities) {
|
|
7574
7586
|
delete oTargetEntity[sSegment];
|
|
7575
|
-
|
|
7587
|
+
continue;
|
|
7576
7588
|
}
|
|
7577
7589
|
oTargetEntity[sSegment] = aNestedCreatedEntities;
|
|
7578
7590
|
aNestedCreatedEntities.$count = undefined;
|
|
@@ -7596,7 +7608,7 @@ _Helper = {
|
|
|
7596
7608
|
_Helper.updateNestedCreates(mChangeListeners, mQueryOptions, sCollectionPath + sPredicate, oCreatedChildEntity, oCreatedChildEntity, mSelectForChildMetaPath);
|
|
7597
7609
|
});
|
|
7598
7610
|
bDeepCreate = true;
|
|
7599
|
-
}
|
|
7611
|
+
}
|
|
7600
7612
|
return bDeepCreate;
|
|
7601
7613
|
},
|
|
7602
7614
|
updateNonExisting: function (oTarget, oSource) {
|
|
@@ -7657,7 +7669,7 @@ _Helper = {
|
|
|
7657
7669
|
_Helper.fireChange(mChangeListeners, sPropertyPath, vSourceProperty, false, true);
|
|
7658
7670
|
}
|
|
7659
7671
|
} else if (vSourceProperty && typeof vSourceProperty === "object" && !sProperty.includes("@")) {
|
|
7660
|
-
oTarget[sProperty] = update(sPropertyPath, vSelected, vTargetProperty
|
|
7672
|
+
oTarget[sProperty] = update(sPropertyPath, vSelected, vTargetProperty ?? ({}), vSourceProperty);
|
|
7661
7673
|
_Helper.fireChange(mChangeListeners, sPropertyPath, vSourceProperty);
|
|
7662
7674
|
} else if (vTargetProperty !== vSourceProperty && !oTarget[sProperty + "@$ui5.updating"]) {
|
|
7663
7675
|
oTarget[sProperty] = vSourceProperty;
|
|
@@ -8728,7 +8740,7 @@ _V2MetadataConverter.prototype.postProcessSchema = function (_oElement, _aResult
|
|
|
8728
8740
|
continue;
|
|
8729
8741
|
}
|
|
8730
8742
|
sTarget = sEntityContainerName + "/" + sEntitySetName;
|
|
8731
|
-
mAnnotations = _Helper$1.merge(this.convertedV2Annotations[sTarget]
|
|
8743
|
+
mAnnotations = _Helper$1.merge(this.convertedV2Annotations[sTarget] ?? ({}), this.mEntityType2EntitySetAnnotation[oEntitySet.$Type]);
|
|
8732
8744
|
if (!_Helper$1.isEmptyObject(mAnnotations)) {
|
|
8733
8745
|
this.convertedV2Annotations[sTarget] = mAnnotations;
|
|
8734
8746
|
}
|
|
@@ -1,18 +1,12 @@
|
|
|
1
|
+
import ICachedResource from "./cachedResource.js";
|
|
1
2
|
export default class CacheHolder {
|
|
2
3
|
private static TEMP_TASK_DIR;
|
|
4
|
+
private static MERGED_DIR;
|
|
3
5
|
static getTempDir(...paths: string[]): string;
|
|
4
|
-
static
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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>;
|
|
15
|
-
private static isValid;
|
|
6
|
+
static hasDirectory(resource: ICachedResource): Promise<boolean>;
|
|
7
|
+
static read(resource: ICachedResource): Promise<Map<string, Buffer>>;
|
|
8
|
+
static write(resource: ICachedResource, files: Map<string, Buffer>): Promise<void>;
|
|
9
|
+
static mergedResource(reference: string): ICachedResource;
|
|
16
10
|
/**
|
|
17
11
|
* Clears cached files by repo name and token
|
|
18
12
|
*/
|
|
@@ -8,50 +8,38 @@ import { getLogger } from "@ui5/logger";
|
|
|
8
8
|
const log = getLogger("@ui5/task-adaptation::CacheHolder");
|
|
9
9
|
export default class CacheHolder {
|
|
10
10
|
static TEMP_TASK_DIR = "ui5-task-adaptation";
|
|
11
|
+
static MERGED_DIR = "merged";
|
|
11
12
|
static getTempDir(...paths) {
|
|
12
13
|
return path.join(os.tmpdir(), this.TEMP_TASK_DIR, ...paths.map(part => encodeFilename(part, { replacement: "_" })));
|
|
13
14
|
}
|
|
14
|
-
static
|
|
15
|
-
const directory = this.getTempDir(
|
|
16
|
-
|
|
17
|
-
return ResourceUtil.byGlob(directory, "**/*");
|
|
18
|
-
}
|
|
19
|
-
return Promise.resolve(new Map());
|
|
15
|
+
static async hasDirectory(resource) {
|
|
16
|
+
const directory = this.getTempDir(resource.appName, await resource.token);
|
|
17
|
+
return fs.existsSync(directory);
|
|
20
18
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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`);
|
|
19
|
+
static async read(resource) {
|
|
20
|
+
const directory = this.getTempDir(resource.appName, await resource.token);
|
|
21
|
+
if (!await this.hasDirectory(resource)) {
|
|
22
|
+
log.verbose(`No cache directory '${directory}' found`);
|
|
23
|
+
return new Map();
|
|
32
24
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
25
|
+
return ResourceUtil.byGlob(directory, "**/*");
|
|
26
|
+
}
|
|
27
|
+
static async write(resource, files) {
|
|
28
|
+
const token = await resource.token;
|
|
29
|
+
if (resource.appName == null || token == null) {
|
|
30
|
+
log.verbose(`No 'appName' or 'token' provided, skipping cache write`);
|
|
31
|
+
return;
|
|
36
32
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
throw new Error(`Cache directory for '${repoName}' is empty. Run a full build first.`);
|
|
33
|
+
if (!resource.keepAppNameDir) {
|
|
34
|
+
this.delete(resource.appName);
|
|
40
35
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
static async write(repoName, token, files) {
|
|
44
|
-
this.delete(repoName);
|
|
45
|
-
if (this.isValid(repoName, "repoName") && this.isValid(token, "token")) {
|
|
46
|
-
await ResourceUtil.write(this.getTempDir(repoName, token), files);
|
|
36
|
+
else {
|
|
37
|
+
this.delete(resource.appName, token);
|
|
47
38
|
}
|
|
39
|
+
await ResourceUtil.write(this.getTempDir(resource.appName, token), files);
|
|
48
40
|
}
|
|
49
|
-
static
|
|
50
|
-
|
|
51
|
-
log.warn(`No '${name}' provided, skipping cache write`);
|
|
52
|
-
return false;
|
|
53
|
-
}
|
|
54
|
-
return true;
|
|
41
|
+
static mergedResource(reference) {
|
|
42
|
+
return { appName: reference, token: Promise.resolve(this.MERGED_DIR), keepAppNameDir: true };
|
|
55
43
|
}
|
|
56
44
|
/**
|
|
57
45
|
* Clears cached files by repo name and token
|
|
@@ -91,14 +79,14 @@ export function cached() {
|
|
|
91
79
|
const originalValue = descriptor.value;
|
|
92
80
|
descriptor.value = async function (...args) {
|
|
93
81
|
const cachedResource = args[0];
|
|
94
|
-
|
|
95
|
-
const
|
|
96
|
-
|
|
82
|
+
let files = await CacheHolder.read(cachedResource);
|
|
83
|
+
const appName = cachedResource.appName;
|
|
84
|
+
const token = await cachedResource.token;
|
|
97
85
|
CacheHolder.clearOutdatedExcept(appName);
|
|
98
86
|
if (files.size === 0) {
|
|
99
87
|
log.verbose(`No cache for repo '${appName}' with token '${token}'. Fetching from repository.`);
|
|
100
88
|
files = await originalValue.apply(this, args);
|
|
101
|
-
await CacheHolder.write(
|
|
89
|
+
await CacheHolder.write(cachedResource, files);
|
|
102
90
|
}
|
|
103
91
|
else {
|
|
104
92
|
log.verbose(`Using cached files for repo '${appName}' with token '${token}'.`);
|
package/dist/index.d.ts
CHANGED
|
@@ -5,11 +5,10 @@ import { ITaskParameters } from "./model/types.js";
|
|
|
5
5
|
declare const _default: ({ workspace, options, taskUtil }: ITaskParameters) => Promise<ReadonlyMap<string, Buffer<ArrayBufferLike>>>;
|
|
6
6
|
export default _default;
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
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.
|
|
8
|
+
* Produces the manifest.json a full build would produce, without a full UI5 build.
|
|
14
9
|
*/
|
|
15
10
|
export declare function previewManifest({ workspace, options }: ITaskParameters): Promise<any>;
|
|
11
|
+
/**
|
|
12
|
+
* Downloads the base app and all resources along the app-variant hierarchy and writes the merged files to `outputDir`.
|
|
13
|
+
*/
|
|
14
|
+
export declare function downloadAppResources({ workspace, options }: ITaskParameters, outputDir: string): Promise<void>;
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import * as dotenv from "dotenv";
|
|
2
|
-
import {
|
|
2
|
+
import { bufferToJson, logBuilderVersion } from "./util/commonUtil.js";
|
|
3
3
|
import AppVariant from "./appVariant.js";
|
|
4
4
|
import BaseApp from "./baseApp.js";
|
|
5
|
+
import CacheHolder from "./cache/cacheHolder.js";
|
|
6
|
+
import ResourceUtil from "./util/resourceUtil.js";
|
|
7
|
+
import ReferencesBuilder from "./util/referencesBuilder.js";
|
|
5
8
|
import { initialize } from "./landscapeConfiguration.js";
|
|
6
9
|
/**
|
|
7
10
|
* Creates an appVariant bundle from the provided resources.
|
|
@@ -14,51 +17,55 @@ export default async ({ workspace, options, taskUtil }) => {
|
|
|
14
17
|
};
|
|
15
18
|
dotenv.config();
|
|
16
19
|
logBuilderVersion();
|
|
17
|
-
const {
|
|
20
|
+
const { adapter, repository } = await initialize(options.configuration);
|
|
18
21
|
const adaptationProject = await AppVariant.fromWorkspace(workspace, options.projectNamespace);
|
|
19
|
-
const
|
|
20
|
-
await
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
// appVariantIdHierarchy contains original application on bottom and the
|
|
26
|
-
// latest app variant on top. We reverse the list to process original
|
|
27
|
-
// application first and then app variants in chronological order.
|
|
28
|
-
const reversedHierarchy = appVariantIdHierarchy.toReversed();
|
|
29
|
-
const fetchFilesPromises = reversedHierarchy.map(variant => repository.fetch(variant));
|
|
30
|
-
const appVariants = new Array();
|
|
31
|
-
const adapt = async (baseFiles, appVariant) => {
|
|
32
|
-
appVariants.push(appVariant);
|
|
33
|
-
const baseApp = BaseApp.fromFiles(baseFiles);
|
|
34
|
-
return adapter.createAdaptCommandChain(baseApp, appVariant).execute();
|
|
35
|
-
};
|
|
36
|
-
let files = await fetchFilesPromises.shift(); // original app files
|
|
37
|
-
for (const appVariantFilesPromise of fetchFilesPromises) {
|
|
38
|
-
const appVariantFiles = await appVariantFilesPromise;
|
|
39
|
-
files = await adapt(files, AppVariant.fromFiles(appVariantFiles));
|
|
40
|
-
}
|
|
41
|
-
files = await adapt(files, adaptationProject);
|
|
42
|
-
const references = getReferences(appVariants, adaptationProject.id);
|
|
22
|
+
const { files: baseFiles } = await foldBaseHierarchy(adapter, repository, adaptationProject.reference);
|
|
23
|
+
await CacheHolder.write(CacheHolder.mergedResource(adaptationProject.reference), new Map(baseFiles));
|
|
24
|
+
const files = await adapter.createAdaptCommandChain(baseFiles, adaptationProject).execute();
|
|
25
|
+
const references = new ReferencesBuilder()
|
|
26
|
+
.addReferences(files, adaptationProject.id)
|
|
27
|
+
.build();
|
|
43
28
|
return adapter.createPostCommandChain(references, adaptationProject, ui5BuilderTools).execute(files);
|
|
44
29
|
};
|
|
45
30
|
/**
|
|
46
|
-
*
|
|
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.
|
|
31
|
+
* Produces the manifest.json a full build would produce, without a full UI5 build.
|
|
52
32
|
*/
|
|
53
33
|
export async function previewManifest({ workspace, options }) {
|
|
54
|
-
const {
|
|
34
|
+
const { adapter, repository } = await initialize(options.configuration, { useCache: true });
|
|
35
|
+
const adaptationProject = await AppVariant.fromWorkspace(workspace, options.projectNamespace);
|
|
36
|
+
const { files: baseFiles } = await foldBaseHierarchy(adapter, repository, adaptationProject.reference);
|
|
37
|
+
await CacheHolder.write(CacheHolder.mergedResource(adaptationProject.reference), new Map(baseFiles));
|
|
38
|
+
const baseApp = BaseApp.fromFiles(baseFiles);
|
|
39
|
+
const references = new ReferencesBuilder()
|
|
40
|
+
.addReference(adaptationProject.reference, adaptationProject.id)
|
|
41
|
+
.addReferences(baseFiles, adaptationProject.id)
|
|
42
|
+
.build();
|
|
43
|
+
const files = new Map(baseFiles);
|
|
44
|
+
await adapter.createManifestPreviewCommandChain(baseApp, adaptationProject, references).execute(files, "manifest.json");
|
|
45
|
+
return bufferToJson(files.get("manifest.json"));
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Downloads the base app and all resources along the app-variant hierarchy and writes the merged files to `outputDir`.
|
|
49
|
+
*/
|
|
50
|
+
export async function downloadAppResources({ workspace, options }, outputDir) {
|
|
51
|
+
const { adapter, repository } = await initialize(options.configuration);
|
|
55
52
|
const adaptationProject = await AppVariant.fromWorkspace(workspace, options.projectNamespace);
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
await
|
|
62
|
-
|
|
53
|
+
const { files } = await foldBaseHierarchy(adapter, repository, adaptationProject.reference);
|
|
54
|
+
await ResourceUtil.write(outputDir, new Map(files));
|
|
55
|
+
}
|
|
56
|
+
async function foldBaseHierarchy(adapter, repository, reference) {
|
|
57
|
+
await adapter.createSetupCommandChain(reference, repository).execute();
|
|
58
|
+
const hierarchy = await repository.getAppVariantIdHierarchy(reference);
|
|
59
|
+
if (hierarchy.length === 0) {
|
|
60
|
+
throw new Error(`No app variant found for reference ${reference}`);
|
|
61
|
+
}
|
|
62
|
+
const fetchFilesPromises = hierarchy.toReversed()
|
|
63
|
+
.map(variant => repository.fetch(variant));
|
|
64
|
+
let files = await fetchFilesPromises.shift(); // original base app files
|
|
65
|
+
for (const filesPromise of fetchFilesPromises) {
|
|
66
|
+
const appVariant = AppVariant.fromFiles(await filesPromise);
|
|
67
|
+
files = await adapter.createAdaptCommandChain(files, appVariant).execute();
|
|
68
|
+
}
|
|
69
|
+
return { files };
|
|
63
70
|
}
|
|
64
71
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { IConfiguration
|
|
1
|
+
import { IConfiguration } from "./model/types.js";
|
|
2
2
|
import { IAdapter } from "./adapters/adapter.js";
|
|
3
3
|
import IRepository from "./repositories/repository.js";
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
export declare function initialize(configuration: IConfiguration, options?: {
|
|
5
|
+
useCache?: boolean;
|
|
6
|
+
}): Promise<{
|
|
6
7
|
adapter: IAdapter;
|
|
7
8
|
repository: IRepository;
|
|
8
|
-
annotationManager: IAnnotationManager;
|
|
9
9
|
}>;
|
|
@@ -8,12 +8,16 @@ const log = getLogger("@ui5/task-adaptation::LandscapeConfiguration");
|
|
|
8
8
|
export async function initialize(configuration, options = {}) {
|
|
9
9
|
const type = await getTypeByConfiguration(configuration);
|
|
10
10
|
const enhancedConfig = { ...configuration, type };
|
|
11
|
-
|
|
11
|
+
let repository = await getRepository(enhancedConfig);
|
|
12
12
|
const annotationManager = await getAnnotationManager(enhancedConfig, repository);
|
|
13
|
+
if (options.useCache) {
|
|
14
|
+
const { default: CacheRepository } = await import("./repositories/cacheRepository.js");
|
|
15
|
+
repository = new CacheRepository(repository);
|
|
16
|
+
}
|
|
17
|
+
const adapter = await getAdapter(enhancedConfig, annotationManager);
|
|
13
18
|
return {
|
|
14
|
-
adapter
|
|
15
|
-
repository
|
|
16
|
-
annotationManager
|
|
19
|
+
adapter,
|
|
20
|
+
repository
|
|
17
21
|
};
|
|
18
22
|
}
|
|
19
23
|
async function getTypeByConfiguration(configuration) {
|
|
@@ -38,62 +42,62 @@ async function getTypeByConfiguration(configuration) {
|
|
|
38
42
|
throw new Error("'type' should be specified in ui5.yaml configuration: 'cf' or 'abap'");
|
|
39
43
|
}
|
|
40
44
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
return new PreviewAdapter(configuration);
|
|
45
|
-
}
|
|
46
|
-
switch (configuration.type) {
|
|
47
|
-
case "abap": {
|
|
45
|
+
const LANDSCAPE_FACTORIES = {
|
|
46
|
+
abap: {
|
|
47
|
+
adapter: async (_configuration, annotationManager) => {
|
|
48
48
|
const { default: AbapAdapter } = await import("./adapters/abapAdapter.js");
|
|
49
49
|
return new AbapAdapter(annotationManager);
|
|
50
|
-
}
|
|
51
|
-
|
|
50
|
+
},
|
|
51
|
+
repository: async (configuration) => {
|
|
52
|
+
const { default: AbapRepository } = await import("./repositories/abapRepository.js");
|
|
53
|
+
return new AbapRepository(configuration);
|
|
54
|
+
},
|
|
55
|
+
annotationManager: async (configuration, repository) => {
|
|
56
|
+
const { default: AbapAnnotationManager } = await import("./annotations/abapAnnotationManager.js");
|
|
57
|
+
return new AbapAnnotationManager(configuration, repository);
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
cf: {
|
|
61
|
+
adapter: async (configuration) => {
|
|
52
62
|
const { default: CFAdapter } = await import("./adapters/cfAdapter.js");
|
|
53
63
|
return new CFAdapter(configuration);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
|
|
64
|
+
},
|
|
65
|
+
repository: async (configuration) => {
|
|
66
|
+
const { default: HTML5Repository } = await import("./repositories/html5Repository.js");
|
|
67
|
+
return new HTML5Repository(configuration);
|
|
68
|
+
},
|
|
69
|
+
annotationManager: async () => {
|
|
70
|
+
const { default: CFAnnotationManager } = await import("./annotations/cfAnnotationManager.js");
|
|
71
|
+
return new CFAnnotationManager();
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
function landscapeFactory(configuration) {
|
|
76
|
+
const factory = LANDSCAPE_FACTORIES[configuration.type];
|
|
77
|
+
if (!factory) {
|
|
78
|
+
throw new Error(`No landscape factory found for the given configuration type '${configuration.type}'`);
|
|
57
79
|
}
|
|
80
|
+
return factory;
|
|
58
81
|
}
|
|
59
|
-
async function
|
|
60
|
-
if (
|
|
61
|
-
const { default:
|
|
62
|
-
return new
|
|
82
|
+
async function getAdapter(configuration, annotationManager) {
|
|
83
|
+
if (isPreview()) {
|
|
84
|
+
const { default: PreviewAdapter } = await import("./adapters/previewAdapter.js");
|
|
85
|
+
return new PreviewAdapter(configuration);
|
|
63
86
|
}
|
|
87
|
+
return landscapeFactory(configuration).adapter(configuration, annotationManager);
|
|
88
|
+
}
|
|
89
|
+
async function getRepository(configuration) {
|
|
64
90
|
if (isLocal()) {
|
|
65
91
|
const { default: LocalRepository } = await import("./repositories/localRepository.js");
|
|
66
92
|
return new LocalRepository();
|
|
67
93
|
}
|
|
68
|
-
|
|
69
|
-
case "abap": {
|
|
70
|
-
const { default: AbapRepository } = await import("./repositories/abapRepository.js");
|
|
71
|
-
return new AbapRepository(configuration);
|
|
72
|
-
}
|
|
73
|
-
case "cf": {
|
|
74
|
-
const { default: HTML5Repository } = await import("./repositories/html5Repository.js");
|
|
75
|
-
return new HTML5Repository(configuration);
|
|
76
|
-
}
|
|
77
|
-
default:
|
|
78
|
-
throw new Error(`No repository found for the given configuration type '${configuration.type}'`);
|
|
79
|
-
}
|
|
94
|
+
return landscapeFactory(configuration).repository(configuration);
|
|
80
95
|
}
|
|
81
96
|
async function getAnnotationManager(configuration, repository) {
|
|
82
97
|
if (isLocal()) {
|
|
83
98
|
return new LocalAnnotationManager();
|
|
84
99
|
}
|
|
85
|
-
|
|
86
|
-
case "abap": {
|
|
87
|
-
const { default: AbapAnnotationManager } = await import("./annotations/abapAnnotationManager.js");
|
|
88
|
-
return new AbapAnnotationManager(configuration, repository);
|
|
89
|
-
}
|
|
90
|
-
case "cf": {
|
|
91
|
-
const { default: CFAnnotationManager } = await import("./annotations/cfAnnotationManager.js");
|
|
92
|
-
return new CFAnnotationManager();
|
|
93
|
-
}
|
|
94
|
-
default:
|
|
95
|
-
throw new Error(`No annotation manager found for the given configuration type '${configuration.type}'`);
|
|
96
|
-
}
|
|
100
|
+
return landscapeFactory(configuration).annotationManager(configuration, repository);
|
|
97
101
|
}
|
|
98
102
|
function isLocal() {
|
|
99
103
|
return process.env.ADP_BUILDER_MODE === "local";
|
package/dist/model/types.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export default class AbapRepository implements IRepository {
|
|
|
9
9
|
constructor(configuration: IConfiguration, abapProvider?: AbapProvider);
|
|
10
10
|
getAppVariantIdHierarchy(id: string): Promise<IAbapResource[]>;
|
|
11
11
|
getAnnotationMetadata(uri: string): Promise<IMetadata>;
|
|
12
|
-
downloadAnnotationFile(uri: string): Promise<
|
|
12
|
+
downloadAnnotationFile(uri: string): Promise<any>;
|
|
13
13
|
getMetadata(id: string): Promise<IMetadata>;
|
|
14
14
|
fetch(resource: IAbapResource): Promise<Map<string, Buffer>>;
|
|
15
15
|
}
|
|
@@ -37,14 +37,14 @@ export default class AbapRepository {
|
|
|
37
37
|
const hierarchy = JSON.parse(response.data)?.appVariantIdHierarchy;
|
|
38
38
|
return hierarchy.map(item => ({
|
|
39
39
|
appName: item.repoName,
|
|
40
|
-
|
|
40
|
+
token: Promise.resolve(item.cachebusterToken)
|
|
41
41
|
}));
|
|
42
42
|
}
|
|
43
43
|
else if (this.configuration.appName) {
|
|
44
44
|
// Fallback to old API on old ABAP backend or CF for backward compatibility
|
|
45
45
|
return [{
|
|
46
46
|
appName: this.configuration.appName,
|
|
47
|
-
|
|
47
|
+
token: this.getMetadata(id).then(metadata => metadata.changedOn),
|
|
48
48
|
}];
|
|
49
49
|
}
|
|
50
50
|
throw new Error(`App variant id hierarchy for app id '${id}' is not provided`);
|
|
@@ -59,7 +59,7 @@ export default class AbapRepository {
|
|
|
59
59
|
const response = await provider.get(uri, {
|
|
60
60
|
headers: REQUEST_OPTIONS_XML.headers
|
|
61
61
|
});
|
|
62
|
-
return
|
|
62
|
+
return response.data;
|
|
63
63
|
}
|
|
64
64
|
async getMetadata(id) {
|
|
65
65
|
const provider = await this.abapProvider.get(this.configuration);
|