arc-1 1.0.2 → 1.1.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/bin/arc1-cli.js +3 -7
- package/bin/arc1.js +4 -9
- package/dist/adt/abapgit.d.ts +10 -5
- package/dist/adt/abapgit.d.ts.map +1 -1
- package/dist/adt/abapgit.js +357 -76
- package/dist/adt/abapgit.js.map +1 -1
- package/dist/adt/atc.d.ts +49 -0
- package/dist/adt/atc.d.ts.map +1 -0
- package/dist/adt/atc.js +294 -0
- package/dist/adt/atc.js.map +1 -0
- package/dist/adt/aunit-package.d.ts +22 -0
- package/dist/adt/aunit-package.d.ts.map +1 -0
- package/dist/adt/aunit-package.js +78 -0
- package/dist/adt/aunit-package.js.map +1 -0
- package/dist/adt/aunit.d.ts +143 -0
- package/dist/adt/aunit.d.ts.map +1 -0
- package/dist/adt/aunit.js +987 -0
- package/dist/adt/aunit.js.map +1 -0
- package/dist/adt/client.d.ts +9 -7
- package/dist/adt/client.d.ts.map +1 -1
- package/dist/adt/client.js +55 -64
- package/dist/adt/client.js.map +1 -1
- package/dist/adt/config.d.ts +2 -0
- package/dist/adt/config.d.ts.map +1 -1
- package/dist/adt/config.js +1 -0
- package/dist/adt/config.js.map +1 -1
- package/dist/adt/devtools.d.ts +8 -30
- package/dist/adt/devtools.d.ts.map +1 -1
- package/dist/adt/devtools.js +41 -218
- package/dist/adt/devtools.js.map +1 -1
- package/dist/adt/diagnostics.d.ts +1 -1
- package/dist/adt/diagnostics.d.ts.map +1 -1
- package/dist/adt/diagnostics.js +12 -12
- package/dist/adt/diagnostics.js.map +1 -1
- package/dist/adt/errors.d.ts +7 -0
- package/dist/adt/errors.d.ts.map +1 -1
- package/dist/adt/errors.js +7 -0
- package/dist/adt/errors.js.map +1 -1
- package/dist/adt/features.d.ts +9 -3
- package/dist/adt/features.d.ts.map +1 -1
- package/dist/adt/features.js +40 -8
- package/dist/adt/features.js.map +1 -1
- package/dist/adt/gcts.d.ts +12 -45
- package/dist/adt/gcts.d.ts.map +1 -1
- package/dist/adt/gcts.js +299 -171
- package/dist/adt/gcts.js.map +1 -1
- package/dist/adt/http-deadline.d.ts +23 -0
- package/dist/adt/http-deadline.d.ts.map +1 -0
- package/dist/adt/http-deadline.js +106 -0
- package/dist/adt/http-deadline.js.map +1 -0
- package/dist/adt/http-wire-body.d.ts +2 -0
- package/dist/adt/http-wire-body.d.ts.map +1 -0
- package/dist/adt/http-wire-body.js +14 -0
- package/dist/adt/http-wire-body.js.map +1 -0
- package/dist/adt/http.d.ts +10 -24
- package/dist/adt/http.d.ts.map +1 -1
- package/dist/adt/http.js +89 -53
- package/dist/adt/http.js.map +1 -1
- package/dist/adt/path-safety.d.ts +16 -0
- package/dist/adt/path-safety.d.ts.map +1 -0
- package/dist/adt/path-safety.js +101 -0
- package/dist/adt/path-safety.js.map +1 -0
- package/dist/adt/semaphore.d.ts +2 -2
- package/dist/adt/semaphore.d.ts.map +1 -1
- package/dist/adt/semaphore.js +26 -9
- package/dist/adt/semaphore.js.map +1 -1
- package/dist/adt/source-diff.d.ts +10 -1
- package/dist/adt/source-diff.d.ts.map +1 -1
- package/dist/adt/source-diff.js +33 -7
- package/dist/adt/source-diff.js.map +1 -1
- package/dist/adt/text-search.d.ts +25 -0
- package/dist/adt/text-search.d.ts.map +1 -0
- package/dist/adt/text-search.js +152 -0
- package/dist/adt/text-search.js.map +1 -0
- package/dist/adt/transport-diff.d.ts +128 -0
- package/dist/adt/transport-diff.d.ts.map +1 -0
- package/dist/adt/transport-diff.js +524 -0
- package/dist/adt/transport-diff.js.map +1 -0
- package/dist/adt/transport.d.ts +78 -13
- package/dist/adt/transport.d.ts.map +1 -1
- package/dist/adt/transport.js +443 -41
- package/dist/adt/transport.js.map +1 -1
- package/dist/adt/types.d.ts +23 -12
- package/dist/adt/types.d.ts.map +1 -1
- package/dist/adt/xml-parser.d.ts +1 -8
- package/dist/adt/xml-parser.d.ts.map +1 -1
- package/dist/adt/xml-parser.js +54 -60
- package/dist/adt/xml-parser.js.map +1 -1
- package/dist/authz/policy.d.ts.map +1 -1
- package/dist/authz/policy.js +5 -2
- package/dist/authz/policy.js.map +1 -1
- package/dist/cli-args.d.ts +2 -2
- package/dist/cli-args.js +2 -2
- package/dist/cli-checks.d.ts +56 -0
- package/dist/cli-checks.d.ts.map +1 -0
- package/dist/cli-checks.js +368 -0
- package/dist/cli-checks.js.map +1 -0
- package/dist/cli.d.ts +68 -15
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +677 -297
- package/dist/cli.js.map +1 -1
- package/dist/handlers/cds-hints.d.ts.map +1 -1
- package/dist/handlers/cds-hints.js +1 -10
- package/dist/handlers/cds-hints.js.map +1 -1
- package/dist/handlers/diagnose.d.ts +4 -0
- package/dist/handlers/diagnose.d.ts.map +1 -1
- package/dist/handlers/diagnose.js +616 -9
- package/dist/handlers/diagnose.js.map +1 -1
- package/dist/handlers/dispatch.d.ts.map +1 -1
- package/dist/handlers/dispatch.js +40 -1
- package/dist/handlers/dispatch.js.map +1 -1
- package/dist/handlers/git.d.ts.map +1 -1
- package/dist/handlers/git.js +165 -84
- package/dist/handlers/git.js.map +1 -1
- package/dist/handlers/read.d.ts.map +1 -1
- package/dist/handlers/read.js +15 -0
- package/dist/handlers/read.js.map +1 -1
- package/dist/handlers/schemas.d.ts +15 -2
- package/dist/handlers/schemas.d.ts.map +1 -1
- package/dist/handlers/schemas.js +75 -6
- package/dist/handlers/schemas.js.map +1 -1
- package/dist/handlers/search.js +1 -1
- package/dist/handlers/search.js.map +1 -1
- package/dist/handlers/tools.d.ts.map +1 -1
- package/dist/handlers/tools.js +51 -42
- package/dist/handlers/tools.js.map +1 -1
- package/dist/handlers/transport.d.ts +2 -1
- package/dist/handlers/transport.d.ts.map +1 -1
- package/dist/handlers/transport.js +128 -27
- package/dist/handlers/transport.js.map +1 -1
- package/dist/handlers/write/create.d.ts.map +1 -1
- package/dist/handlers/write/create.js +11 -0
- package/dist/handlers/write/create.js.map +1 -1
- package/dist/handlers/write/update-delete.d.ts.map +1 -1
- package/dist/handlers/write/update-delete.js +33 -10
- package/dist/handlers/write/update-delete.js.map +1 -1
- package/dist/handlers/write-helpers.d.ts.map +1 -1
- package/dist/handlers/write-helpers.js +3 -2
- package/dist/handlers/write-helpers.js.map +1 -1
- package/dist/server/audit.d.ts +1 -1
- package/dist/server/audit.d.ts.map +1 -1
- package/dist/server/audit.js +228 -21
- package/dist/server/audit.js.map +1 -1
- package/dist/server/config.d.ts +16 -0
- package/dist/server/config.d.ts.map +1 -1
- package/dist/server/config.js +145 -17
- package/dist/server/config.js.map +1 -1
- package/dist/server/effective-policy-log.d.ts +2 -1
- package/dist/server/effective-policy-log.d.ts.map +1 -1
- package/dist/server/effective-policy-log.js +8 -2
- package/dist/server/effective-policy-log.js.map +1 -1
- package/dist/server/multi-target-runtime.d.ts.map +1 -1
- package/dist/server/multi-target-runtime.js +3 -0
- package/dist/server/multi-target-runtime.js.map +1 -1
- package/dist/server/multi-target-tools.d.ts.map +1 -1
- package/dist/server/multi-target-tools.js +5 -0
- package/dist/server/multi-target-tools.js.map +1 -1
- package/dist/server/server.d.ts +15 -13
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +36 -26
- package/dist/server/server.js.map +1 -1
- package/dist/server/types.d.ts +2 -0
- package/dist/server/types.d.ts.map +1 -1
- package/dist/server/types.js +1 -0
- package/dist/server/types.js.map +1 -1
- package/package.json +13 -13
|
@@ -0,0 +1,524 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transport-scoped review diffs — backs `SAPTransport action="diff"`.
|
|
3
|
+
*
|
|
4
|
+
* Answers "what did this transport change?" by picking, per object, the revision written
|
|
5
|
+
* under the transport and the one immediately before it, then diffing those two sources.
|
|
6
|
+
*
|
|
7
|
+
* The selection mirrors SAP's own ADT MCP tool
|
|
8
|
+
* (`com.sap.adt.tm.backend.diff.TransportDiffService`, ADT 3.60.1) with four corrections
|
|
9
|
+
* proven necessary against live feeds — see docs/plans/2026-08-03-transport-diff.md:
|
|
10
|
+
*
|
|
11
|
+
* 1. match the request AND its tasks (SAP matches one exact correction number);
|
|
12
|
+
* 2. break timestamp ties on the version number — the feed is returned in neither
|
|
13
|
+
* version nor date order (a4h returns `00002, 00000, 00001`);
|
|
14
|
+
* 3. skip every same-transport sibling when walking back, not just one active entry,
|
|
15
|
+
* so two saves under one transport still diff against the pre-transport state;
|
|
16
|
+
* 4. never require the predecessor to carry a CTS id — released revisions with a blank
|
|
17
|
+
* transport exist and are valid baselines.
|
|
18
|
+
*
|
|
19
|
+
* `selectionMethod` and `baselineStatus` ride the result so a reviewer can tell exact
|
|
20
|
+
* evidence from a fallback guess; SAP's tool reports neither.
|
|
21
|
+
*/
|
|
22
|
+
import { CLASS_REVISION_INCLUDES, REVISION_TYPES } from './client.js';
|
|
23
|
+
import { AdtApiError, isNotFoundError } from './errors.js';
|
|
24
|
+
import { unifiedDiff } from './source-diff.js';
|
|
25
|
+
/**
|
|
26
|
+
* Error text for a result NOTE (not a thrown error).
|
|
27
|
+
*
|
|
28
|
+
* These notes ride a SUCCESS payload, so they never reach dispatch's `formatMinimalAdtError`.
|
|
29
|
+
* Under `ARC1_MINIMAL_ERRORS` the SAP diagnostic and the ADT path must still be withheld —
|
|
30
|
+
* the status code alone is enough for a reviewer to see that something failed.
|
|
31
|
+
*/
|
|
32
|
+
function describeError(err, minimalErrors) {
|
|
33
|
+
if (!minimalErrors)
|
|
34
|
+
return err instanceof Error ? err.message : String(err);
|
|
35
|
+
if (err instanceof AdtApiError)
|
|
36
|
+
return `SAP request failed (status ${err.statusCode})`;
|
|
37
|
+
return 'request failed';
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The two pseudo-versions SAP's `IRevision` maps to UI text rather than a number: `00000` is the
|
|
41
|
+
* ACTIVE work state and `99999` the INACTIVE draft. Either can legitimately be the *current* side
|
|
42
|
+
* of a review — that is the change being shipped — but neither is ever a transported baseline.
|
|
43
|
+
*/
|
|
44
|
+
const ACTIVE_VERSION = '00000';
|
|
45
|
+
const INACTIVE_VERSION = '99999';
|
|
46
|
+
const WORK_STATE_VERSIONS = new Set([ACTIVE_VERSION, INACTIVE_VERSION]);
|
|
47
|
+
/**
|
|
48
|
+
* The 5-digit ADT version number of a revision.
|
|
49
|
+
*
|
|
50
|
+
* On 7.58 the atom `<id>` is the bare number (`00001`). Some releases use a URN there, so
|
|
51
|
+
* fall back to the number segment of the content URI (`…/versions/<ts>/00001/content`).
|
|
52
|
+
*/
|
|
53
|
+
export function revisionNumber(revision) {
|
|
54
|
+
for (const value of [revision.id, revision.uri]) {
|
|
55
|
+
const match = String(value ?? '').match(/(?:^|\/)(\d{5})(?:$|[/?#])/);
|
|
56
|
+
if (match)
|
|
57
|
+
return match[1];
|
|
58
|
+
}
|
|
59
|
+
return '';
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Newest first: timestamp desc, then version number desc, then original order (stable).
|
|
63
|
+
*
|
|
64
|
+
* A revision may carry NO `<atom:updated>` at all (live: CERTRULE_DYNP version 00001 on
|
|
65
|
+
* a4h). Such entries rank AFTER every dated one — a high-numbered undated revision must not
|
|
66
|
+
* outrank a genuinely newer dated one and become the baseline — and are then ordered among
|
|
67
|
+
* themselves by version number.
|
|
68
|
+
*/
|
|
69
|
+
function sortNewestFirst(revisions) {
|
|
70
|
+
return revisions
|
|
71
|
+
.map((revision, index) => {
|
|
72
|
+
const parsed = Date.parse(String(revision.timestamp ?? ''));
|
|
73
|
+
// revisionNumber() returns '' when no digit run is present, and Number('') is 0 — which
|
|
74
|
+
// would rank an unparseable revision alongside ACTIVE (00000). Test the digits instead.
|
|
75
|
+
const raw = revisionNumber(revision);
|
|
76
|
+
return {
|
|
77
|
+
revision,
|
|
78
|
+
index,
|
|
79
|
+
time: Number.isFinite(parsed) ? parsed : Number.NEGATIVE_INFINITY,
|
|
80
|
+
num: /^\d+$/.test(raw) ? Number(raw) : Number.NEGATIVE_INFINITY,
|
|
81
|
+
};
|
|
82
|
+
})
|
|
83
|
+
.sort(
|
|
84
|
+
// Subtracting two -Infinity values yields NaN, so compare the keys instead of
|
|
85
|
+
// differencing them — the ordering must not depend on NaN happening to be falsy.
|
|
86
|
+
(a, b) => compareDesc(a.time, b.time) || compareDesc(a.num, b.num) || a.index - b.index)
|
|
87
|
+
.map((e) => e.revision);
|
|
88
|
+
}
|
|
89
|
+
/** Descending compare that is total for ±Infinity (a - b would be NaN for equal infinities). */
|
|
90
|
+
function compareDesc(a, b) {
|
|
91
|
+
if (a === b)
|
|
92
|
+
return 0;
|
|
93
|
+
return a > b ? -1 : 1;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Pick the revision written under `transportIds` and the one immediately preceding it.
|
|
97
|
+
*
|
|
98
|
+
* `transportIds` should hold the request id AND every task id: version records reference
|
|
99
|
+
* the request on the systems verified so far, but matching both is a superset that can
|
|
100
|
+
* only add correct matches.
|
|
101
|
+
*/
|
|
102
|
+
export function selectTransportRevisionPair(revisions, transportIds) {
|
|
103
|
+
const sorted = sortNewestFirst(revisions);
|
|
104
|
+
const wanted = new Set([...transportIds].map((id) => String(id).trim().toUpperCase()).filter(Boolean));
|
|
105
|
+
const belongsToTransport = (r) => {
|
|
106
|
+
const id = String(r.transport ?? '')
|
|
107
|
+
.trim()
|
|
108
|
+
.toUpperCase();
|
|
109
|
+
return id !== '' && wanted.has(id);
|
|
110
|
+
};
|
|
111
|
+
if (!sorted.length) {
|
|
112
|
+
return { current: null, previous: null, selectionMethod: 'no-revisions', skipped: [] };
|
|
113
|
+
}
|
|
114
|
+
// An UNRELEASED transport has no snapshot of its own — but while its objects are locked,
|
|
115
|
+
// the active entry (00000) carries the transport link, so it matches here and the walk
|
|
116
|
+
// back lands on the last released state. That makes "what am I about to ship" the same
|
|
117
|
+
// code path as "what did this transport ship", with the same evidence labels.
|
|
118
|
+
let currentIndex = sorted.findIndex(belongsToTransport);
|
|
119
|
+
let selectionMethod = 'exact-transport';
|
|
120
|
+
if (currentIndex === -1) {
|
|
121
|
+
// No revision names this transport. Prefer the newest real snapshot over a work state,
|
|
122
|
+
// so the diff is still between two transported versions.
|
|
123
|
+
currentIndex = sorted.findIndex((r) => !WORK_STATE_VERSIONS.has(revisionNumber(r)));
|
|
124
|
+
selectionMethod = 'latest-revision-fallback';
|
|
125
|
+
}
|
|
126
|
+
if (currentIndex === -1) {
|
|
127
|
+
currentIndex = 0;
|
|
128
|
+
selectionMethod = 'active-only-fallback';
|
|
129
|
+
}
|
|
130
|
+
const skipped = [];
|
|
131
|
+
let previousIndex = currentIndex + 1;
|
|
132
|
+
while (previousIndex < sorted.length) {
|
|
133
|
+
const candidate = sorted[previousIndex];
|
|
134
|
+
const num = revisionNumber(candidate);
|
|
135
|
+
if (WORK_STATE_VERSIONS.has(num)) {
|
|
136
|
+
const kind = num === ACTIVE_VERSION ? 'active work state' : 'inactive draft';
|
|
137
|
+
skipped.push({ revision: candidate, reason: `${kind} (version ${num}), not a transported predecessor` });
|
|
138
|
+
}
|
|
139
|
+
else if (belongsToTransport(candidate)) {
|
|
140
|
+
skipped.push({ revision: candidate, reason: 'belongs to the same transport — baseline must predate it' });
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
previousIndex += 1;
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
current: sorted[currentIndex],
|
|
149
|
+
previous: previousIndex < sorted.length ? sorted[previousIndex] : null,
|
|
150
|
+
selectionMethod,
|
|
151
|
+
skipped,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Classify the "before" side.
|
|
156
|
+
*
|
|
157
|
+
* Creation is asserted ONLY when the current revision was matched to the transport and has
|
|
158
|
+
* no predecessor. A missing predecessor under a fallback selection is ambiguous — it may
|
|
159
|
+
* simply mean the object's history was never snapshotted.
|
|
160
|
+
*/
|
|
161
|
+
export function baselineStatusFor(pair, allRevisions = []) {
|
|
162
|
+
if (!pair.current)
|
|
163
|
+
return 'baseline-unavailable';
|
|
164
|
+
const matched = pair.selectionMethod === 'exact-transport';
|
|
165
|
+
if (pair.previous)
|
|
166
|
+
return matched ? 'prior-revision' : 'prior-revision-unverified';
|
|
167
|
+
if (!matched)
|
|
168
|
+
return 'baseline-ambiguous';
|
|
169
|
+
// "Matched with no predecessor" normally means created here — but for an OPEN transport the
|
|
170
|
+
// active row carries the transport link, so `matched` is trivially true, and SAP only writes
|
|
171
|
+
// versions on release. If any revision has a strictly lower version number, the object plainly
|
|
172
|
+
// pre-existed and the walk-back simply failed to reach it (e.g. the transport's own revision
|
|
173
|
+
// is undated and sorts last). Creation is asserted only when nothing older exists.
|
|
174
|
+
const currentNum = Number(revisionNumber(pair.current));
|
|
175
|
+
const hasOlder = allRevisions.some((r) => {
|
|
176
|
+
const raw = revisionNumber(r);
|
|
177
|
+
return /^\d+$/.test(raw) && !WORK_STATE_VERSIONS.has(raw) && Number(raw) < currentNum;
|
|
178
|
+
});
|
|
179
|
+
return hasOlder ? 'baseline-ambiguous' : 'no-prior-snapshot';
|
|
180
|
+
}
|
|
181
|
+
// ─── Logical object rollup ──────────────────────────────────────────
|
|
182
|
+
/**
|
|
183
|
+
* LIMU component types that belong to a class.
|
|
184
|
+
*
|
|
185
|
+
* `REPT` (text pool) deliberately is NOT here: it exists for BOTH classes (the `====CP` class
|
|
186
|
+
* pool) and programs, and claiming it for classes turned every report with text symbols into a
|
|
187
|
+
* phantom class. It is resolved by `wbtype`/name shape below instead.
|
|
188
|
+
*/
|
|
189
|
+
const CLASS_COMPONENT_TYPES = new Set(['CINC', 'CPRI', 'CPRO', 'CPUB', 'CLSD', 'METH']);
|
|
190
|
+
/** LIMU source types that roll up to a program (or, by `wbtype`, an include). */
|
|
191
|
+
const PROGRAM_COMPONENT_TYPES = new Set(['REPS', 'REPT']);
|
|
192
|
+
/**
|
|
193
|
+
* The owning class of a LIMU class component, or '' when the entry is not one.
|
|
194
|
+
*
|
|
195
|
+
* CTS pads the class name to 30 characters and appends the component:
|
|
196
|
+
* `ZCL_ARC1_DEMO_CALC SUBTRACT` (METH — space padded)
|
|
197
|
+
* `ZCL_ARC1_DEMO_CALC============CCIMP` (CINC — '=' padded)
|
|
198
|
+
* Both live shapes verified on a4h. Taking the first 30 chars and cutting at the first
|
|
199
|
+
* '=' handles both, where SAP's own `^([^\s]+)` leaves `====CCIMP` attached.
|
|
200
|
+
*
|
|
201
|
+
* `REPT` is ambiguous (class pool vs program text pool), so it counts as a class component
|
|
202
|
+
* only when `wbtype` says CLAS or the name carries the `=`-padded class-pool shape.
|
|
203
|
+
*/
|
|
204
|
+
function classOwnerName(pgmid, type, wbtype, name) {
|
|
205
|
+
if (pgmid !== 'LIMU')
|
|
206
|
+
return '';
|
|
207
|
+
const wb = wbtype.toUpperCase();
|
|
208
|
+
const isClassComponent = CLASS_COMPONENT_TYPES.has(type) || wb.startsWith('CLAS/') || (type === 'REPT' && name.includes('='));
|
|
209
|
+
if (!isClassComponent)
|
|
210
|
+
return '';
|
|
211
|
+
return name.slice(0, 30).replace(/=+.*$/, '').trimEnd();
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* ADT splits programs and includes across two endpoints (`/programs/programs/` vs
|
|
215
|
+
* `/programs/includes/`) although CTS types both as `R3TR PROG` / `LIMU REPS`. Only `wbtype`
|
|
216
|
+
* carries the distinction, so an include typed as PROG would 404 on every revision lookup.
|
|
217
|
+
*/
|
|
218
|
+
function isIncludeWbtype(wbtype) {
|
|
219
|
+
return wbtype.toUpperCase().startsWith('PROG/I');
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* A FUNCTION-GROUP *source* entry: the group container (`FUGR/F`), its main program
|
|
223
|
+
* (`FUGR/PX`) or a structural include (`FUGR/I`, live-verified on 7.50 and 7.58 — see
|
|
224
|
+
* `src/handlers/read.ts`). These live under `/functions/groups/{group}/...`, which has no
|
|
225
|
+
* revisions feed here, so they are reported as inventory rather than 404'd elsewhere.
|
|
226
|
+
*
|
|
227
|
+
* `FUGR/FF` is deliberately EXCLUDED: it is a function MODULE (`LIMU FUNC`), which
|
|
228
|
+
* `SLASH_TYPE_MAP` maps to the fully supported `FUNC` type. Matching the bare `FUGR/`
|
|
229
|
+
* prefix would send every changed function module to inventory instead of diffing it.
|
|
230
|
+
*/
|
|
231
|
+
function isFunctionGroupSource(wbtype) {
|
|
232
|
+
const wb = wbtype.toUpperCase();
|
|
233
|
+
return wb.startsWith('FUGR/') && !wb.startsWith('FUGR/FF');
|
|
234
|
+
}
|
|
235
|
+
/** Marker type for a function-group part, so `diffTransportObject` can explain it. */
|
|
236
|
+
const FUGR_INCLUDE_TYPE = 'FUGR_INCLUDE';
|
|
237
|
+
/**
|
|
238
|
+
* Collapse a transport's raw entries into reviewable objects.
|
|
239
|
+
*
|
|
240
|
+
* `parseTransportList` already yields task-level entries only, so request-level and
|
|
241
|
+
* `<tm:all_objects>` duplicates never arrive here — but the same object under two tasks
|
|
242
|
+
* does, and LIMU names are unusable as ADT object names either way.
|
|
243
|
+
*/
|
|
244
|
+
export function rollupTransportObjects(tasks) {
|
|
245
|
+
const byKey = new Map();
|
|
246
|
+
for (const task of tasks) {
|
|
247
|
+
for (const object of task.objects) {
|
|
248
|
+
const pgmid = String(object.pgmid ?? '').toUpperCase();
|
|
249
|
+
// Release comments ("Comment Entry: Released") are bookkeeping, not repository objects.
|
|
250
|
+
if (pgmid === 'CORR')
|
|
251
|
+
continue;
|
|
252
|
+
const rawType = String(object.type ?? '').toUpperCase();
|
|
253
|
+
const wbtype = String(object.wbtype ?? '');
|
|
254
|
+
const rawName = String(object.name ?? '').toUpperCase();
|
|
255
|
+
const owner = classOwnerName(pgmid, rawType, wbtype, rawName);
|
|
256
|
+
let type = rawType;
|
|
257
|
+
let name = rawName;
|
|
258
|
+
let logicalPgmid = pgmid;
|
|
259
|
+
if (owner) {
|
|
260
|
+
logicalPgmid = 'R3TR';
|
|
261
|
+
type = 'CLAS';
|
|
262
|
+
name = owner;
|
|
263
|
+
}
|
|
264
|
+
else if (isFunctionGroupSource(wbtype)) {
|
|
265
|
+
// FUGR sources are not addressable via the program/include endpoints — keep the entry
|
|
266
|
+
// visible as inventory instead of routing it somewhere that 404s.
|
|
267
|
+
logicalPgmid = 'R3TR';
|
|
268
|
+
type = FUGR_INCLUDE_TYPE;
|
|
269
|
+
}
|
|
270
|
+
else if (pgmid === 'LIMU' && PROGRAM_COMPONENT_TYPES.has(rawType)) {
|
|
271
|
+
logicalPgmid = 'R3TR';
|
|
272
|
+
type = isIncludeWbtype(wbtype) ? 'INCL' : 'PROG';
|
|
273
|
+
}
|
|
274
|
+
else if (type === 'PROG' && isIncludeWbtype(wbtype)) {
|
|
275
|
+
// R3TR PROG with wbtype PROG/I is a standalone include, not a program.
|
|
276
|
+
type = 'INCL';
|
|
277
|
+
}
|
|
278
|
+
if (!type || !name)
|
|
279
|
+
continue;
|
|
280
|
+
const key = `${logicalPgmid}:${type}:${name}`;
|
|
281
|
+
const component = { pgmid, type: rawType, name: object.name, wbtype, taskId: task.id };
|
|
282
|
+
const existing = byKey.get(key);
|
|
283
|
+
if (!existing) {
|
|
284
|
+
byKey.set(key, {
|
|
285
|
+
pgmid: logicalPgmid,
|
|
286
|
+
type,
|
|
287
|
+
name,
|
|
288
|
+
description: String(object.description ?? ''),
|
|
289
|
+
taskIds: [task.id],
|
|
290
|
+
components: [component],
|
|
291
|
+
});
|
|
292
|
+
continue;
|
|
293
|
+
}
|
|
294
|
+
existing.description ||= String(object.description ?? '');
|
|
295
|
+
if (!existing.taskIds.includes(task.id))
|
|
296
|
+
existing.taskIds.push(task.id);
|
|
297
|
+
existing.components.push(component);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
return [...byKey.values()];
|
|
301
|
+
}
|
|
302
|
+
// ─── Per-object diffing ─────────────────────────────────────────────
|
|
303
|
+
/** Class-pool suffix → the ADT include that holds it. */
|
|
304
|
+
const CLASS_POOL_INCLUDES = {
|
|
305
|
+
CCDEF: 'definitions',
|
|
306
|
+
CCIMP: 'implementations',
|
|
307
|
+
CCMAC: 'macros',
|
|
308
|
+
CCAU: 'testclasses',
|
|
309
|
+
};
|
|
310
|
+
/**
|
|
311
|
+
* Which class includes this transport actually touched.
|
|
312
|
+
*
|
|
313
|
+
* CTS already states it: a `CINC ZCL_X============CCIMP` entry names the include, and
|
|
314
|
+
* `METH`/`CPUB`/`CPRI`/`CPRO`/`CLSD` mean the main source. Reading that is strictly better
|
|
315
|
+
* than diffing all five and guessing afterwards which were untouched — it cannot mislabel a
|
|
316
|
+
* changed include as unchanged, and it drops ~4/5 of the SAP round trips for a typical class.
|
|
317
|
+
* A bare `R3TR CLAS` entry carries no component detail, so fall back to all five.
|
|
318
|
+
*/
|
|
319
|
+
export function classIncludesFor(object) {
|
|
320
|
+
const includes = new Set();
|
|
321
|
+
for (const c of object.components) {
|
|
322
|
+
// A whole-class R3TR entry is exactly the case where CTS records NO component detail
|
|
323
|
+
// (`R3TR CLAS X` and `LIMU <sub> X` are mutually exclusive per request — measured across
|
|
324
|
+
// ~640k LIMU rows on 758, zero counterexamples), so fall back to every include.
|
|
325
|
+
if (c.pgmid !== 'LIMU')
|
|
326
|
+
return { includes: [...CLASS_REVISION_INCLUDES], fromComponents: false };
|
|
327
|
+
// The suffix starts at a FIXED offset: CTS pads the class name into a 30-char field. It
|
|
328
|
+
// pads with '=' only when the name is shorter — 6.6% of live CINC rows are 30-char names
|
|
329
|
+
// with no padding at all, where splitting on '=' returns the whole string and silently
|
|
330
|
+
// resolves to `main`. Positions 31+ hold only CCAU/CCIMP/CCDEF/CCMAC (census-verified);
|
|
331
|
+
// for METH/CLSD/CPUB/CPRI/CPRO they hold a method name or '', which correctly means main.
|
|
332
|
+
const suffix = c.name.slice(30).trim().toUpperCase();
|
|
333
|
+
includes.add(CLASS_POOL_INCLUDES[suffix] ?? 'main');
|
|
334
|
+
}
|
|
335
|
+
return includes.size
|
|
336
|
+
? { includes: [...includes], fromComponents: true }
|
|
337
|
+
: { includes: [...CLASS_REVISION_INCLUDES], fromComponents: false };
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Per-part diff cap. A created object renders its ENTIRE source as an addition, so a page of
|
|
341
|
+
* 20 such objects is otherwise unbounded — `MAX_DIFF_OBJECTS` limits the object count, never
|
|
342
|
+
* the bytes. `added`/`removed` are counted before truncation, so the totals stay honest.
|
|
343
|
+
*/
|
|
344
|
+
const MAX_DIFF_LINES = 400;
|
|
345
|
+
/** Trim a unified diff to `MAX_DIFF_LINES` body lines, keeping the header. */
|
|
346
|
+
function capDiff(diff) {
|
|
347
|
+
const lines = diff.split('\n');
|
|
348
|
+
if (lines.length <= MAX_DIFF_LINES)
|
|
349
|
+
return { diff, truncated: false };
|
|
350
|
+
return {
|
|
351
|
+
diff: `${lines.slice(0, MAX_DIFF_LINES).join('\n')}\n… diff truncated at ${MAX_DIFF_LINES} lines`,
|
|
352
|
+
truncated: true,
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
/** Short evidence label for a revision, e.g. `00001 (A4HK906289)`. */
|
|
356
|
+
function revisionLabel(revision) {
|
|
357
|
+
const num = revisionNumber(revision) || revision.id || '?';
|
|
358
|
+
return revision.transport ? `${num} (${revision.transport})` : num;
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Build the "we could not read this" part row. Message text is sanitized by the caller.
|
|
362
|
+
*
|
|
363
|
+
* `resolved` carries whatever evidence was already established. A failure AFTER pair selection
|
|
364
|
+
* (a flaky source GET) must keep its `selectionMethod`/`from`/`to` — claiming "no revisions"
|
|
365
|
+
* for an object whose pair WAS identified is a false signal in the field a reviewer uses to
|
|
366
|
+
* judge evidence quality.
|
|
367
|
+
*/
|
|
368
|
+
function unavailablePart(part, note, resolved) {
|
|
369
|
+
return {
|
|
370
|
+
part,
|
|
371
|
+
baselineStatus: 'baseline-unavailable',
|
|
372
|
+
selectionMethod: resolved?.selectionMethod ?? 'no-revisions',
|
|
373
|
+
from: resolved?.from ?? null,
|
|
374
|
+
to: resolved?.to ?? null,
|
|
375
|
+
added: 0,
|
|
376
|
+
removed: 0,
|
|
377
|
+
diff: '',
|
|
378
|
+
note,
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* Diff one source part of one object across the transport boundary.
|
|
383
|
+
*
|
|
384
|
+
* Returns null ONLY for a class include that genuinely does not exist (most classes have no
|
|
385
|
+
* CCAU test include) — every other failure becomes a visible `baseline-unavailable` row, so a
|
|
386
|
+
* read error can never masquerade as "unchanged".
|
|
387
|
+
*/
|
|
388
|
+
async function diffPart(client, type, name, part, transportIds, opts) {
|
|
389
|
+
const include = type === 'CLAS' ? part : undefined;
|
|
390
|
+
let revisions;
|
|
391
|
+
try {
|
|
392
|
+
revisions = (await client.getRevisions(type, name, { include, group: opts.group })).revisions;
|
|
393
|
+
}
|
|
394
|
+
catch (err) {
|
|
395
|
+
if (type === 'CLAS' && part !== 'main' && isNotFoundError(err))
|
|
396
|
+
return null;
|
|
397
|
+
return unavailablePart(part, `revision history unavailable: ${describeError(err, opts.minimalErrors)}`);
|
|
398
|
+
}
|
|
399
|
+
const pair = selectTransportRevisionPair(revisions, transportIds);
|
|
400
|
+
const base = {
|
|
401
|
+
part,
|
|
402
|
+
baselineStatus: baselineStatusFor(pair, revisions),
|
|
403
|
+
selectionMethod: pair.selectionMethod,
|
|
404
|
+
from: pair.previous ? revisionLabel(pair.previous) : null,
|
|
405
|
+
to: pair.current ? revisionLabel(pair.current) : null,
|
|
406
|
+
};
|
|
407
|
+
if (!pair.current) {
|
|
408
|
+
return { ...base, added: 0, removed: 0, diff: '', note: 'no revision history for this part' };
|
|
409
|
+
}
|
|
410
|
+
let after;
|
|
411
|
+
let before;
|
|
412
|
+
try {
|
|
413
|
+
// No predecessor: render the whole thing as an addition so a created object is still
|
|
414
|
+
// reviewable. `baselineStatus` says whether that is proven creation or a missing base.
|
|
415
|
+
[after, before] = await Promise.all([
|
|
416
|
+
client.getRevisionSource(pair.current.uri),
|
|
417
|
+
pair.previous ? client.getRevisionSource(pair.previous.uri) : Promise.resolve(''),
|
|
418
|
+
]);
|
|
419
|
+
}
|
|
420
|
+
catch (err) {
|
|
421
|
+
return unavailablePart(part, `source read failed: ${describeError(err, opts.minimalErrors)}`, base);
|
|
422
|
+
}
|
|
423
|
+
const result = unifiedDiff(before, after, `${name} (${base.from ?? 'none'})`, `${name} (${base.to})`, 3, true);
|
|
424
|
+
const capped = capDiff(result.diff);
|
|
425
|
+
const note = result.cosmeticOnly
|
|
426
|
+
? 'whitespace-only change (trailing blanks / final newline)'
|
|
427
|
+
: result.identical
|
|
428
|
+
? 'no source change between the selected revisions'
|
|
429
|
+
: undefined;
|
|
430
|
+
return {
|
|
431
|
+
...base,
|
|
432
|
+
added: result.added,
|
|
433
|
+
removed: result.removed,
|
|
434
|
+
diff: capped.diff,
|
|
435
|
+
...(capped.truncated ? { diffTruncated: true } : {}),
|
|
436
|
+
...(note ? { note } : {}),
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
/** Diff every source part of one logical object. Never throws — failures become visible rows. */
|
|
440
|
+
export async function diffTransportObject(client, object, transportIds, opts = {}) {
|
|
441
|
+
const { type, name, taskIds } = object;
|
|
442
|
+
const head = { type, name, taskIds };
|
|
443
|
+
if (type === FUGR_INCLUDE_TYPE) {
|
|
444
|
+
return {
|
|
445
|
+
...head,
|
|
446
|
+
parts: [],
|
|
447
|
+
inventoryReason: 'function-group source (wbtype FUGR/*) — in scope, but its includes live under /functions/groups and have no revisions feed here',
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
if (!REVISION_TYPES.has(type)) {
|
|
451
|
+
return {
|
|
452
|
+
...head,
|
|
453
|
+
parts: [],
|
|
454
|
+
inventoryReason: `type ${type} has no ADT source revision feed — in scope, but no source diff available`,
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
// FUNC revisions are addressed under their group. A lookup failure must not abort the whole
|
|
458
|
+
// review, so it degrades to an inventory row like any other per-object problem.
|
|
459
|
+
let group;
|
|
460
|
+
if (type === 'FUNC') {
|
|
461
|
+
try {
|
|
462
|
+
group = (await client.resolveFunctionGroup(name)) ?? undefined;
|
|
463
|
+
}
|
|
464
|
+
catch (err) {
|
|
465
|
+
return {
|
|
466
|
+
...head,
|
|
467
|
+
parts: [],
|
|
468
|
+
inventoryReason: `function group lookup failed: ${describeError(err, opts.minimalErrors)}`,
|
|
469
|
+
};
|
|
470
|
+
}
|
|
471
|
+
if (!group) {
|
|
472
|
+
return { ...head, parts: [], inventoryReason: `cannot resolve the function group for FUNC ${name}` };
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
// Parts are independent reads; http.ts funnels every request through the shared Semaphore
|
|
476
|
+
// (ARC1_MAX_CONCURRENT), so fanning out here is bounded without extra bookkeeping.
|
|
477
|
+
const selection = type === 'CLAS' ? classIncludesFor(object) : { includes: ['main'], fromComponents: true };
|
|
478
|
+
const wanted = selection.includes;
|
|
479
|
+
const settled = await Promise.all(wanted.map(async (part) => {
|
|
480
|
+
try {
|
|
481
|
+
return await diffPart(client, type, name, part, transportIds, { group, minimalErrors: opts.minimalErrors });
|
|
482
|
+
}
|
|
483
|
+
catch (err) {
|
|
484
|
+
if (type === 'CLAS' && part !== 'main' && isNotFoundError(err))
|
|
485
|
+
return null;
|
|
486
|
+
return unavailablePart(part, `source read failed: ${describeError(err, opts.minimalErrors)}`);
|
|
487
|
+
}
|
|
488
|
+
}));
|
|
489
|
+
const parts = settled.filter((p) => p !== null);
|
|
490
|
+
// Every selected part turned out not to exist. Dropping them all would emit an object with
|
|
491
|
+
// no rows and no reason — indistinguishable from "nothing changed", which is the one thing
|
|
492
|
+
// this tool must never say by accident.
|
|
493
|
+
if (!parts.length) {
|
|
494
|
+
return {
|
|
495
|
+
...head,
|
|
496
|
+
parts: [],
|
|
497
|
+
inventoryReason: `no readable source for ${wanted.join(', ')} — the object or its includes could not be found`,
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
return { ...head, parts: selection.fromComponents ? parts : suppressUntouchedParts(parts) };
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* Blank the DIFF of parts this transport did not touch, keeping the row for coverage.
|
|
504
|
+
*
|
|
505
|
+
* ONLY valid for a SPECULATIVE part list. When the includes came from the transport's own
|
|
506
|
+
* components, every selected part was named by CTS and therefore WAS changed — suppressing
|
|
507
|
+
* one because its revision happens to carry no CTS id (a live-verified shape) would erase a
|
|
508
|
+
* real diff and report it clean. The caller enforces that; this function assumes the parts
|
|
509
|
+
* were probed blindly.
|
|
510
|
+
*
|
|
511
|
+
* Without it, the whole-class (`R3TR CLAS`) shape renders SAP's boilerplate headers in the
|
|
512
|
+
* four untouched includes as fresh additions — noise around one real change.
|
|
513
|
+
*
|
|
514
|
+
* Two further guards: suppress only when a sibling part DID match the transport (so
|
|
515
|
+
* attribution demonstrably works for this object), and NEVER touch a row whose read failed.
|
|
516
|
+
*/
|
|
517
|
+
function suppressUntouchedParts(parts) {
|
|
518
|
+
if (!parts.some((p) => p.selectionMethod === 'exact-transport'))
|
|
519
|
+
return parts;
|
|
520
|
+
return parts.map((p) => p.selectionMethod === 'exact-transport' || p.baselineStatus === 'baseline-unavailable'
|
|
521
|
+
? p
|
|
522
|
+
: { ...p, added: 0, removed: 0, diff: '', note: 'not changed by this transport' });
|
|
523
|
+
}
|
|
524
|
+
//# sourceMappingURL=transport-diff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport-diff.js","sourceRoot":"","sources":["../../src/adt/transport-diff.ts"],"names":[],"mappings":"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"}
|