trm-core 10.3.0 → 10.3.2
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.txt +11 -0
- package/dist/actions/commons/utils/packageCleanup.d.ts +5 -5
- package/dist/actions/commons/utils/packageCleanup.js +35 -14
- package/dist/actions/publish/init.js +17 -1
- package/dist/actions/uninstall/init.js +9 -10
- package/dist/dependencies/PackageDependencies.js +6 -5
- package/dist/manifest/Manifest.js +24 -0
- package/dist/systemConnector/SystemConnectorBase.js +11 -1
- package/package.json +3 -3
package/changelog.txt
CHANGED
|
@@ -8,6 +8,17 @@ Legend
|
|
|
8
8
|
+ : added
|
|
9
9
|
- : removed
|
|
10
10
|
|
|
11
|
+
2026-10-14 v10.3.2
|
|
12
|
+
-------------------
|
|
13
|
+
* post activities xml -> json
|
|
14
|
+
+ post activity ui method parameters
|
|
15
|
+
+ default values for local export
|
|
16
|
+
|
|
17
|
+
2026-10-14 v10.3.1
|
|
18
|
+
-------------------
|
|
19
|
+
* dependency tree preserves the direct ABAP package instead of collapsing it to the root package
|
|
20
|
+
* dependency tree lists every object referencing the same TRM package
|
|
21
|
+
|
|
11
22
|
2026-10-14 v10.3.0
|
|
12
23
|
-------------------
|
|
13
24
|
* rollback cleanup excludes LANG entries rejected by SAP deletion transports
|
|
@@ -114,12 +114,12 @@ export type CustomizingRow = {
|
|
|
114
114
|
*/
|
|
115
115
|
export declare function getPackagesInstalledIn(systemPackages: TrmPackage[], installed: TrmPackage, devclasses: Set<string>): TrmPackage[];
|
|
116
116
|
/**
|
|
117
|
-
* Locks on
|
|
118
|
-
*
|
|
119
|
-
* lock check, so they can be checked before asking anything.
|
|
120
|
-
* outside the installation are left out, as the cleanup may keep them.
|
|
117
|
+
* Locks on what removing `installed` certainly deletes: the objects of its installed transport
|
|
118
|
+
* still in its SAP packages, and the SAP packages themselves when nothing may keep them. These
|
|
119
|
+
* would abort the cleanup at its objects lock check, so they can be checked before asking anything.
|
|
120
|
+
* Objects added locally or moved outside the installation are left out, as the cleanup may keep them.
|
|
121
121
|
*/
|
|
122
|
-
export declare function getInstalledObjectsLocks(installed: TrmPackage, previousInstallPackages: InstallPackageReplacements[], systemPackages: TrmPackage[]
|
|
122
|
+
export declare function getInstalledObjectsLocks(installed: TrmPackage, previousInstallPackages: InstallPackageReplacements[], systemPackages: TrmPackage[]): Promise<ZTRM_OBJ_LOCK[]>;
|
|
123
123
|
/** Deletes every temporary package, reporting the first failure after the cleanup pass. */
|
|
124
124
|
export declare function deleteTemporaryCleanupPackages(temporaryPackages: Array<Pick<E071, 'objName'>>): Promise<void>;
|
|
125
125
|
/**
|
|
@@ -161,26 +161,47 @@ function readRelocatedObjects(objects, tree) {
|
|
|
161
161
|
});
|
|
162
162
|
}
|
|
163
163
|
/**
|
|
164
|
-
* Locks on
|
|
165
|
-
*
|
|
166
|
-
* lock check, so they can be checked before asking anything.
|
|
167
|
-
* outside the installation are left out, as the cleanup may keep them.
|
|
164
|
+
* Locks on what removing `installed` certainly deletes: the objects of its installed transport
|
|
165
|
+
* still in its SAP packages, and the SAP packages themselves when nothing may keep them. These
|
|
166
|
+
* would abort the cleanup at its objects lock check, so they can be checked before asking anything.
|
|
167
|
+
* Objects added locally or moved outside the installation are left out, as the cleanup may keep them.
|
|
168
168
|
*/
|
|
169
|
-
function getInstalledObjectsLocks(installed, previousInstallPackages, systemPackages
|
|
169
|
+
function getInstalledObjectsLocks(installed, previousInstallPackages, systemPackages) {
|
|
170
170
|
return __awaiter(this, void 0, void 0, function* () {
|
|
171
|
-
if (objects.length === 0) {
|
|
172
|
-
return [];
|
|
173
|
-
}
|
|
174
171
|
const { previousTransportObjects } = yield readInstalledTransportObjects(installed);
|
|
175
172
|
const installedKeys = new Set(previousTransportObjects.map(objectKey));
|
|
176
|
-
|
|
177
|
-
|
|
173
|
+
// TRM comment rows are not objects; SAP packages follow the decision for the whole installation.
|
|
174
|
+
const candidates = new Map(previousTransportObjects
|
|
175
|
+
.filter(object => normalize(object.pgmid) !== '*' && !isDevclass(object))
|
|
178
176
|
.map(object => [objectKey(object), object]));
|
|
179
|
-
if (candidates.size === 0) {
|
|
180
|
-
return [];
|
|
181
|
-
}
|
|
182
177
|
const tree = yield readInstallationTree(installed, previousInstallPackages, previousTransportObjects, [], systemPackages);
|
|
183
|
-
|
|
178
|
+
// SAP packages are kept when a TRM package is installed underneath, or when the cleanup of
|
|
179
|
+
// locally added packages or objects is declined.
|
|
180
|
+
let packagesDeleted = tree.otherInstallations.size === 0
|
|
181
|
+
&& Array.from(tree.previousDevclasses.keys()).every(devclass => tree.installedDevclasses.has(devclass));
|
|
182
|
+
for (const devclass of packagesDeleted ? tree.previousDevclasses.values() : []) {
|
|
183
|
+
if ((yield systemConnector_1.SystemConnector.getDevclassObjects(devclass, false)).some(object => !isDevclass(object) && !isNamespace(object) && !installedKeys.has(objectKey(object)))) {
|
|
184
|
+
packagesDeleted = false;
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
if (packagesDeleted) {
|
|
189
|
+
tree.previousDevclasses.forEach(devclass => candidates.set(objectKey({ pgmid: 'R3TR', object: 'DEVC', objName: devclass }), { pgmid: 'R3TR', object: 'DEVC', objName: devclass }));
|
|
190
|
+
}
|
|
191
|
+
// Only existing objects are deleted, and only those still in the installation's SAP packages.
|
|
192
|
+
const checkedObjects = Array.from(candidates.values()).filter(object => normalize(object.pgmid) === 'R3TR');
|
|
193
|
+
if (checkedObjects.length > 0) {
|
|
194
|
+
const existing = new Map((yield systemConnector_1.SystemConnector.getExistingObjects(checkedObjects.map(object => ({
|
|
195
|
+
pgmid: object.pgmid, object: object.object, objName: object.objName, devclass: ''
|
|
196
|
+
})))).map(object => [objectKey(object), object]));
|
|
197
|
+
checkedObjects.forEach(object => {
|
|
198
|
+
const tadir = existing.get(objectKey(object));
|
|
199
|
+
if (!tadir || (!isDevclass(object) && tadir.devclass
|
|
200
|
+
&& (!tree.previousDevclasses.has(normalize(tadir.devclass)) || tree.isOtherInstallation(tadir.devclass)))) {
|
|
201
|
+
candidates.delete(objectKey(object));
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
}
|
|
184
205
|
if (candidates.size === 0) {
|
|
185
206
|
return [];
|
|
186
207
|
}
|
|
@@ -176,8 +176,24 @@ exports.init = {
|
|
|
176
176
|
//if not provided, derive it from the system package (previous publish), then prompt (if allowed)
|
|
177
177
|
//supplied or derived values are normalized and validated, prompted values are validated by the prompt
|
|
178
178
|
var packageNeedsValidation = true;
|
|
179
|
+
let installedPublicPackage;
|
|
180
|
+
if (context.rawInput.packageData.registry.getRegistryType() === registry_1.RegistryType.LOCAL) {
|
|
181
|
+
installedPublicPackage = context.rawInput.contextData.systemPackages.find(o => o.compareName(context.rawInput.packageData.name)
|
|
182
|
+
&& o.registry.getRegistryType() === registry_1.RegistryType.PUBLIC
|
|
183
|
+
&& !!o.manifest);
|
|
184
|
+
if (installedPublicPackage) {
|
|
185
|
+
const manifest = installedPublicPackage.manifest.get();
|
|
186
|
+
context.runtime.latest.data = {
|
|
187
|
+
manifest,
|
|
188
|
+
dist_tags: { latest: manifest.version },
|
|
189
|
+
versions: [manifest.version],
|
|
190
|
+
yanked_versions: [],
|
|
191
|
+
transports: []
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
}
|
|
179
195
|
if (!context.rawInput.packageData.devclass) {
|
|
180
|
-
const trmPackage = context.rawInput.contextData.systemPackages.find(o => trmPackage_1.TrmPackage.compare(o, new trmPackage_1.TrmPackage(context.rawInput.packageData.name, context.rawInput.packageData.registry)));
|
|
196
|
+
const trmPackage = installedPublicPackage || context.rawInput.contextData.systemPackages.find(o => trmPackage_1.TrmPackage.compare(o, new trmPackage_1.TrmPackage(context.rawInput.packageData.name, context.rawInput.packageData.registry)));
|
|
181
197
|
if (trmPackage) {
|
|
182
198
|
context.rawInput.packageData.devclass = trmPackage.getDevclass();
|
|
183
199
|
}
|
|
@@ -77,17 +77,16 @@ exports.init = {
|
|
|
77
77
|
const previousInstallPackages = yield systemConnector_1.SystemConnector.getInstallPackages(installed.packageName, installed.registry);
|
|
78
78
|
const previousInstallTransports = yield systemConnector_1.SystemConnector.getInstallTransports(installed.packageName, installed.registry);
|
|
79
79
|
const nestedPackages = yield (0, uninstallNestedPackages_1.getNestedPackages)(context.rawInput.contextData.systemPackages, installed, previousInstallPackages.map(replacement => replacement.installDevclass));
|
|
80
|
-
//5- dirty check:
|
|
81
|
-
//so check them before asking anything
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
throw new Error(`Uninstall aborted. To continue, all cleanup objects and SAP packages must be released`);
|
|
89
|
-
}
|
|
80
|
+
//5- dirty check: objects still being edited would fail the cleanup objects lock check,
|
|
81
|
+
//so check them before asking anything. Dirty entries may not list every edit: check all
|
|
82
|
+
//the cleanup deletes for sure
|
|
83
|
+
trm_commons_1.Logger.loading(`Checking installed objects locks...`, true);
|
|
84
|
+
const locks = yield (0, utils_1.getInstalledObjectsLocks)(installed, previousInstallPackages, context.rawInput.contextData.systemPackages);
|
|
85
|
+
if (locks.length > 0) {
|
|
86
|
+
locks.forEach(lock => trm_commons_1.Logger.error(`${lock.pgmid} ${lock.object} ${lock.objName} is currently locked in transport ${lock.trkorr}`, { important: true }));
|
|
87
|
+
throw new Error(`Uninstall aborted. To continue, all cleanup objects and SAP packages must be released`);
|
|
90
88
|
}
|
|
89
|
+
const allDirtyEntries = yield (0, utils_1.withoutOwnTrmTransports)(installed.getDirtyEntries(), installed.packageName);
|
|
91
90
|
//the TRM packages installed under it confirm their own changes
|
|
92
91
|
const dirtyEntries = yield (0, uninstallNestedPackages_1.withoutNestedDirtyEntries)(allDirtyEntries, nestedPackages.all);
|
|
93
92
|
if (dirtyEntries.length > 0 && !context.rawInput.uninstallData.checks.ignoreDirty) {
|
|
@@ -80,7 +80,7 @@ class PackageDependencies {
|
|
|
80
80
|
foundIn: []
|
|
81
81
|
}) - 1;
|
|
82
82
|
}
|
|
83
|
-
if (!this.trmPackageDependencies[depIndex].foundIn.find(f => f.object === o.object && f.objName ===
|
|
83
|
+
if (!this.trmPackageDependencies[depIndex].foundIn.find(f => f.object === o.object && f.objName === o.objName)) {
|
|
84
84
|
this.trmPackageDependencies[depIndex].foundIn.push({
|
|
85
85
|
object: o.object,
|
|
86
86
|
objName: o.objName
|
|
@@ -98,11 +98,12 @@ class PackageDependencies {
|
|
|
98
98
|
for (const dep of sapPackage.dependencies) {
|
|
99
99
|
// only if the abap package is not a subpackage of the one analyzed
|
|
100
100
|
if (!(yield this.getDevclasses()).includes(sapPackage.package)) {
|
|
101
|
-
//
|
|
102
|
-
|
|
103
|
-
|
|
101
|
+
// Keep the package that owns the dependency. Collapsing it to the topmost
|
|
102
|
+
// superpackage loses the actionable package reported by TADIR and can group
|
|
103
|
+
// unrelated dependencies under a broad customer-package root.
|
|
104
|
+
var packageIndex = this.abapPackageDependencies.findIndex(k => k.abapPackage.devclass === sapPackage.package);
|
|
104
105
|
if (packageIndex < 0) {
|
|
105
|
-
const abapPackage = yield systemConnector_1.SystemConnector.getDevclass(
|
|
106
|
+
const abapPackage = yield systemConnector_1.SystemConnector.getDevclass(sapPackage.package);
|
|
106
107
|
packageIndex = this.abapPackageDependencies.push({
|
|
107
108
|
abapPackage: abapPackage,
|
|
108
109
|
isCustomerPackage: !abapPackage.tpclass,
|
|
@@ -755,6 +755,30 @@ class Manifest {
|
|
|
755
755
|
}];
|
|
756
756
|
}
|
|
757
757
|
}
|
|
758
|
+
if (oAbapManifest.postActivities && oAbapManifest.postActivities.item) {
|
|
759
|
+
const postActivities = Array.isArray(oAbapManifest.postActivities.item)
|
|
760
|
+
? oAbapManifest.postActivities.item
|
|
761
|
+
: [oAbapManifest.postActivities.item];
|
|
762
|
+
manifest.postActivities = postActivities.map(postActivity => {
|
|
763
|
+
var _a, _b;
|
|
764
|
+
const parsedPostActivity = {
|
|
765
|
+
name: (_a = postActivity.name) === null || _a === void 0 ? void 0 : _a.text
|
|
766
|
+
};
|
|
767
|
+
if ((_b = postActivity.parameters) === null || _b === void 0 ? void 0 : _b.item) {
|
|
768
|
+
const parameters = Array.isArray(postActivity.parameters.item)
|
|
769
|
+
? postActivity.parameters.item
|
|
770
|
+
: [postActivity.parameters.item];
|
|
771
|
+
parsedPostActivity.parameters = parameters.map(parameter => {
|
|
772
|
+
var _a, _b;
|
|
773
|
+
return ({
|
|
774
|
+
name: (_a = parameter.name) === null || _a === void 0 ? void 0 : _a.text,
|
|
775
|
+
value: (_b = parameter.value) === null || _b === void 0 ? void 0 : _b.text
|
|
776
|
+
});
|
|
777
|
+
});
|
|
778
|
+
}
|
|
779
|
+
return parsedPostActivity;
|
|
780
|
+
});
|
|
781
|
+
}
|
|
758
782
|
if (oAbapManifest.engines && oAbapManifest.engines.text) {
|
|
759
783
|
try {
|
|
760
784
|
manifest.engines = JSON.parse(oAbapManifest.engines.text);
|
|
@@ -85,10 +85,20 @@ class SystemConnectorBase {
|
|
|
85
85
|
const hasMore = classes.length > ctx.limit;
|
|
86
86
|
const rows = classes.slice(0, ctx.limit).map(o => ({ name: o.clsname }));
|
|
87
87
|
if (rows.length > 0) {
|
|
88
|
-
const
|
|
88
|
+
const classOptions = `( ${rows.map(o => `CLSNAME EQ '${o.name}'`).join(' OR ')} )`;
|
|
89
|
+
const [texts, mandatoryParameters] = yield Promise.all([
|
|
90
|
+
this.readTable('SEOCLASSTX', [{ fieldName: 'CLSNAME' }, { fieldName: 'DESCRIPT' }], `LANGU EQ '${this.getLangu(true)}' AND ${classOptions}`),
|
|
91
|
+
this.readTable('SEOSUBCODF', [{ fieldName: 'CLSNAME' }, { fieldName: 'SCONAME' }, { fieldName: 'PARVALUE' }], `CMPNAME EQ '${exports.POST_ACTIVITY_METHOD}' AND PARDECLTYP EQ '0' AND PAROPTIONL EQ '' AND VERSION EQ '1' AND ${classOptions}`)
|
|
92
|
+
]);
|
|
89
93
|
rows.forEach(o => {
|
|
90
94
|
var _a;
|
|
91
95
|
o.description = (_a = texts.find(t => t.clsname === o.name)) === null || _a === void 0 ? void 0 : _a.descript;
|
|
96
|
+
const parameters = mandatoryParameters
|
|
97
|
+
.filter(parameter => parameter.clsname === o.name)
|
|
98
|
+
.map(parameter => (Object.assign({ name: parameter.sconame }, (parameter.parvalue ? { value: parameter.parvalue } : {}))));
|
|
99
|
+
if (parameters.length > 0) {
|
|
100
|
+
o.parameters = parameters;
|
|
101
|
+
}
|
|
92
102
|
});
|
|
93
103
|
}
|
|
94
104
|
return { rows, hasMore };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "trm-core",
|
|
3
|
-
"version": "10.3.
|
|
3
|
+
"version": "10.3.2",
|
|
4
4
|
"description": "TRM (Transport Request Manager) Core",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"xml-js": "^1.6.11"
|
|
68
68
|
},
|
|
69
69
|
"peerDependencies": {
|
|
70
|
-
"trm-commons": "^5.
|
|
70
|
+
"trm-commons": "^5.4.1"
|
|
71
71
|
},
|
|
72
72
|
"devDependencies": {
|
|
73
73
|
"@types/adm-zip": "^0.5.0",
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
"@types/stack-trace": "^0.0.33",
|
|
85
85
|
"jest": "^30.5.2",
|
|
86
86
|
"rimraf": "^6.0.1",
|
|
87
|
-
"trm-commons": "^5.
|
|
87
|
+
"trm-commons": "^5.4.1",
|
|
88
88
|
"ts-jest": "^29.4.1",
|
|
89
89
|
"ts-node": "^10.9.2",
|
|
90
90
|
"typescript": "^5.8.2"
|