@ui5/task-adaptation 1.5.0 → 1.5.2-rc.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/CHANGELOG.md +8 -4
- package/dist/annotationManager.d.ts +1 -2
- package/dist/annotationManager.js +4 -8
- package/dist/appVariantManager.d.ts +15 -0
- package/dist/appVariantManager.js +49 -6
- package/dist/baseAppManager.d.ts +9 -1
- package/dist/baseAppManager.js +56 -16
- package/dist/bundle.js +97 -59
- package/dist/index.js +40 -17
- package/dist/model/configuration.d.ts +1 -0
- package/dist/processors/abapProcessor.d.ts +1 -1
- package/dist/processors/abapProcessor.js +2 -2
- package/dist/processors/cfProcessor.d.ts +3 -1
- package/dist/processors/cfProcessor.js +51 -2
- package/dist/processors/processor.d.ts +1 -1
- package/dist/util/cfUtil.d.ts +47 -0
- package/dist/util/cfUtil.js +121 -0
- package/dist/util/commonUtil.d.ts +1 -3
- package/dist/util/commonUtil.js +8 -104
- package/dist/util/filesUtil.d.ts +11 -12
- package/dist/util/filesUtil.js +65 -31
- package/dist/util/i18nMerger.js +3 -3
- package/dist/util/movingHandler/fileMoveHandler.d.ts +8 -0
- package/dist/util/movingHandler/fileMoveHandler.js +77 -0
- package/dist/util/renamingHandlers/{manifestHandler.d.ts → manifestRenamingHandler.d.ts} +1 -1
- package/dist/util/renamingHandlers/{manifestHandler.js → manifestRenamingHandler.js} +2 -2
- package/dist/util/renamingUtil.d.ts +3 -0
- package/dist/util/renamingUtil.js +111 -0
- package/package.json +124 -126
- package/scripts/rollup/overrides/sap/base/config.js +52 -14
- package/scripts/rollup.ts +1 -2
package/dist/bundle.js
CHANGED
|
@@ -4955,30 +4955,31 @@ var FilterOperator = {
|
|
|
4955
4955
|
EndsWith: "EndsWith",
|
|
4956
4956
|
NotEndsWith: "NotEndsWith",
|
|
4957
4957
|
All: "All",
|
|
4958
|
-
|
|
4958
|
+
NotAll: "NotAll",
|
|
4959
|
+
Any: "Any",
|
|
4960
|
+
NotAny: "NotAny"
|
|
4959
4961
|
};
|
|
4960
4962
|
|
|
4961
|
-
|
|
4962
|
-
|
|
4963
|
-
|
|
4964
|
-
|
|
4965
|
-
|
|
4966
|
-
|
|
4967
|
-
|
|
4968
|
-
|
|
4969
|
-
|
|
4970
|
-
|
|
4971
|
-
|
|
4972
|
-
return {
|
|
4973
|
-
get(obj) {
|
|
4974
|
-
config.get(obj.name);
|
|
4975
|
-
},
|
|
4976
|
-
set(name, obj) {
|
|
4977
|
-
config.set(name, obj);
|
|
4978
|
-
}
|
|
4979
|
-
}
|
|
4963
|
+
const _Configuration = {
|
|
4964
|
+
_: {}
|
|
4965
|
+
};
|
|
4966
|
+
const internalConfig = new Map();
|
|
4967
|
+
_Configuration.getWritableInstance = () => {
|
|
4968
|
+
return {
|
|
4969
|
+
get(obj) {
|
|
4970
|
+
internalConfig.get(obj.name);
|
|
4971
|
+
},
|
|
4972
|
+
set(name, obj) {
|
|
4973
|
+
internalConfig.set(name, obj);
|
|
4980
4974
|
}
|
|
4981
|
-
}
|
|
4975
|
+
};
|
|
4976
|
+
};
|
|
4977
|
+
function attachInvalidated() {}
|
|
4978
|
+
_Configuration._.attachInvalidated = attachInvalidated;
|
|
4979
|
+
const origInvalidate = _Configuration._.invalidate;
|
|
4980
|
+
_Configuration._.invalidate = () => {
|
|
4981
|
+
origInvalidate();
|
|
4982
|
+
};
|
|
4982
4983
|
|
|
4983
4984
|
class Eventing {
|
|
4984
4985
|
#mEventRegistry = {};
|
|
@@ -5210,6 +5211,11 @@ class LanguageTag {
|
|
|
5210
5211
|
*/
|
|
5211
5212
|
privateUseSubtags;
|
|
5212
5213
|
|
|
5214
|
+
/**
|
|
5215
|
+
* @private
|
|
5216
|
+
*/
|
|
5217
|
+
#tagAsString;
|
|
5218
|
+
|
|
5213
5219
|
constructor(sLanguageTag) {
|
|
5214
5220
|
var aResult = rLanguageTag.exec(sLanguageTag.replace(/_/g, "-"));
|
|
5215
5221
|
// If the given language tag string cannot be parsed by the regular expression above,
|
|
@@ -5241,16 +5247,17 @@ class LanguageTag {
|
|
|
5241
5247
|
if ( this.region ) {
|
|
5242
5248
|
this.region = this.region.toUpperCase();
|
|
5243
5249
|
}
|
|
5244
|
-
|
|
5245
|
-
}
|
|
5246
|
-
toString() {
|
|
5247
|
-
return this.#join(
|
|
5250
|
+
this.#tagAsString = this.#join(
|
|
5248
5251
|
this.language,
|
|
5249
5252
|
this.script,
|
|
5250
5253
|
this.region,
|
|
5251
5254
|
this.variant,
|
|
5252
5255
|
this.extension,
|
|
5253
5256
|
this.privateUse);
|
|
5257
|
+
Object.freeze(this);
|
|
5258
|
+
}
|
|
5259
|
+
toString() {
|
|
5260
|
+
return this.#tagAsString;
|
|
5254
5261
|
}
|
|
5255
5262
|
#join() {
|
|
5256
5263
|
return Array.prototype.filter.call(arguments, Boolean).join("-");
|
|
@@ -5550,11 +5557,15 @@ TimezoneUtils._clearLocalTimezoneCache = function () {
|
|
|
5550
5557
|
sLocalTimezone = "";
|
|
5551
5558
|
};
|
|
5552
5559
|
|
|
5553
|
-
const oWritableConfig =
|
|
5560
|
+
const oWritableConfig = _Configuration.getWritableInstance();
|
|
5554
5561
|
let sLanguageSetByApi;
|
|
5555
5562
|
const oEventing = new Eventing();
|
|
5563
|
+
let mCache = Object.create(null);
|
|
5556
5564
|
let mChanges;
|
|
5557
5565
|
let bLanguageWarningLogged = false;
|
|
5566
|
+
_Configuration._.attachInvalidated(() => {
|
|
5567
|
+
mCache = Object.create(null);
|
|
5568
|
+
});
|
|
5558
5569
|
const _mPreferredCalendar = {
|
|
5559
5570
|
"ar-SA": CalendarType.Islamic,
|
|
5560
5571
|
"fa": CalendarType.Persian,
|
|
@@ -5615,9 +5626,11 @@ function createLanguageTag(sLanguage) {
|
|
|
5615
5626
|
}
|
|
5616
5627
|
return oLanguageTag;
|
|
5617
5628
|
}
|
|
5618
|
-
function
|
|
5619
|
-
return globalThis.navigator
|
|
5620
|
-
}
|
|
5629
|
+
const detectLanguage = globalThis.navigator ? function () {
|
|
5630
|
+
return globalThis.navigator.languages?.[0] || globalThis.navigator.language || "en";
|
|
5631
|
+
} : function () {
|
|
5632
|
+
return new Intl.Collator().resolvedOptions().locale || "en";
|
|
5633
|
+
};
|
|
5621
5634
|
function check(bCondition, sMessage) {
|
|
5622
5635
|
if (!bCondition) {
|
|
5623
5636
|
throw new TypeError(sMessage);
|
|
@@ -5643,29 +5656,32 @@ const Localization = {
|
|
|
5643
5656
|
getActiveTerminologies: function () {
|
|
5644
5657
|
return oWritableConfig.get({
|
|
5645
5658
|
name: "sapUiActiveTerminologies",
|
|
5646
|
-
type:
|
|
5659
|
+
type: _Configuration.Type.StringArray,
|
|
5647
5660
|
defaultValue: undefined,
|
|
5648
5661
|
external: true
|
|
5649
5662
|
});
|
|
5650
5663
|
},
|
|
5651
5664
|
getLanguage: function () {
|
|
5652
5665
|
let oLanguageTag, sDerivedLanguage;
|
|
5666
|
+
if (mCache.language) {
|
|
5667
|
+
return mCache.language;
|
|
5668
|
+
}
|
|
5653
5669
|
if (sLanguageSetByApi) {
|
|
5654
5670
|
return sLanguageSetByApi;
|
|
5655
5671
|
}
|
|
5656
5672
|
const sLanguage = oWritableConfig.get({
|
|
5657
5673
|
name: "sapUiLanguage",
|
|
5658
|
-
type:
|
|
5674
|
+
type: _Configuration.Type.String,
|
|
5659
5675
|
external: true
|
|
5660
5676
|
});
|
|
5661
5677
|
const sSapLocale = oWritableConfig.get({
|
|
5662
5678
|
name: "sapLocale",
|
|
5663
|
-
type:
|
|
5679
|
+
type: _Configuration.Type.String,
|
|
5664
5680
|
external: true
|
|
5665
5681
|
});
|
|
5666
5682
|
const sSapLanguage = oWritableConfig.get({
|
|
5667
5683
|
name: "sapLanguage",
|
|
5668
|
-
type:
|
|
5684
|
+
type: _Configuration.Type.String,
|
|
5669
5685
|
external: true
|
|
5670
5686
|
});
|
|
5671
5687
|
if (sSapLocale) {
|
|
@@ -5680,14 +5696,15 @@ const Localization = {
|
|
|
5680
5696
|
}
|
|
5681
5697
|
if (!oLanguageTag) {
|
|
5682
5698
|
if (sLanguage) {
|
|
5683
|
-
|
|
5699
|
+
createLanguageTag(sLanguage);
|
|
5684
5700
|
sDerivedLanguage = sLanguage;
|
|
5685
5701
|
} else {
|
|
5686
5702
|
sDerivedLanguage = detectLanguage();
|
|
5687
|
-
|
|
5703
|
+
createLanguageTag(sLanguage);
|
|
5688
5704
|
}
|
|
5689
5705
|
}
|
|
5690
|
-
|
|
5706
|
+
mCache.language = sDerivedLanguage;
|
|
5707
|
+
return mCache.language;
|
|
5691
5708
|
},
|
|
5692
5709
|
getModernLanguage: function (sLanguage) {
|
|
5693
5710
|
return M_ISO639_OLD_TO_NEW[sLanguage] || sLanguage;
|
|
@@ -5699,7 +5716,7 @@ const Localization = {
|
|
|
5699
5716
|
sSAPLogonLanguage = sSAPLogonLanguage || "";
|
|
5700
5717
|
if (oLanguageTag.toString() != Localization.getLanguageTag().toString() || sSAPLogonLanguage !== oWritableConfig.get({
|
|
5701
5718
|
name: "sapLanguage",
|
|
5702
|
-
type:
|
|
5719
|
+
type: _Configuration.Type.String,
|
|
5703
5720
|
external: true
|
|
5704
5721
|
})) {
|
|
5705
5722
|
oWritableConfig.set("sapLanguage", sSAPLogonLanguage);
|
|
@@ -5714,20 +5731,24 @@ const Localization = {
|
|
|
5714
5731
|
}
|
|
5715
5732
|
},
|
|
5716
5733
|
getTimezone: function () {
|
|
5734
|
+
if (mCache.timezone) {
|
|
5735
|
+
return mCache.timezone;
|
|
5736
|
+
}
|
|
5717
5737
|
let sTimezone = oWritableConfig.get({
|
|
5718
5738
|
name: "sapTimezone",
|
|
5719
|
-
type:
|
|
5739
|
+
type: _Configuration.Type.String,
|
|
5720
5740
|
external: true,
|
|
5721
5741
|
defaultValue: oWritableConfig.get({
|
|
5722
5742
|
name: "sapUiTimezone",
|
|
5723
|
-
type:
|
|
5743
|
+
type: _Configuration.Type.String,
|
|
5724
5744
|
external: true
|
|
5725
5745
|
})
|
|
5726
5746
|
});
|
|
5727
5747
|
if (!sTimezone || !checkTimezone(sTimezone)) {
|
|
5728
5748
|
sTimezone = TimezoneUtils.getLocalTimezone();
|
|
5729
5749
|
}
|
|
5730
|
-
|
|
5750
|
+
mCache.timezone = sTimezone;
|
|
5751
|
+
return mCache.timezone;
|
|
5731
5752
|
},
|
|
5732
5753
|
setTimezone: function (sTimezone) {
|
|
5733
5754
|
check(sTimezone == null || typeof sTimezone === "string", "Localization.setTimezone: sTimezone must be null or be a string");
|
|
@@ -5741,6 +5762,9 @@ const Localization = {
|
|
|
5741
5762
|
}
|
|
5742
5763
|
},
|
|
5743
5764
|
getLanguageTag: function () {
|
|
5765
|
+
if (mCache.languageTag) {
|
|
5766
|
+
return mCache.languageTag;
|
|
5767
|
+
}
|
|
5744
5768
|
const oLanguageTag = new LanguageTag(Localization.getLanguage());
|
|
5745
5769
|
const sLanguage = Localization.getModernLanguage(oLanguageTag.language);
|
|
5746
5770
|
const sScript = oLanguageTag.script;
|
|
@@ -5750,22 +5774,27 @@ const Localization = {
|
|
|
5750
5774
|
} else {
|
|
5751
5775
|
sLanguageTag = sLanguageTag.replace(oLanguageTag.language, sLanguage);
|
|
5752
5776
|
}
|
|
5753
|
-
|
|
5777
|
+
mCache.languageTag = new LanguageTag(sLanguageTag);
|
|
5778
|
+
return mCache.languageTag;
|
|
5754
5779
|
},
|
|
5755
5780
|
getRTL: function () {
|
|
5756
|
-
|
|
5781
|
+
if (mCache.rtl) {
|
|
5782
|
+
return mCache.rtl;
|
|
5783
|
+
}
|
|
5784
|
+
mCache.rtl = oWritableConfig.get({
|
|
5757
5785
|
name: "sapRtl",
|
|
5758
|
-
type:
|
|
5786
|
+
type: _Configuration.Type.Boolean,
|
|
5759
5787
|
external: true,
|
|
5760
5788
|
defaultValue: oWritableConfig.get({
|
|
5761
5789
|
name: "sapUiRtl",
|
|
5762
|
-
type:
|
|
5790
|
+
type: _Configuration.Type.Boolean,
|
|
5763
5791
|
defaultValue: function () {
|
|
5764
5792
|
return impliesRTL(Localization.getLanguageTag());
|
|
5765
5793
|
},
|
|
5766
5794
|
external: true
|
|
5767
5795
|
})
|
|
5768
5796
|
});
|
|
5797
|
+
return mCache.rtl;
|
|
5769
5798
|
},
|
|
5770
5799
|
setRTL: function (bRTL) {
|
|
5771
5800
|
check(bRTL === null || typeof bRTL === "boolean", "bRTL must be null or a boolean");
|
|
@@ -5794,7 +5823,7 @@ const Localization = {
|
|
|
5794
5823
|
let oLanguageTag;
|
|
5795
5824
|
const sLanguage = oWritableConfig.get({
|
|
5796
5825
|
name: "sapLanguage",
|
|
5797
|
-
type:
|
|
5826
|
+
type: _Configuration.Type.String,
|
|
5798
5827
|
external: true
|
|
5799
5828
|
}).toUpperCase();
|
|
5800
5829
|
try {
|
|
@@ -5813,9 +5842,9 @@ const Localization = {
|
|
|
5813
5842
|
return _coreI18nLocales;
|
|
5814
5843
|
},
|
|
5815
5844
|
getSupportedLanguages: function () {
|
|
5816
|
-
let aLangs =
|
|
5845
|
+
let aLangs = _Configuration.get({
|
|
5817
5846
|
name: "sapUiXxSupportedLanguages",
|
|
5818
|
-
type:
|
|
5847
|
+
type: _Configuration.Type.StringArray,
|
|
5819
5848
|
external: true
|
|
5820
5849
|
});
|
|
5821
5850
|
if (aLangs.length === 0 || aLangs.length === 1 && aLangs[0] === "*") {
|
|
@@ -5870,8 +5899,8 @@ var Filter = BaseObject.extend("sap.ui.model.Filter", {
|
|
|
5870
5899
|
}
|
|
5871
5900
|
this.oValue1 = vValue1;
|
|
5872
5901
|
this.oValue2 = vValue2;
|
|
5873
|
-
if (this.sOperator === FilterOperator.Any || this.sOperator === FilterOperator.All) {
|
|
5874
|
-
throw new Error("The filter operators 'Any' and '
|
|
5902
|
+
if (this.sOperator === FilterOperator.Any || this.sOperator === FilterOperator.All || this.sOperator === FilterOperator.NotAny || this.sOperator === FilterOperator.NotAll) {
|
|
5903
|
+
throw new Error("The filter operators 'Any', 'All', 'NotAny', and 'NotAll' are only supported with " + "the parameter object notation.");
|
|
5875
5904
|
}
|
|
5876
5905
|
}
|
|
5877
5906
|
if (this.aFilters?.includes(Filter.NONE)) {
|
|
@@ -5879,13 +5908,13 @@ var Filter = BaseObject.extend("sap.ui.model.Filter", {
|
|
|
5879
5908
|
} else if (this.oCondition && this.oCondition === Filter.NONE) {
|
|
5880
5909
|
throw new Error("Filter.NONE not allowed as condition");
|
|
5881
5910
|
}
|
|
5882
|
-
if (this.sOperator === FilterOperator.Any) {
|
|
5911
|
+
if (this.sOperator === FilterOperator.Any || this.sOperator === FilterOperator.NotAny) {
|
|
5883
5912
|
if (this.sVariable && this.oCondition) {
|
|
5884
5913
|
this._checkLambdaArgumentTypes();
|
|
5885
5914
|
} else if (!this.sVariable && !this.oCondition) ; else {
|
|
5886
|
-
throw new Error("When using the filter operator 'Any', a lambda variable and a condition
|
|
5915
|
+
throw new Error("When using the filter operator 'Any' or 'NotAny', you need to provide " + "both a lambda variable and a condition, or neither.");
|
|
5887
5916
|
}
|
|
5888
|
-
} else if (this.sOperator === FilterOperator.All) {
|
|
5917
|
+
} else if (this.sOperator === FilterOperator.All || this.sOperator === FilterOperator.NotAll) {
|
|
5889
5918
|
this._checkLambdaArgumentTypes();
|
|
5890
5919
|
} else if (Array.isArray(this.aFilters) && !this.sPath && !this.sOperator && !this.oValue1 && !this.oValue2) {
|
|
5891
5920
|
this._bMultiFilter = true;
|
|
@@ -5912,10 +5941,10 @@ Filter.checkFilterNone = function (vFilter) {
|
|
|
5912
5941
|
};
|
|
5913
5942
|
Filter.prototype._checkLambdaArgumentTypes = function () {
|
|
5914
5943
|
if (!this.sVariable || typeof this.sVariable !== "string") {
|
|
5915
|
-
throw new Error("When using the filter operators 'Any' or '
|
|
5944
|
+
throw new Error("When using the filter operators 'Any', 'All', 'NotAny', or 'NotAll', a string has to be " + "given as the 'variable' argument.");
|
|
5916
5945
|
}
|
|
5917
5946
|
if (!isFilter(this.oCondition)) {
|
|
5918
|
-
throw new Error("When using the filter operator 'Any' or '
|
|
5947
|
+
throw new Error("When using the filter operator 'Any', 'All', 'NotAny', or 'NotAll', a valid instance of " + "sap.ui.model.Filter has to be given as the 'condition' argument.");
|
|
5919
5948
|
}
|
|
5920
5949
|
};
|
|
5921
5950
|
function isFilter(v) {
|
|
@@ -5955,7 +5984,7 @@ var Func = {
|
|
|
5955
5984
|
EndsWith: "endswith"
|
|
5956
5985
|
};
|
|
5957
5986
|
Filter.prototype.getAST = function (bIncludeOrigin) {
|
|
5958
|
-
var oResult, sOp, sOrigOp, oRef, oValue, oFromValue, oToValue
|
|
5987
|
+
var oResult, sOp, sOrigOp, oRef, oValue, oFromValue, oToValue;
|
|
5959
5988
|
function logical(sOp, oLeft, oRight) {
|
|
5960
5989
|
return {
|
|
5961
5990
|
type: Type.Logical,
|
|
@@ -6074,10 +6103,19 @@ Filter.prototype.getAST = function (bIncludeOrigin) {
|
|
|
6074
6103
|
break;
|
|
6075
6104
|
case FilterOperator.Any:
|
|
6076
6105
|
case FilterOperator.All:
|
|
6077
|
-
|
|
6078
|
-
|
|
6079
|
-
|
|
6080
|
-
|
|
6106
|
+
case FilterOperator.NotAny:
|
|
6107
|
+
case FilterOperator.NotAll:
|
|
6108
|
+
{
|
|
6109
|
+
let sOpLambda = sOp;
|
|
6110
|
+
if (sOp === FilterOperator.NotAny) {
|
|
6111
|
+
sOpLambda = FilterOperator.Any;
|
|
6112
|
+
} else if (sOp === FilterOperator.NotAll) {
|
|
6113
|
+
sOpLambda = FilterOperator.All;
|
|
6114
|
+
}
|
|
6115
|
+
const oLambda = lambda(sOpLambda, oRef, variable(this.sVariable), this.oCondition.getAST(bIncludeOrigin));
|
|
6116
|
+
oResult = sOp === FilterOperator.NotAny || sOp === FilterOperator.NotAll ? unary(Op.Not, oLambda) : oLambda;
|
|
6117
|
+
break;
|
|
6118
|
+
}
|
|
6081
6119
|
default:
|
|
6082
6120
|
throw new Error("Unknown operator: " + sOp);
|
|
6083
6121
|
}
|
package/dist/index.js
CHANGED
|
@@ -17,34 +17,57 @@ export default ({ workspace, options, taskUtil }) => {
|
|
|
17
17
|
const processor = determineProcessor(options.configuration);
|
|
18
18
|
const adaptationProject = await AppVariant.fromWorkspace(workspace, options.projectNamespace);
|
|
19
19
|
const appVariantIdHierarchy = await processor.getAppVariantIdHierarchy(adaptationProject.reference);
|
|
20
|
+
if (appVariantIdHierarchy.length === 0) {
|
|
21
|
+
throw new Error(`No app variant found for reference ${adaptationProject.reference}`);
|
|
22
|
+
}
|
|
20
23
|
// appVariantIdHierarchy contains original application on bottom and the
|
|
21
24
|
// latest app variant on top. We reverse the list to process original
|
|
22
25
|
// application first and then app variants in chronological order.
|
|
23
26
|
const reversedHierarchy = appVariantIdHierarchy.toReversed();
|
|
24
27
|
const fetchFilesPromises = reversedHierarchy.map(({ repoName, cachebusterToken }) => processor.fetch(repoName, cachebusterToken));
|
|
25
28
|
fetchFilesPromises.push(Promise.resolve(adaptationProject.files));
|
|
29
|
+
const appVariants = new Array();
|
|
26
30
|
const adapt = async (baseAppFiles, appVariantFiles) => {
|
|
27
|
-
|
|
28
|
-
|
|
31
|
+
let baseApp = BaseApp.fromFiles(baseAppFiles);
|
|
32
|
+
let appVariant = AppVariant.fromFiles(appVariantFiles);
|
|
33
|
+
// If the app variant is the same as the adaptation project, we use the
|
|
34
|
+
// adaptation project because it contains resources that should be updated.
|
|
35
|
+
if (appVariant.id === adaptationProject.id) {
|
|
36
|
+
appVariant = adaptationProject;
|
|
37
|
+
}
|
|
38
|
+
appVariants.push(appVariant);
|
|
29
39
|
const adaptedFiles = await baseApp.adapt(appVariant, processor);
|
|
30
40
|
return I18nMerger.merge(adaptedFiles, baseApp.i18nPath, appVariant);
|
|
31
41
|
};
|
|
32
|
-
let files = await fetchFilesPromises.reduce(async (previousFiles, currentFiles) =>
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
writePromises.push(workspace.write(resource));
|
|
44
|
-
});
|
|
45
|
-
await Promise.all(writePromises);
|
|
46
|
-
}
|
|
42
|
+
let files = await fetchFilesPromises.reduce(async (previousFiles, currentFiles) => adapt(await previousFiles, await currentFiles), fetchFilesPromises.shift());
|
|
43
|
+
const references = getReferences(appVariants, adaptationProject.id);
|
|
44
|
+
files = FilesUtil.filter(files);
|
|
45
|
+
files = FilesUtil.rename(files, references);
|
|
46
|
+
adaptationProject.omitDeletedResources(files, options.projectNamespace, taskUtil);
|
|
47
|
+
const writePromises = new Array();
|
|
48
|
+
files.forEach((content, filename) => {
|
|
49
|
+
const resource = ResourceUtil.createResource(filename, options.projectNamespace, content);
|
|
50
|
+
writePromises.push(workspace.write(resource));
|
|
51
|
+
});
|
|
52
|
+
await Promise.all(writePromises);
|
|
47
53
|
}
|
|
48
54
|
return process(workspace, taskUtil);
|
|
55
|
+
/**
|
|
56
|
+
* 4p. Reference map contains searchTerm as key and replacement as value. Base
|
|
57
|
+
* id and app variant ids are renamed to adaptation project id.
|
|
58
|
+
*/
|
|
59
|
+
function getReferences(appVariants, adaptationProjectId) {
|
|
60
|
+
const references = new Map();
|
|
61
|
+
appVariants.forEach((variant, i) => {
|
|
62
|
+
if (i === 0) {
|
|
63
|
+
references.set(variant.reference, adaptationProjectId);
|
|
64
|
+
}
|
|
65
|
+
if (variant.id !== adaptationProjectId) {
|
|
66
|
+
references.set(variant.id, adaptationProjectId);
|
|
67
|
+
}
|
|
68
|
+
variant.getRenamingForMovedFiles().forEach((value, key) => references.set(key, value));
|
|
69
|
+
});
|
|
70
|
+
return references;
|
|
71
|
+
}
|
|
49
72
|
};
|
|
50
73
|
//# sourceMappingURL=index.js.map
|
|
@@ -11,7 +11,7 @@ export default class AbapProcessor implements IProcessor {
|
|
|
11
11
|
getAppVariantIdHierarchy(appId: string): Promise<IAppVariantIdHierarchyItem[]>;
|
|
12
12
|
fetch(repoName: string, _cachebusterToken: string): Promise<Map<string, string>>;
|
|
13
13
|
validateConfiguration(): void;
|
|
14
|
-
updateLandscapeSpecificContent(baseAppManifest: any, baseAppFiles: Map<string, string>, appVariantId: string): Promise<void>;
|
|
14
|
+
updateLandscapeSpecificContent(baseAppManifest: any, baseAppFiles: Map<string, string>, appVariantId: string, prefix: string): Promise<void>;
|
|
15
15
|
getConfigurationType(): string;
|
|
16
16
|
createAppVariantHierarchyItem(appVariantId: string, version: string): {
|
|
17
17
|
appVariantId: string;
|
|
@@ -27,9 +27,9 @@ export default class AbapProcessor {
|
|
|
27
27
|
const properties = ["appName"];
|
|
28
28
|
validateObject(this.configuration, properties, "should be specified in ui5.yaml configuration");
|
|
29
29
|
}
|
|
30
|
-
async updateLandscapeSpecificContent(baseAppManifest, baseAppFiles, appVariantId) {
|
|
30
|
+
async updateLandscapeSpecificContent(baseAppManifest, baseAppFiles, appVariantId, prefix) {
|
|
31
31
|
const languages = Language.create(this.configuration.languages);
|
|
32
|
-
const files = await this.annotationManager.process(baseAppManifest, languages, appVariantId);
|
|
32
|
+
const files = await this.annotationManager.process(baseAppManifest, languages, appVariantId, prefix);
|
|
33
33
|
if (baseAppFiles) {
|
|
34
34
|
files.forEach((value, key) => baseAppFiles.set(key, value));
|
|
35
35
|
}
|
|
@@ -7,7 +7,9 @@ export default class CFProcessor implements IProcessor {
|
|
|
7
7
|
getAppVariantIdHierarchy(appId: string): Promise<IAppInfo[]>;
|
|
8
8
|
fetch(_repoName: string, _cachebusterToken: string): Promise<Map<string, string>>;
|
|
9
9
|
validateConfiguration(): void;
|
|
10
|
-
updateLandscapeSpecificContent(
|
|
10
|
+
updateLandscapeSpecificContent(baseAppManifest: any, baseAppFiles: Map<string, string>): Promise<void>;
|
|
11
|
+
private updateXsAppJson;
|
|
12
|
+
private enhanceRoutesWithEndpointAndService;
|
|
11
13
|
private updateCloudPlatform;
|
|
12
14
|
getConfigurationType(): string;
|
|
13
15
|
createAppVariantHierarchyItem(appVariantId: string, version: string): {
|
|
@@ -7,6 +7,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
import HTML5RepoManager from "../repositories/html5RepoManager.js";
|
|
8
8
|
import { cached } from "../cache/cacheHolder.js";
|
|
9
9
|
import { validateObject } from "../util/commonUtil.js";
|
|
10
|
+
import CFUtil from "../util/cfUtil.js";
|
|
10
11
|
export default class CFProcessor {
|
|
11
12
|
configuration;
|
|
12
13
|
constructor(configuration) {
|
|
@@ -26,8 +27,56 @@ export default class CFProcessor {
|
|
|
26
27
|
validateConfiguration() {
|
|
27
28
|
validateObject(this.configuration, ["appHostId", "appName", "appVersion"], "should be specified in ui5.yaml configuration");
|
|
28
29
|
}
|
|
29
|
-
async updateLandscapeSpecificContent(
|
|
30
|
-
this.updateCloudPlatform(
|
|
30
|
+
async updateLandscapeSpecificContent(baseAppManifest, baseAppFiles) {
|
|
31
|
+
this.updateCloudPlatform(baseAppManifest);
|
|
32
|
+
await this.updateXsAppJson(baseAppFiles);
|
|
33
|
+
}
|
|
34
|
+
async updateXsAppJson(baseAppFiles) {
|
|
35
|
+
const xsAppJsonContent = baseAppFiles.get("xs-app.json");
|
|
36
|
+
if (!xsAppJsonContent) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const { serviceInstanceName, space } = this.configuration;
|
|
40
|
+
if (!serviceInstanceName) {
|
|
41
|
+
throw new Error(`Service instance name must be specified in ui5.yaml configuration for app '${this.configuration.appName}'`);
|
|
42
|
+
}
|
|
43
|
+
let serviceCredentials;
|
|
44
|
+
try {
|
|
45
|
+
// Get valid service keys with proper endpoints structure
|
|
46
|
+
serviceCredentials = await CFUtil.getOrCreateServiceKeyWithEndpoints(serviceInstanceName, space);
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
throw new Error(`Failed to get valid service keys for app '${this.configuration.appName}': ${error.message}`);
|
|
50
|
+
}
|
|
51
|
+
const xsAppJson = JSON.parse(xsAppJsonContent);
|
|
52
|
+
xsAppJson.routes = this.enhanceRoutesWithEndpointAndService(serviceCredentials, xsAppJson.routes);
|
|
53
|
+
baseAppFiles.set("xs-app.json", JSON.stringify(xsAppJson, null, 2));
|
|
54
|
+
}
|
|
55
|
+
enhanceRoutesWithEndpointAndService(serviceCredentials, baseRoutes) {
|
|
56
|
+
const endpoints = serviceCredentials.endpoints;
|
|
57
|
+
// Map destinations to endpoint names
|
|
58
|
+
const destinationToEndpoint = Object.entries(endpoints).reduce((acc, [endpointName, obj]) => {
|
|
59
|
+
if (obj.destination) {
|
|
60
|
+
acc[obj.destination] = endpointName;
|
|
61
|
+
}
|
|
62
|
+
return acc;
|
|
63
|
+
}, {});
|
|
64
|
+
return baseRoutes.map((route) => {
|
|
65
|
+
const endpointName = destinationToEndpoint[route.destination];
|
|
66
|
+
if (endpointName) {
|
|
67
|
+
// There is a matching endpoint: remove destination and add endpoint/service
|
|
68
|
+
const { destination: _destination, ...rest } = route;
|
|
69
|
+
return {
|
|
70
|
+
...rest,
|
|
71
|
+
endpoint: endpointName,
|
|
72
|
+
service: serviceCredentials["sap.cloud.service"],
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
// No match: return route unchanged
|
|
77
|
+
return route;
|
|
78
|
+
}
|
|
79
|
+
});
|
|
31
80
|
}
|
|
32
81
|
updateCloudPlatform(baseAppManifest) {
|
|
33
82
|
const sapCloudService = baseAppManifest["sap.cloud"]?.service;
|
|
@@ -4,6 +4,6 @@ export default interface IProcessor {
|
|
|
4
4
|
getAppVariantIdHierarchy(appId: string): Promise<IAppVariantIdHierarchyItem[]>;
|
|
5
5
|
fetch(repoName: string, cachebusterToken: string): Promise<Map<string, string>>;
|
|
6
6
|
createAppVariantHierarchyItem(appVariantId: string, version: string): void;
|
|
7
|
-
updateLandscapeSpecificContent(baseAppManifest: any, baseAppFiles:
|
|
7
|
+
updateLandscapeSpecificContent(baseAppManifest: any, baseAppFiles: Map<string, string>, appVariantId: string, prefix: string): Promise<void>;
|
|
8
8
|
}
|
|
9
9
|
export declare function determineProcessor(configuration: IConfiguration): IProcessor;
|
package/dist/util/cfUtil.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export default class CFUtil {
|
|
|
13
13
|
private static getOrCreateServiceKeys;
|
|
14
14
|
private static getServiceKeys;
|
|
15
15
|
private static createServiceKey;
|
|
16
|
+
private static deleteServiceKeyUnsafe;
|
|
16
17
|
private static getServiceInstance;
|
|
17
18
|
static processErrors(json: any): void;
|
|
18
19
|
static requestCfApi(url: string): Promise<IResource[]>;
|
|
@@ -20,6 +21,52 @@ export default class CFUtil {
|
|
|
20
21
|
private static cfExecute;
|
|
21
22
|
private static errorsToString;
|
|
22
23
|
private static parseJson;
|
|
24
|
+
/**
|
|
25
|
+
* Get service keys and return the first one with valid endpoints
|
|
26
|
+
* @private
|
|
27
|
+
* @static
|
|
28
|
+
* @param {string} serviceInstanceGuid the service instance guid
|
|
29
|
+
* @return {Promise<any>} the first service key with valid endpoints, or null if none found
|
|
30
|
+
* @memberof CFUtil
|
|
31
|
+
*/
|
|
32
|
+
private static getServiceKeyWithValidEndpoints;
|
|
33
|
+
/**
|
|
34
|
+
* Get service keys for a service instance by name. If the existing service key
|
|
35
|
+
* has endpoints as strings instead of objects, a new service key will be created.
|
|
36
|
+
* @static
|
|
37
|
+
* @param {string} serviceInstanceName name of the service instance
|
|
38
|
+
* @param {string} [spaceGuid] optional space guid, will use current space if not provided
|
|
39
|
+
* @return {Promise<any>} promise with service key credentials
|
|
40
|
+
* @memberof CFUtil
|
|
41
|
+
*/
|
|
42
|
+
static getOrCreateServiceKeyWithEndpoints(serviceInstanceName: string, spaceGuid?: string): Promise<any>;
|
|
43
|
+
/**
|
|
44
|
+
* Check if endpoints object has at least one property that is an object
|
|
45
|
+
* @private
|
|
46
|
+
* @static
|
|
47
|
+
* @param {any} endpoints the endpoints object to validate
|
|
48
|
+
* @return {boolean} true if at least one property of endpoints is an object
|
|
49
|
+
* @memberof CFUtil
|
|
50
|
+
*/
|
|
51
|
+
private static hasValidEndpoints;
|
|
52
|
+
/**
|
|
53
|
+
* Get all service key names for a service instance
|
|
54
|
+
* @private
|
|
55
|
+
* @static
|
|
56
|
+
* @param {string} serviceInstanceGuid the service instance guid
|
|
57
|
+
* @return {Promise<string[]>} promise with array of service key names
|
|
58
|
+
* @memberof CFUtil
|
|
59
|
+
*/
|
|
60
|
+
private static getAllServiceKeyNames;
|
|
61
|
+
/**
|
|
62
|
+
* Generate a unique service key name in format serviceInstanceName-key-N
|
|
63
|
+
* @static
|
|
64
|
+
* @param {string} serviceInstanceName the service instance name
|
|
65
|
+
* @param {string} serviceInstanceGuid the service instance guid
|
|
66
|
+
* @return {Promise<string>} promise with unique service key name
|
|
67
|
+
* @memberof CFUtil
|
|
68
|
+
*/
|
|
69
|
+
static generateUniqueServiceKeyName(serviceInstanceName: string, serviceInstanceGuid: string): Promise<string>;
|
|
23
70
|
/**
|
|
24
71
|
* Get space guid from configuration or local CF fodler
|
|
25
72
|
* @static
|