arc-1 0.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/LICENSE +21 -0
- package/README.md +222 -0
- package/bin/arc1.js +12 -0
- package/dist/adt/btp.d.ts +122 -0
- package/dist/adt/btp.d.ts.map +1 -0
- package/dist/adt/btp.js +392 -0
- package/dist/adt/btp.js.map +1 -0
- package/dist/adt/client.d.ts +89 -0
- package/dist/adt/client.d.ts.map +1 -0
- package/dist/adt/client.js +208 -0
- package/dist/adt/client.js.map +1 -0
- package/dist/adt/codeintel.d.ts +38 -0
- package/dist/adt/codeintel.d.ts.map +1 -0
- package/dist/adt/codeintel.js +61 -0
- package/dist/adt/codeintel.js.map +1 -0
- package/dist/adt/config.d.ts +65 -0
- package/dist/adt/config.d.ts.map +1 -0
- package/dist/adt/config.js +35 -0
- package/dist/adt/config.js.map +1 -0
- package/dist/adt/cookies.d.ts +27 -0
- package/dist/adt/cookies.d.ts.map +1 -0
- package/dist/adt/cookies.js +67 -0
- package/dist/adt/cookies.js.map +1 -0
- package/dist/adt/crud.d.ts +35 -0
- package/dist/adt/crud.d.ts.map +1 -0
- package/dist/adt/crud.js +87 -0
- package/dist/adt/crud.js.map +1 -0
- package/dist/adt/devtools.d.ts +32 -0
- package/dist/adt/devtools.d.ts.map +1 -0
- package/dist/adt/devtools.js +154 -0
- package/dist/adt/devtools.js.map +1 -0
- package/dist/adt/errors.d.ts +49 -0
- package/dist/adt/errors.d.ts.map +1 -0
- package/dist/adt/errors.js +80 -0
- package/dist/adt/errors.js.map +1 -0
- package/dist/adt/features.d.ts +44 -0
- package/dist/adt/features.d.ts.map +1 -0
- package/dist/adt/features.js +173 -0
- package/dist/adt/features.js.map +1 -0
- package/dist/adt/http.d.ts +116 -0
- package/dist/adt/http.d.ts.map +1 -0
- package/dist/adt/http.js +374 -0
- package/dist/adt/http.js.map +1 -0
- package/dist/adt/safety.d.ts +70 -0
- package/dist/adt/safety.d.ts.map +1 -0
- package/dist/adt/safety.js +222 -0
- package/dist/adt/safety.js.map +1 -0
- package/dist/adt/transport.d.ts +18 -0
- package/dist/adt/transport.d.ts.map +1 -0
- package/dist/adt/transport.js +66 -0
- package/dist/adt/transport.js.map +1 -0
- package/dist/adt/types.d.ts +91 -0
- package/dist/adt/types.d.ts.map +1 -0
- package/dist/adt/types.js +9 -0
- package/dist/adt/types.js.map +1 -0
- package/dist/adt/xml-parser.d.ts +109 -0
- package/dist/adt/xml-parser.d.ts.map +1 -0
- package/dist/adt/xml-parser.js +283 -0
- package/dist/adt/xml-parser.js.map +1 -0
- package/dist/cache/cache.d.ts +61 -0
- package/dist/cache/cache.d.ts.map +1 -0
- package/dist/cache/cache.js +14 -0
- package/dist/cache/cache.js.map +1 -0
- package/dist/cache/memory.d.ts +25 -0
- package/dist/cache/memory.d.ts.map +1 -0
- package/dist/cache/memory.js +69 -0
- package/dist/cache/memory.js.map +1 -0
- package/dist/cache/sqlite.d.ts +26 -0
- package/dist/cache/sqlite.d.ts.map +1 -0
- package/dist/cache/sqlite.js +130 -0
- package/dist/cache/sqlite.js.map +1 -0
- package/dist/cli.d.ts +14 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +101 -0
- package/dist/cli.js.map +1 -0
- package/dist/context/compressor.d.ts +33 -0
- package/dist/context/compressor.d.ts.map +1 -0
- package/dist/context/compressor.js +208 -0
- package/dist/context/compressor.js.map +1 -0
- package/dist/context/contract.d.ts +14 -0
- package/dist/context/contract.d.ts.map +1 -0
- package/dist/context/contract.js +202 -0
- package/dist/context/contract.js.map +1 -0
- package/dist/context/deps.d.ts +32 -0
- package/dist/context/deps.d.ts.map +1 -0
- package/dist/context/deps.js +240 -0
- package/dist/context/deps.js.map +1 -0
- package/dist/context/types.d.ts +56 -0
- package/dist/context/types.d.ts.map +1 -0
- package/dist/context/types.js +10 -0
- package/dist/context/types.js.map +1 -0
- package/dist/handlers/intent.d.ts +46 -0
- package/dist/handlers/intent.d.ts.map +1 -0
- package/dist/handlers/intent.js +539 -0
- package/dist/handlers/intent.js.map +1 -0
- package/dist/handlers/tools.d.ts +21 -0
- package/dist/handlers/tools.d.ts.map +1 -0
- package/dist/handlers/tools.js +260 -0
- package/dist/handlers/tools.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/lint/lint.d.ts +35 -0
- package/dist/lint/lint.d.ts.map +1 -0
- package/dist/lint/lint.js +67 -0
- package/dist/lint/lint.js.map +1 -0
- package/dist/server/audit.d.ts +96 -0
- package/dist/server/audit.d.ts.map +1 -0
- package/dist/server/audit.js +27 -0
- package/dist/server/audit.js.map +1 -0
- package/dist/server/config.d.ts +19 -0
- package/dist/server/config.d.ts.map +1 -0
- package/dist/server/config.js +101 -0
- package/dist/server/config.js.map +1 -0
- package/dist/server/context.d.ts +20 -0
- package/dist/server/context.d.ts.map +1 -0
- package/dist/server/context.js +20 -0
- package/dist/server/context.js.map +1 -0
- package/dist/server/elicit.d.ts +43 -0
- package/dist/server/elicit.d.ts.map +1 -0
- package/dist/server/elicit.js +183 -0
- package/dist/server/elicit.js.map +1 -0
- package/dist/server/http.d.ts +34 -0
- package/dist/server/http.d.ts.map +1 -0
- package/dist/server/http.js +328 -0
- package/dist/server/http.js.map +1 -0
- package/dist/server/logger.d.ts +57 -0
- package/dist/server/logger.d.ts.map +1 -0
- package/dist/server/logger.js +129 -0
- package/dist/server/logger.js.map +1 -0
- package/dist/server/server.d.ts +25 -0
- package/dist/server/server.d.ts.map +1 -0
- package/dist/server/server.js +307 -0
- package/dist/server/server.js.map +1 -0
- package/dist/server/sinks/btp-auditlog.d.ts +48 -0
- package/dist/server/sinks/btp-auditlog.d.ts.map +1 -0
- package/dist/server/sinks/btp-auditlog.js +232 -0
- package/dist/server/sinks/btp-auditlog.js.map +1 -0
- package/dist/server/sinks/file.d.ts +22 -0
- package/dist/server/sinks/file.d.ts.map +1 -0
- package/dist/server/sinks/file.js +59 -0
- package/dist/server/sinks/file.js.map +1 -0
- package/dist/server/sinks/stderr.d.ts +19 -0
- package/dist/server/sinks/stderr.d.ts.map +1 -0
- package/dist/server/sinks/stderr.js +63 -0
- package/dist/server/sinks/stderr.js.map +1 -0
- package/dist/server/sinks/types.d.ts +14 -0
- package/dist/server/sinks/types.d.ts.map +1 -0
- package/dist/server/sinks/types.js +8 -0
- package/dist/server/sinks/types.js.map +1 -0
- package/dist/server/types.d.ts +54 -0
- package/dist/server/types.d.ts.map +1 -0
- package/dist/server/types.js +42 -0
- package/dist/server/types.js.map +1 -0
- package/dist/server/xsuaa.d.ts +77 -0
- package/dist/server/xsuaa.d.ts.map +1 -0
- package/dist/server/xsuaa.js +364 -0
- package/dist/server/xsuaa.js.map +1 -0
- package/package.json +66 -0
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Safety system for ARC-1.
|
|
3
|
+
*
|
|
4
|
+
* Gates all operations before they reach SAP. This is the first line of defense
|
|
5
|
+
* against unintended modifications — it runs before any HTTP call.
|
|
6
|
+
*
|
|
7
|
+
* Key design principle: safety checks are declarative and composable.
|
|
8
|
+
* Each check is independent: readOnly, blockFreeSQL, allowedOps, disallowedOps,
|
|
9
|
+
* allowedPackages, enableTransports, etc. They combine additively — if ANY
|
|
10
|
+
* check blocks the operation, it's blocked.
|
|
11
|
+
*
|
|
12
|
+
* This matches the Go implementation exactly (pkg/adt/safety.go) to ensure
|
|
13
|
+
* behavioral parity during migration.
|
|
14
|
+
*/
|
|
15
|
+
import { AdtSafetyError } from './errors.js';
|
|
16
|
+
/**
|
|
17
|
+
* Operation type codes.
|
|
18
|
+
* Single-character codes used in allowedOps/disallowedOps strings.
|
|
19
|
+
* Example: "RSQ" = allow Read, Search, Query only.
|
|
20
|
+
*/
|
|
21
|
+
export const OperationType = {
|
|
22
|
+
Read: 'R',
|
|
23
|
+
Search: 'S',
|
|
24
|
+
Query: 'Q',
|
|
25
|
+
FreeSQL: 'F',
|
|
26
|
+
Create: 'C',
|
|
27
|
+
Update: 'U',
|
|
28
|
+
Delete: 'D',
|
|
29
|
+
Activate: 'A',
|
|
30
|
+
Test: 'T',
|
|
31
|
+
Lock: 'L',
|
|
32
|
+
Intelligence: 'I',
|
|
33
|
+
Workflow: 'W',
|
|
34
|
+
Transport: 'X',
|
|
35
|
+
};
|
|
36
|
+
/** Write operations that are blocked in read-only mode */
|
|
37
|
+
const WRITE_OPS = 'CDUAW';
|
|
38
|
+
/** Safe defaults: read-only, no free SQL, standard ops only */
|
|
39
|
+
export function defaultSafetyConfig() {
|
|
40
|
+
return {
|
|
41
|
+
readOnly: true,
|
|
42
|
+
blockFreeSQL: true,
|
|
43
|
+
allowedOps: 'RSQTI',
|
|
44
|
+
disallowedOps: '',
|
|
45
|
+
allowedPackages: [],
|
|
46
|
+
dryRun: false,
|
|
47
|
+
enableTransports: false,
|
|
48
|
+
transportReadOnly: false,
|
|
49
|
+
allowedTransports: [],
|
|
50
|
+
allowTransportableEdits: false,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/** No restrictions — use with caution */
|
|
54
|
+
export function unrestrictedSafetyConfig() {
|
|
55
|
+
return {
|
|
56
|
+
readOnly: false,
|
|
57
|
+
blockFreeSQL: false,
|
|
58
|
+
allowedOps: '',
|
|
59
|
+
disallowedOps: '',
|
|
60
|
+
allowedPackages: [],
|
|
61
|
+
dryRun: false,
|
|
62
|
+
enableTransports: false,
|
|
63
|
+
transportReadOnly: false,
|
|
64
|
+
allowedTransports: [],
|
|
65
|
+
allowTransportableEdits: false,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/** Check if an operation type is allowed by the safety config */
|
|
69
|
+
export function isOperationAllowed(config, op) {
|
|
70
|
+
// DryRun mode allows everything (but doesn't execute)
|
|
71
|
+
if (config.dryRun)
|
|
72
|
+
return true;
|
|
73
|
+
// ReadOnly blocks all write operations
|
|
74
|
+
if (config.readOnly && WRITE_OPS.includes(op))
|
|
75
|
+
return false;
|
|
76
|
+
// BlockFreeSQL specifically blocks free SQL queries
|
|
77
|
+
if (config.blockFreeSQL && op === OperationType.FreeSQL)
|
|
78
|
+
return false;
|
|
79
|
+
// Transport operations require explicit opt-in
|
|
80
|
+
if (op === OperationType.Transport && !config.enableTransports)
|
|
81
|
+
return false;
|
|
82
|
+
// Disallowed ops blacklist (takes precedence over allowed)
|
|
83
|
+
if (config.disallowedOps?.includes(op))
|
|
84
|
+
return false;
|
|
85
|
+
// Allowed ops whitelist (if set, only listed ops are allowed)
|
|
86
|
+
if (config.allowedOps && !config.allowedOps.includes(op))
|
|
87
|
+
return false;
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
/** Check operation and throw AdtSafetyError if blocked */
|
|
91
|
+
export function checkOperation(config, op, opName) {
|
|
92
|
+
if (!isOperationAllowed(config, op)) {
|
|
93
|
+
throw new AdtSafetyError(`Operation '${opName}' (type ${op}) is blocked by safety configuration`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/** Check if operations on a given package are allowed */
|
|
97
|
+
export function isPackageAllowed(config, pkg) {
|
|
98
|
+
if (config.allowedPackages.length === 0)
|
|
99
|
+
return true;
|
|
100
|
+
const upperPkg = pkg.toUpperCase();
|
|
101
|
+
for (const allowed of config.allowedPackages) {
|
|
102
|
+
const upperAllowed = allowed.toUpperCase();
|
|
103
|
+
// Exact match
|
|
104
|
+
if (upperAllowed === upperPkg)
|
|
105
|
+
return true;
|
|
106
|
+
// Wildcard match: "Z*" matches "ZTEST", "ZRAY", etc.
|
|
107
|
+
if (upperAllowed.endsWith('*')) {
|
|
108
|
+
const prefix = upperAllowed.slice(0, -1);
|
|
109
|
+
if (upperPkg.startsWith(prefix))
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
/** Check package and throw AdtSafetyError if blocked */
|
|
116
|
+
export function checkPackage(config, pkg) {
|
|
117
|
+
if (!isPackageAllowed(config, pkg)) {
|
|
118
|
+
throw new AdtSafetyError(`Operations on package '${pkg}' are blocked by safety configuration (allowed: ${JSON.stringify(config.allowedPackages)})`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/** Check if a transport is in the whitelist (helper, doesn't check enableTransports) */
|
|
122
|
+
function isTransportInWhitelist(config, transport) {
|
|
123
|
+
if (config.allowedTransports.length === 0)
|
|
124
|
+
return true;
|
|
125
|
+
const upperTransport = transport.toUpperCase();
|
|
126
|
+
for (const allowed of config.allowedTransports) {
|
|
127
|
+
const upperAllowed = allowed.toUpperCase();
|
|
128
|
+
if (upperAllowed === upperTransport)
|
|
129
|
+
return true;
|
|
130
|
+
if (upperAllowed.endsWith('*')) {
|
|
131
|
+
const prefix = upperAllowed.slice(0, -1);
|
|
132
|
+
if (upperTransport.startsWith(prefix))
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
/** Check if operations on a given transport are allowed */
|
|
139
|
+
export function isTransportAllowed(config, transport) {
|
|
140
|
+
if (!config.enableTransports)
|
|
141
|
+
return false;
|
|
142
|
+
if (config.allowedTransports.length === 0)
|
|
143
|
+
return true;
|
|
144
|
+
return isTransportInWhitelist(config, transport);
|
|
145
|
+
}
|
|
146
|
+
/** Check if transport write operations are allowed */
|
|
147
|
+
export function isTransportWriteAllowed(config) {
|
|
148
|
+
if (!config.enableTransports)
|
|
149
|
+
return false;
|
|
150
|
+
return !config.transportReadOnly;
|
|
151
|
+
}
|
|
152
|
+
/** Check transport operation and throw AdtSafetyError if blocked */
|
|
153
|
+
export function checkTransport(config, transport, opName, isWrite) {
|
|
154
|
+
// For read operations, allow if enableTransports OR allowTransportableEdits
|
|
155
|
+
if (!isWrite && (config.enableTransports || config.allowTransportableEdits)) {
|
|
156
|
+
if (transport && transport !== '*' && config.allowedTransports.length > 0) {
|
|
157
|
+
if (!isTransportInWhitelist(config, transport)) {
|
|
158
|
+
throw new AdtSafetyError(`Operation '${opName}' on transport '${transport}' is blocked by safety configuration (allowed: ${JSON.stringify(config.allowedTransports)})`);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
// For write operations, require enableTransports
|
|
164
|
+
if (!config.enableTransports) {
|
|
165
|
+
if (config.allowTransportableEdits && isWrite) {
|
|
166
|
+
throw new AdtSafetyError(`Transport write operation '${opName}' requires --enable-transports flag (--allow-transportable-edits only enables read operations)`);
|
|
167
|
+
}
|
|
168
|
+
throw new AdtSafetyError(`Transport operation '${opName}' is blocked: transports not enabled (use --enable-transports or SAP_ENABLE_TRANSPORTS=true)`);
|
|
169
|
+
}
|
|
170
|
+
// Check write permissions
|
|
171
|
+
if (isWrite && config.transportReadOnly) {
|
|
172
|
+
throw new AdtSafetyError(`Transport write operation '${opName}' is blocked: transport read-only mode enabled`);
|
|
173
|
+
}
|
|
174
|
+
// Check transport whitelist
|
|
175
|
+
if (transport && transport !== '*' && config.allowedTransports.length > 0) {
|
|
176
|
+
if (!isTransportAllowed(config, transport)) {
|
|
177
|
+
throw new AdtSafetyError(`Operation '${opName}' on transport '${transport}' is blocked by safety configuration (allowed: ${JSON.stringify(config.allowedTransports)})`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/** Check if editing a transportable object is allowed */
|
|
182
|
+
export function checkTransportableEdit(config, transport, opName) {
|
|
183
|
+
if (!transport)
|
|
184
|
+
return; // No transport = local object, always allowed
|
|
185
|
+
if (!config.allowTransportableEdits) {
|
|
186
|
+
throw new AdtSafetyError(`Operation '${opName}' with transport '${transport}' is blocked: editing transportable objects is disabled.\n` +
|
|
187
|
+
'Objects in transportable packages require explicit opt-in.\n' +
|
|
188
|
+
'Use --allow-transportable-edits or SAP_ALLOW_TRANSPORTABLE_EDITS=true to enable.\n' +
|
|
189
|
+
'WARNING: This allows modifications to non-local objects that may affect production systems.');
|
|
190
|
+
}
|
|
191
|
+
// If transportable edits are allowed, also check transport whitelist
|
|
192
|
+
if (config.allowedTransports.length > 0 && !isTransportInWhitelist(config, transport)) {
|
|
193
|
+
throw new AdtSafetyError(`Operation '${opName}' with transport '${transport}' is blocked by safety configuration (allowed transports: ${JSON.stringify(config.allowedTransports)})`);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
/** Human-readable description of the safety configuration */
|
|
197
|
+
export function describeSafety(config) {
|
|
198
|
+
const parts = [];
|
|
199
|
+
if (config.readOnly)
|
|
200
|
+
parts.push('READ-ONLY');
|
|
201
|
+
if (config.blockFreeSQL)
|
|
202
|
+
parts.push('NO-FREE-SQL');
|
|
203
|
+
if (config.dryRun)
|
|
204
|
+
parts.push('DRY-RUN');
|
|
205
|
+
if (config.allowedOps)
|
|
206
|
+
parts.push(`AllowedOps=${config.allowedOps}`);
|
|
207
|
+
if (config.disallowedOps)
|
|
208
|
+
parts.push(`DisallowedOps=${config.disallowedOps}`);
|
|
209
|
+
if (config.allowedPackages.length > 0)
|
|
210
|
+
parts.push(`AllowedPackages=[${config.allowedPackages.join(',')}]`);
|
|
211
|
+
if (config.enableTransports) {
|
|
212
|
+
parts.push('TRANSPORTS-ENABLED');
|
|
213
|
+
if (config.transportReadOnly)
|
|
214
|
+
parts.push('TRANSPORT-READ-ONLY');
|
|
215
|
+
if (config.allowedTransports.length > 0)
|
|
216
|
+
parts.push(`AllowedTransports=[${config.allowedTransports.join(',')}]`);
|
|
217
|
+
}
|
|
218
|
+
if (config.allowTransportableEdits)
|
|
219
|
+
parts.push('TRANSPORTABLE-EDITS-ALLOWED');
|
|
220
|
+
return parts.length === 0 ? 'UNRESTRICTED' : parts.join(', ');
|
|
221
|
+
}
|
|
222
|
+
//# sourceMappingURL=safety.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safety.js","sourceRoot":"","sources":["../../ts-src/adt/safety.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CTS Transport management for SAP ADT.
|
|
3
|
+
*
|
|
4
|
+
* Transport operations require explicit opt-in via enableTransports flag.
|
|
5
|
+
* Safety checks are applied at every entry point.
|
|
6
|
+
*/
|
|
7
|
+
import type { AdtHttpClient } from './http.js';
|
|
8
|
+
import { type SafetyConfig } from './safety.js';
|
|
9
|
+
import type { TransportRequest } from './types.js';
|
|
10
|
+
/** List transport requests for a user */
|
|
11
|
+
export declare function listTransports(http: AdtHttpClient, safety: SafetyConfig, user?: string): Promise<TransportRequest[]>;
|
|
12
|
+
/** Get details of a specific transport request */
|
|
13
|
+
export declare function getTransport(http: AdtHttpClient, safety: SafetyConfig, transportId: string): Promise<TransportRequest | null>;
|
|
14
|
+
/** Create a new transport request */
|
|
15
|
+
export declare function createTransport(http: AdtHttpClient, safety: SafetyConfig, description: string, targetPackage?: string): Promise<string>;
|
|
16
|
+
/** Release a transport request */
|
|
17
|
+
export declare function releaseTransport(http: AdtHttpClient, safety: SafetyConfig, transportId: string): Promise<void>;
|
|
18
|
+
//# sourceMappingURL=transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../ts-src/adt/transport.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,yCAAyC;AACzC,wBAAsB,cAAc,CAClC,IAAI,EAAE,aAAa,EACnB,MAAM,EAAE,YAAY,EACpB,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAU7B;AAED,kDAAkD;AAClD,wBAAsB,YAAY,CAChC,IAAI,EAAE,aAAa,EACnB,MAAM,EAAE,YAAY,EACpB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CASlC;AAED,qCAAqC;AACrC,wBAAsB,eAAe,CACnC,IAAI,EAAE,aAAa,EACnB,MAAM,EAAE,YAAY,EACpB,WAAW,EAAE,MAAM,EACnB,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,MAAM,CAAC,CAejB;AAED,kCAAkC;AAClC,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIpH"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CTS Transport management for SAP ADT.
|
|
3
|
+
*
|
|
4
|
+
* Transport operations require explicit opt-in via enableTransports flag.
|
|
5
|
+
* Safety checks are applied at every entry point.
|
|
6
|
+
*/
|
|
7
|
+
import { checkTransport } from './safety.js';
|
|
8
|
+
/** List transport requests for a user */
|
|
9
|
+
export async function listTransports(http, safety, user) {
|
|
10
|
+
checkTransport(safety, '', 'ListTransports', false);
|
|
11
|
+
let url = '/sap/bc/adt/cts/transportrequests';
|
|
12
|
+
if (user && user !== '*') {
|
|
13
|
+
url += `?user=${encodeURIComponent(user)}`;
|
|
14
|
+
}
|
|
15
|
+
const resp = await http.get(url, { Accept: 'application/xml' });
|
|
16
|
+
return parseTransportList(resp.body);
|
|
17
|
+
}
|
|
18
|
+
/** Get details of a specific transport request */
|
|
19
|
+
export async function getTransport(http, safety, transportId) {
|
|
20
|
+
checkTransport(safety, transportId, 'GetTransport', false);
|
|
21
|
+
const resp = await http.get(`/sap/bc/adt/cts/transportrequests/${encodeURIComponent(transportId)}`, {
|
|
22
|
+
Accept: 'application/xml',
|
|
23
|
+
});
|
|
24
|
+
const transports = parseTransportList(resp.body);
|
|
25
|
+
return transports[0] ?? null;
|
|
26
|
+
}
|
|
27
|
+
/** Create a new transport request */
|
|
28
|
+
export async function createTransport(http, safety, description, targetPackage) {
|
|
29
|
+
checkTransport(safety, '', 'CreateTransport', true);
|
|
30
|
+
const body = `<?xml version="1.0" encoding="UTF-8"?>
|
|
31
|
+
<tm:root xmlns:tm="http://www.sap.com/cts/transports">
|
|
32
|
+
<tm:request tm:desc="${escapeXml(description)}" tm:type="K"${targetPackage ? ` tm:target="${escapeXml(targetPackage)}"` : ''}/>
|
|
33
|
+
</tm:root>`;
|
|
34
|
+
const resp = await http.post('/sap/bc/adt/cts/transportrequests', body, 'application/xml', {
|
|
35
|
+
Accept: 'application/xml',
|
|
36
|
+
});
|
|
37
|
+
// Extract transport number from response
|
|
38
|
+
const match = resp.body.match(/tm:number="([^"]*)"/);
|
|
39
|
+
return match?.[1] ?? '';
|
|
40
|
+
}
|
|
41
|
+
/** Release a transport request */
|
|
42
|
+
export async function releaseTransport(http, safety, transportId) {
|
|
43
|
+
checkTransport(safety, transportId, 'ReleaseTransport', true);
|
|
44
|
+
await http.post(`/sap/bc/adt/cts/transportrequests/${encodeURIComponent(transportId)}/newreleasejobs`);
|
|
45
|
+
}
|
|
46
|
+
// ─── Parsers ────────────────────────────────────────────────────────
|
|
47
|
+
function parseTransportList(xml) {
|
|
48
|
+
const transports = [];
|
|
49
|
+
const trRegex = /<tm:request[^>]*tm:number="([^"]*)"[^>]*tm:owner="([^"]*)"[^>]*tm:desc="([^"]*)"[^>]*tm:status="([^"]*)"[^>]*tm:type="([^"]*)"/g;
|
|
50
|
+
let match;
|
|
51
|
+
while ((match = trRegex.exec(xml)) !== null) {
|
|
52
|
+
transports.push({
|
|
53
|
+
id: match[1],
|
|
54
|
+
description: match[3],
|
|
55
|
+
owner: match[2],
|
|
56
|
+
status: match[4],
|
|
57
|
+
type: match[5],
|
|
58
|
+
tasks: [],
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
return transports;
|
|
62
|
+
}
|
|
63
|
+
function escapeXml(str) {
|
|
64
|
+
return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../../ts-src/adt/transport.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ADT XML response types.
|
|
3
|
+
*
|
|
4
|
+
* SAP ADT returns XML for most responses. These types represent
|
|
5
|
+
* the parsed structures we care about. Not exhaustive — we add
|
|
6
|
+
* types as we port each operation.
|
|
7
|
+
*/
|
|
8
|
+
/** Search result from /sap/bc/adt/repository/informationsystem/search */
|
|
9
|
+
export interface AdtSearchResult {
|
|
10
|
+
objectType: string;
|
|
11
|
+
objectName: string;
|
|
12
|
+
description: string;
|
|
13
|
+
packageName: string;
|
|
14
|
+
uri: string;
|
|
15
|
+
}
|
|
16
|
+
/** Object structure node */
|
|
17
|
+
export interface AdtObjectNode {
|
|
18
|
+
type: string;
|
|
19
|
+
name: string;
|
|
20
|
+
uri: string;
|
|
21
|
+
children?: AdtObjectNode[];
|
|
22
|
+
}
|
|
23
|
+
/** Feature probe result */
|
|
24
|
+
export interface FeatureStatus {
|
|
25
|
+
id: string;
|
|
26
|
+
available: boolean;
|
|
27
|
+
mode: string;
|
|
28
|
+
message?: string;
|
|
29
|
+
probedAt?: string;
|
|
30
|
+
}
|
|
31
|
+
/** Resolved features after probing */
|
|
32
|
+
export interface ResolvedFeatures {
|
|
33
|
+
hana: FeatureStatus;
|
|
34
|
+
abapGit: FeatureStatus;
|
|
35
|
+
rap: FeatureStatus;
|
|
36
|
+
amdp: FeatureStatus;
|
|
37
|
+
ui5: FeatureStatus;
|
|
38
|
+
transport: FeatureStatus;
|
|
39
|
+
/** Detected SAP_BASIS release (e.g. "750", "757"). Populated during probe. */
|
|
40
|
+
abapRelease?: string;
|
|
41
|
+
}
|
|
42
|
+
/** System info from /sap/bc/adt/core/discovery */
|
|
43
|
+
export interface SystemInfo {
|
|
44
|
+
systemId: string;
|
|
45
|
+
release: string;
|
|
46
|
+
type: string;
|
|
47
|
+
}
|
|
48
|
+
/** Unit test result */
|
|
49
|
+
export interface UnitTestResult {
|
|
50
|
+
program: string;
|
|
51
|
+
testClass: string;
|
|
52
|
+
testMethod: string;
|
|
53
|
+
status: 'passed' | 'failed' | 'skipped';
|
|
54
|
+
message?: string;
|
|
55
|
+
duration?: number;
|
|
56
|
+
}
|
|
57
|
+
/** Syntax check result */
|
|
58
|
+
export interface SyntaxCheckResult {
|
|
59
|
+
hasErrors: boolean;
|
|
60
|
+
messages: SyntaxMessage[];
|
|
61
|
+
}
|
|
62
|
+
export interface SyntaxMessage {
|
|
63
|
+
severity: 'error' | 'warning' | 'info';
|
|
64
|
+
text: string;
|
|
65
|
+
line: number;
|
|
66
|
+
column: number;
|
|
67
|
+
}
|
|
68
|
+
/** Transport request */
|
|
69
|
+
export interface TransportRequest {
|
|
70
|
+
id: string;
|
|
71
|
+
description: string;
|
|
72
|
+
owner: string;
|
|
73
|
+
status: string;
|
|
74
|
+
type: string;
|
|
75
|
+
tasks: TransportTask[];
|
|
76
|
+
}
|
|
77
|
+
export interface TransportTask {
|
|
78
|
+
id: string;
|
|
79
|
+
description: string;
|
|
80
|
+
owner: string;
|
|
81
|
+
status: string;
|
|
82
|
+
}
|
|
83
|
+
/** Table structure */
|
|
84
|
+
export interface TableField {
|
|
85
|
+
name: string;
|
|
86
|
+
type: string;
|
|
87
|
+
length: number;
|
|
88
|
+
description: string;
|
|
89
|
+
isKey: boolean;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../ts-src/adt/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,yEAAyE;AACzE,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,4BAA4B;AAC5B,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAC;CAC5B;AAED,2BAA2B;AAC3B,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,sCAAsC;AACtC,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,aAAa,CAAC;IACpB,OAAO,EAAE,aAAa,CAAC;IACvB,GAAG,EAAE,aAAa,CAAC;IACnB,IAAI,EAAE,aAAa,CAAC;IACpB,GAAG,EAAE,aAAa,CAAC;IACnB,SAAS,EAAE,aAAa,CAAC;IACzB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,kDAAkD;AAClD,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,uBAAuB;AACvB,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,0BAA0B;AAC1B,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAwB;AACxB,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,aAAa,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,sBAAsB;AACtB,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,OAAO,CAAC;CAChB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../ts-src/adt/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* XML parser for SAP ADT responses.
|
|
3
|
+
*
|
|
4
|
+
* SAP ADT returns XML with multiple namespace conventions:
|
|
5
|
+
* - adtcore: (http://www.sap.com/adt/core) — object references, search results
|
|
6
|
+
* - asx: (http://www.sap.com/abapxml) — table contents, package structure
|
|
7
|
+
* - atom: (http://www.w3.org/2005/Atom) — feed entries
|
|
8
|
+
*
|
|
9
|
+
* We use fast-xml-parser v5 with removeNSPrefix to strip namespaces,
|
|
10
|
+
* since we know the expected structure and don't need namespace dispatch.
|
|
11
|
+
*
|
|
12
|
+
* Key design choice: parse to plain objects, then map to our types.
|
|
13
|
+
* This decouples the XML format from our internal types, making it
|
|
14
|
+
* easier to handle SAP's inconsistent XML across different endpoints.
|
|
15
|
+
*/
|
|
16
|
+
import type { AdtSearchResult } from './types.js';
|
|
17
|
+
/** Parse raw XML string to a JS object */
|
|
18
|
+
export declare function parseXml(xml: string): Record<string, unknown>;
|
|
19
|
+
/**
|
|
20
|
+
* Parse ADT search results XML.
|
|
21
|
+
*
|
|
22
|
+
* Expected format:
|
|
23
|
+
* <adtcore:objectReferences>
|
|
24
|
+
* <adtcore:objectReference uri="..." type="PROG/P" name="ZTEST" packageName="$TMP" description="..."/>
|
|
25
|
+
* </adtcore:objectReferences>
|
|
26
|
+
*/
|
|
27
|
+
export declare function parseSearchResults(xml: string): AdtSearchResult[];
|
|
28
|
+
/**
|
|
29
|
+
* Parse ADT package contents (nodestructure response).
|
|
30
|
+
*
|
|
31
|
+
* Expected format:
|
|
32
|
+
* <asx:abap><asx:values><DATA><TREE_CONTENT>
|
|
33
|
+
* <SEU_ADT_REPOSITORY_OBJ_NODE>
|
|
34
|
+
* <OBJECT_TYPE>PROG/P</OBJECT_TYPE>
|
|
35
|
+
* <OBJECT_NAME>ZTEST</OBJECT_NAME>
|
|
36
|
+
* <DESCRIPTION>...</DESCRIPTION>
|
|
37
|
+
* </SEU_ADT_REPOSITORY_OBJ_NODE>
|
|
38
|
+
* </TREE_CONTENT></DATA></asx:values></asx:abap>
|
|
39
|
+
*/
|
|
40
|
+
export declare function parsePackageContents(xml: string): Array<{
|
|
41
|
+
type: string;
|
|
42
|
+
name: string;
|
|
43
|
+
description: string;
|
|
44
|
+
uri: string;
|
|
45
|
+
}>;
|
|
46
|
+
/**
|
|
47
|
+
* Parse table contents (datapreview response).
|
|
48
|
+
*
|
|
49
|
+
* SAP ADT returns two possible formats for data preview:
|
|
50
|
+
*
|
|
51
|
+
* Format 1 (older/asx): COLUMNS/COLUMN/METADATA + DATASET/DATA
|
|
52
|
+
* Format 2 (newer/dataPreview namespace): columns/metadata + dataSet/data
|
|
53
|
+
*
|
|
54
|
+
* After namespace stripping, both converge but with different casing.
|
|
55
|
+
* We try both patterns with fallback.
|
|
56
|
+
*/
|
|
57
|
+
export declare function parseTableContents(xml: string): {
|
|
58
|
+
columns: string[];
|
|
59
|
+
rows: Record<string, string>[];
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Parse installed components response.
|
|
63
|
+
*
|
|
64
|
+
* SAP returns an Atom feed for /sap/bc/adt/system/components:
|
|
65
|
+
* <atom:feed>
|
|
66
|
+
* <atom:entry>
|
|
67
|
+
* <atom:id>SAP_BASIS</atom:id>
|
|
68
|
+
* <atom:title>753;SAPKB75308;0008;SAP Basis Component</atom:title>
|
|
69
|
+
* </atom:entry>
|
|
70
|
+
* </atom:feed>
|
|
71
|
+
*
|
|
72
|
+
* The title field is semicolon-separated: release;sp_name;sp_level;description
|
|
73
|
+
*/
|
|
74
|
+
export declare function parseInstalledComponents(xml: string): Array<{
|
|
75
|
+
name: string;
|
|
76
|
+
release: string;
|
|
77
|
+
description: string;
|
|
78
|
+
}>;
|
|
79
|
+
/**
|
|
80
|
+
* Parse function group structure.
|
|
81
|
+
*
|
|
82
|
+
* <group name="ZGROUP" type="FUGR/F">
|
|
83
|
+
* <functionModule name="ZFUNC" type="FUNC/FM"/>
|
|
84
|
+
* </group>
|
|
85
|
+
*/
|
|
86
|
+
export declare function parseFunctionGroup(xml: string): {
|
|
87
|
+
name: string;
|
|
88
|
+
functions: string[];
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* Parse ADT system discovery XML into structured info.
|
|
92
|
+
*
|
|
93
|
+
* The discovery response is an Atom service document that lists available
|
|
94
|
+
* ADT workspaces/collections. We extract collection titles and hrefs
|
|
95
|
+
* to determine what capabilities the SAP system has.
|
|
96
|
+
*
|
|
97
|
+
* The authenticated username is passed in from the client config since
|
|
98
|
+
* the discovery XML doesn't directly contain "you are logged in as X".
|
|
99
|
+
*/
|
|
100
|
+
export declare function parseSystemInfo(xml: string, username: string): {
|
|
101
|
+
user: string;
|
|
102
|
+
collections: Array<{
|
|
103
|
+
title: string;
|
|
104
|
+
href: string;
|
|
105
|
+
}>;
|
|
106
|
+
};
|
|
107
|
+
/** Recursively find an array by key name, anywhere in the object tree */
|
|
108
|
+
export declare function findDeepNodes(obj: unknown, key: string): Array<Record<string, unknown>>;
|
|
109
|
+
//# sourceMappingURL=xml-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xml-parser.d.ts","sourceRoot":"","sources":["../../ts-src/adt/xml-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AA8BlD,0CAA0C;AAC1C,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAE7D;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,EAAE,CAUjE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,GACV,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAczE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAA;CAAE,CA6CrG;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,CAgBnH;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,EAAE,CAAA;CAAE,CAQrF;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,GACf;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CA0BvE;AAcD,yEAAyE;AACzE,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAoBvF"}
|