catalyst-relay 0.6.2 → 0.6.4
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/dist/index.d.mts +15 -7
- package/dist/index.d.ts +15 -7
- package/dist/index.js +87 -34
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +87 -34
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -599,17 +599,25 @@ interface SearchOptions {
|
|
|
599
599
|
type ClassIncludeType = 'definitions' | 'implementations' | 'macros' | 'testclasses';
|
|
600
600
|
|
|
601
601
|
/**
|
|
602
|
-
* Create Transport —
|
|
602
|
+
* Create Transport — create a new transport request.
|
|
603
|
+
*
|
|
604
|
+
* Uses the transport-organizer endpoint, which allows choosing the request
|
|
605
|
+
* type (Workbench vs Customizing). The target is taken from the caller, or
|
|
606
|
+
* resolved from the target value-help when unambiguous.
|
|
603
607
|
*/
|
|
604
608
|
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
609
|
+
declare const TRANSPORT_TYPE_CODES: {
|
|
610
|
+
readonly workbench: "K";
|
|
611
|
+
readonly customizing: "W";
|
|
612
|
+
};
|
|
613
|
+
type TransportType = keyof typeof TRANSPORT_TYPE_CODES;
|
|
608
614
|
interface TransportConfig {
|
|
609
|
-
/** Package name (DEVCLASS) */
|
|
610
|
-
package: string;
|
|
611
615
|
/** Transport description/text */
|
|
612
616
|
description: string;
|
|
617
|
+
/** Request type — 'workbench' (default) or 'customizing' */
|
|
618
|
+
type?: TransportType;
|
|
619
|
+
/** Transport target. If omitted, resolved from the value-help (fails when ambiguous). */
|
|
620
|
+
target?: string;
|
|
613
621
|
}
|
|
614
622
|
|
|
615
623
|
/**
|
|
@@ -792,4 +800,4 @@ declare function activateLogging(): void;
|
|
|
792
800
|
*/
|
|
793
801
|
declare function deactivateLogging(): void;
|
|
794
802
|
|
|
795
|
-
export { type ADTClient, type ActivationMessage, type ActivationReference, type ActivationResult, type Aggregation, type ApiResponse, type AsyncResult, type AuthConfig, type AuthType, type BasicAuthConfig, type BasicFilter, BehaviorImplementationType, type BetweenFilter, type CheckResult, type ClassIncludeType, type ClientConfig, type ColumnInfo, type CreateServiceBindingOptions, type DataFrame, type DataPreviewQuery, type DeleteResult, type Dependency, type DiffHunk, type DiffResult, type DistinctResult, type ErrorCode, type ErrorResponse, type ExportableSessionState, type ExternalReference, ExternalReferencesError, type FolderNode, type GetPackagesOptions, type InactiveEntry, type InactiveObject, type InactiveRef, type InactiveTransport, type ListFilter, type ModifiedDiffHunk, type ObjectConfig, type ObjectContent, type ObjectMetadata, type ObjectNode, type ObjectRef, type ObjectWithContent, type Package, type PackageNode, type Parameter, type PreviewSQL, type QueryFilter, type Result, type SamlAuthConfig, type SearchOptions, type SearchResult, type ServiceBindingResult, type ServiceBindingType, type ServiceBindingVersion, type Session, type SimpleDiffHunk, type Sorting, type SsoAuthConfig, type SuccessResponse, type TaskContents, type Transport, type TransportConfig, type TransportObject, type TreeQuery, type TreeResponse, type UpsertResult, activateLogging, buildSQLQuery, createClient, deactivateLogging, err, ok };
|
|
803
|
+
export { type ADTClient, type ActivationMessage, type ActivationReference, type ActivationResult, type Aggregation, type ApiResponse, type AsyncResult, type AuthConfig, type AuthType, type BasicAuthConfig, type BasicFilter, BehaviorImplementationType, type BetweenFilter, type CheckResult, type ClassIncludeType, type ClientConfig, type ColumnInfo, type CreateServiceBindingOptions, type DataFrame, type DataPreviewQuery, type DeleteResult, type Dependency, type DiffHunk, type DiffResult, type DistinctResult, type ErrorCode, type ErrorResponse, type ExportableSessionState, type ExternalReference, ExternalReferencesError, type FolderNode, type GetPackagesOptions, type InactiveEntry, type InactiveObject, type InactiveRef, type InactiveTransport, type ListFilter, type ModifiedDiffHunk, type ObjectConfig, type ObjectContent, type ObjectMetadata, type ObjectNode, type ObjectRef, type ObjectWithContent, type Package, type PackageNode, type Parameter, type PreviewSQL, type QueryFilter, type Result, type SamlAuthConfig, type SearchOptions, type SearchResult, type ServiceBindingResult, type ServiceBindingType, type ServiceBindingVersion, type Session, type SimpleDiffHunk, type Sorting, type SsoAuthConfig, type SuccessResponse, type TaskContents, type Transport, type TransportConfig, type TransportObject, type TransportType, type TreeQuery, type TreeResponse, type UpsertResult, activateLogging, buildSQLQuery, createClient, deactivateLogging, err, ok };
|
package/dist/index.d.ts
CHANGED
|
@@ -599,17 +599,25 @@ interface SearchOptions {
|
|
|
599
599
|
type ClassIncludeType = 'definitions' | 'implementations' | 'macros' | 'testclasses';
|
|
600
600
|
|
|
601
601
|
/**
|
|
602
|
-
* Create Transport —
|
|
602
|
+
* Create Transport — create a new transport request.
|
|
603
|
+
*
|
|
604
|
+
* Uses the transport-organizer endpoint, which allows choosing the request
|
|
605
|
+
* type (Workbench vs Customizing). The target is taken from the caller, or
|
|
606
|
+
* resolved from the target value-help when unambiguous.
|
|
603
607
|
*/
|
|
604
608
|
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
609
|
+
declare const TRANSPORT_TYPE_CODES: {
|
|
610
|
+
readonly workbench: "K";
|
|
611
|
+
readonly customizing: "W";
|
|
612
|
+
};
|
|
613
|
+
type TransportType = keyof typeof TRANSPORT_TYPE_CODES;
|
|
608
614
|
interface TransportConfig {
|
|
609
|
-
/** Package name (DEVCLASS) */
|
|
610
|
-
package: string;
|
|
611
615
|
/** Transport description/text */
|
|
612
616
|
description: string;
|
|
617
|
+
/** Request type — 'workbench' (default) or 'customizing' */
|
|
618
|
+
type?: TransportType;
|
|
619
|
+
/** Transport target. If omitted, resolved from the value-help (fails when ambiguous). */
|
|
620
|
+
target?: string;
|
|
613
621
|
}
|
|
614
622
|
|
|
615
623
|
/**
|
|
@@ -792,4 +800,4 @@ declare function activateLogging(): void;
|
|
|
792
800
|
*/
|
|
793
801
|
declare function deactivateLogging(): void;
|
|
794
802
|
|
|
795
|
-
export { type ADTClient, type ActivationMessage, type ActivationReference, type ActivationResult, type Aggregation, type ApiResponse, type AsyncResult, type AuthConfig, type AuthType, type BasicAuthConfig, type BasicFilter, BehaviorImplementationType, type BetweenFilter, type CheckResult, type ClassIncludeType, type ClientConfig, type ColumnInfo, type CreateServiceBindingOptions, type DataFrame, type DataPreviewQuery, type DeleteResult, type Dependency, type DiffHunk, type DiffResult, type DistinctResult, type ErrorCode, type ErrorResponse, type ExportableSessionState, type ExternalReference, ExternalReferencesError, type FolderNode, type GetPackagesOptions, type InactiveEntry, type InactiveObject, type InactiveRef, type InactiveTransport, type ListFilter, type ModifiedDiffHunk, type ObjectConfig, type ObjectContent, type ObjectMetadata, type ObjectNode, type ObjectRef, type ObjectWithContent, type Package, type PackageNode, type Parameter, type PreviewSQL, type QueryFilter, type Result, type SamlAuthConfig, type SearchOptions, type SearchResult, type ServiceBindingResult, type ServiceBindingType, type ServiceBindingVersion, type Session, type SimpleDiffHunk, type Sorting, type SsoAuthConfig, type SuccessResponse, type TaskContents, type Transport, type TransportConfig, type TransportObject, type TreeQuery, type TreeResponse, type UpsertResult, activateLogging, buildSQLQuery, createClient, deactivateLogging, err, ok };
|
|
803
|
+
export { type ADTClient, type ActivationMessage, type ActivationReference, type ActivationResult, type Aggregation, type ApiResponse, type AsyncResult, type AuthConfig, type AuthType, type BasicAuthConfig, type BasicFilter, BehaviorImplementationType, type BetweenFilter, type CheckResult, type ClassIncludeType, type ClientConfig, type ColumnInfo, type CreateServiceBindingOptions, type DataFrame, type DataPreviewQuery, type DeleteResult, type Dependency, type DiffHunk, type DiffResult, type DistinctResult, type ErrorCode, type ErrorResponse, type ExportableSessionState, type ExternalReference, ExternalReferencesError, type FolderNode, type GetPackagesOptions, type InactiveEntry, type InactiveObject, type InactiveRef, type InactiveTransport, type ListFilter, type ModifiedDiffHunk, type ObjectConfig, type ObjectContent, type ObjectMetadata, type ObjectNode, type ObjectRef, type ObjectWithContent, type Package, type PackageNode, type Parameter, type PreviewSQL, type QueryFilter, type Result, type SamlAuthConfig, type SearchOptions, type SearchResult, type ServiceBindingResult, type ServiceBindingType, type ServiceBindingVersion, type Session, type SimpleDiffHunk, type Sorting, type SsoAuthConfig, type SuccessResponse, type TaskContents, type Transport, type TransportConfig, type TransportObject, type TransportType, type TreeQuery, type TreeResponse, type UpsertResult, activateLogging, buildSQLQuery, createClient, deactivateLogging, err, ok };
|
package/dist/index.js
CHANGED
|
@@ -1061,22 +1061,6 @@ function escapeXml(str) {
|
|
|
1061
1061
|
}
|
|
1062
1062
|
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
1063
1063
|
}
|
|
1064
|
-
function dictToAbapXml(data, root = "DATA") {
|
|
1065
|
-
const innerElements = Object.entries(data).map(([key, value]) => {
|
|
1066
|
-
if (value) {
|
|
1067
|
-
return `<${key}>${escapeXml(value)}</${key}>`;
|
|
1068
|
-
}
|
|
1069
|
-
return `<${key}/>`;
|
|
1070
|
-
}).join("\n ");
|
|
1071
|
-
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
1072
|
-
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
|
|
1073
|
-
<asx:values>
|
|
1074
|
-
<${root}>
|
|
1075
|
-
${innerElements}
|
|
1076
|
-
</${root}>
|
|
1077
|
-
</asx:values>
|
|
1078
|
-
</asx:abap>`;
|
|
1079
|
-
}
|
|
1080
1064
|
|
|
1081
1065
|
// src/core/utils/csrf.ts
|
|
1082
1066
|
var FETCH_CSRF_TOKEN = "fetch";
|
|
@@ -1950,6 +1934,7 @@ async function updateClassInclude(client, className, includeType, source, lockHa
|
|
|
1950
1934
|
// src/core/adt/craud/activation.ts
|
|
1951
1935
|
var MAX_POLL_ATTEMPTS = 30;
|
|
1952
1936
|
var POLL_RETRY_DELAY_MS = 1e3;
|
|
1937
|
+
var LONG_POLL_TIMEOUT_MS = 36e5;
|
|
1953
1938
|
var RUN_ID_REGEX = /\/activation\/runs\/([^?/]+)/;
|
|
1954
1939
|
var BACKGROUND_RUN_MEDIA_TYPE = "application/vnd.sap.adt.backgroundrun.v1+xml";
|
|
1955
1940
|
async function activateObjects(client, objects) {
|
|
@@ -2012,7 +1997,8 @@ async function activateByReferences(client, references) {
|
|
|
2012
1997
|
method: "GET",
|
|
2013
1998
|
path: `/sap/bc/adt/activation/runs/${runId}`,
|
|
2014
1999
|
params: { "withLongPolling": "true" },
|
|
2015
|
-
headers: { "Accept": BACKGROUND_RUN_MEDIA_TYPE }
|
|
2000
|
+
headers: { "Accept": BACKGROUND_RUN_MEDIA_TYPE },
|
|
2001
|
+
timeout: LONG_POLL_TIMEOUT_MS
|
|
2016
2002
|
});
|
|
2017
2003
|
if (pollErr) return err(pollErr);
|
|
2018
2004
|
debug(`Activation poll attempt ${pollAttempt} status: ${pollRes.status}`);
|
|
@@ -3098,35 +3084,102 @@ function parseSearchResults(xml) {
|
|
|
3098
3084
|
return ok(results);
|
|
3099
3085
|
}
|
|
3100
3086
|
|
|
3101
|
-
// src/core/adt/transports/
|
|
3102
|
-
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3087
|
+
// src/core/adt/transports/getTransportTargets.ts
|
|
3088
|
+
var TARGET_VALUEHELP_PATH = "/sap/bc/adt/cts/transportrequests/valuehelp/target?name=*";
|
|
3089
|
+
var NAMEDITEM_CONTENT_TYPE = "application/vnd.sap.adt.nameditems.v1+xml";
|
|
3090
|
+
var NAMEDITEM_NS = "http://www.sap.com/adt/nameditem";
|
|
3091
|
+
async function getTransportTargets(client) {
|
|
3092
|
+
const [response, requestErr] = await client.request({
|
|
3093
|
+
method: "GET",
|
|
3094
|
+
path: TARGET_VALUEHELP_PATH,
|
|
3095
|
+
headers: { Accept: NAMEDITEM_CONTENT_TYPE }
|
|
3108
3096
|
});
|
|
3097
|
+
if (requestErr) return err(requestErr);
|
|
3098
|
+
if (!response.ok) {
|
|
3099
|
+
const text2 = await response.text();
|
|
3100
|
+
return err(new Error(`Failed to fetch transport targets: ${extractError(text2)}`));
|
|
3101
|
+
}
|
|
3102
|
+
const text = await response.text();
|
|
3103
|
+
const [targets, parseErr] = extractTargets(text);
|
|
3104
|
+
if (parseErr) return err(parseErr);
|
|
3105
|
+
return ok(targets);
|
|
3106
|
+
}
|
|
3107
|
+
function extractTargets(xml) {
|
|
3108
|
+
const [doc, parseErr] = safeParseXml(xml);
|
|
3109
|
+
if (parseErr) return err(parseErr);
|
|
3110
|
+
const targets = [];
|
|
3111
|
+
const items = doc.getElementsByTagNameNS(NAMEDITEM_NS, "namedItem");
|
|
3112
|
+
for (let i = 0; i < items.length; i++) {
|
|
3113
|
+
const item = items[i];
|
|
3114
|
+
if (!item) continue;
|
|
3115
|
+
const name = item.getElementsByTagNameNS(NAMEDITEM_NS, "name")[0]?.textContent;
|
|
3116
|
+
if (!name || !name.trim()) continue;
|
|
3117
|
+
const description = item.getElementsByTagNameNS(NAMEDITEM_NS, "description")[0]?.textContent;
|
|
3118
|
+
targets.push({ name: name.trim(), description: (description ?? "").trim() });
|
|
3119
|
+
}
|
|
3120
|
+
return ok(targets);
|
|
3121
|
+
}
|
|
3122
|
+
|
|
3123
|
+
// src/core/adt/transports/createTransport.ts
|
|
3124
|
+
var TRANSPORTREQUESTS_PATH = "/sap/bc/adt/cts/transportrequests";
|
|
3125
|
+
var TM_CONTENT_TYPE = "application/vnd.sap.adt.transportorganizer.v1+xml";
|
|
3126
|
+
var TM_NS = "http://www.sap.com/cts/adt/tm";
|
|
3127
|
+
var TRANSPORT_TYPE_CODES = {
|
|
3128
|
+
workbench: "K",
|
|
3129
|
+
customizing: "W"
|
|
3130
|
+
};
|
|
3131
|
+
async function createTransport(client, config, owner) {
|
|
3132
|
+
const [target, targetErr] = await resolveTarget(client, config.target);
|
|
3133
|
+
if (targetErr) return err(targetErr);
|
|
3134
|
+
const typeCode = TRANSPORT_TYPE_CODES[config.type ?? "workbench"];
|
|
3135
|
+
const body = `<?xml version="1.0" encoding="UTF-8"?>
|
|
3136
|
+
<tm:root xmlns:tm="${TM_NS}" tm:useraction="newrequest">
|
|
3137
|
+
<tm:request tm:desc="${escapeXml(config.description)}" tm:type="${typeCode}" tm:target="${escapeXml(target)}" tm:cts_project="">
|
|
3138
|
+
<tm:task tm:owner="${escapeXml(owner)}"/>
|
|
3139
|
+
</tm:request>
|
|
3140
|
+
</tm:root>`;
|
|
3109
3141
|
const [response, requestErr] = await client.request({
|
|
3110
3142
|
method: "POST",
|
|
3111
|
-
path:
|
|
3143
|
+
path: TRANSPORTREQUESTS_PATH,
|
|
3112
3144
|
headers: {
|
|
3113
|
-
"Content-Type":
|
|
3114
|
-
"Accept":
|
|
3145
|
+
"Content-Type": TM_CONTENT_TYPE,
|
|
3146
|
+
"Accept": TM_CONTENT_TYPE
|
|
3115
3147
|
},
|
|
3116
3148
|
body
|
|
3117
3149
|
});
|
|
3118
3150
|
if (requestErr) return err(requestErr);
|
|
3119
3151
|
if (!response.ok) {
|
|
3120
3152
|
const text2 = await response.text();
|
|
3121
|
-
|
|
3122
|
-
return err(new Error(`Failed to create transport for ${config.package}: ${errorMsg}`));
|
|
3153
|
+
return err(new Error(`Failed to create transport: ${extractError(text2)}`));
|
|
3123
3154
|
}
|
|
3124
3155
|
const text = await response.text();
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3156
|
+
return extractTransportNumber(text);
|
|
3157
|
+
}
|
|
3158
|
+
async function resolveTarget(client, explicit) {
|
|
3159
|
+
if (explicit) return ok(explicit);
|
|
3160
|
+
const [targets, targetsErr] = await getTransportTargets(client);
|
|
3161
|
+
if (targetsErr) return err(targetsErr);
|
|
3162
|
+
if (targets.length === 0) {
|
|
3163
|
+
return err(new Error("No transport targets available; pass an explicit target."));
|
|
3164
|
+
}
|
|
3165
|
+
if (targets.length === 1) {
|
|
3166
|
+
return ok(targets[0].name);
|
|
3167
|
+
}
|
|
3168
|
+
const options = targets.map((t) => `${t.name} (${t.description})`).join(", ");
|
|
3169
|
+
return err(new Error(
|
|
3170
|
+
`Multiple transport targets available; pass an explicit target. Options: ${options}`
|
|
3171
|
+
));
|
|
3172
|
+
}
|
|
3173
|
+
function extractTransportNumber(xml) {
|
|
3174
|
+
const [doc, parseErr] = safeParseXml(xml);
|
|
3175
|
+
if (parseErr) return err(parseErr);
|
|
3176
|
+
const request4 = doc.getElementsByTagNameNS(TM_NS, "request")[0];
|
|
3177
|
+
if (!request4) return err(new Error("Failed to parse transport number from response"));
|
|
3178
|
+
const number = request4.getAttributeNS(TM_NS, "number") || request4.getAttribute("tm:number");
|
|
3179
|
+
if (!number || !number.trim()) {
|
|
3180
|
+
return err(new Error("Failed to parse transport number from response"));
|
|
3128
3181
|
}
|
|
3129
|
-
return ok(
|
|
3182
|
+
return ok(number.trim());
|
|
3130
3183
|
}
|
|
3131
3184
|
|
|
3132
3185
|
// src/core/adt/transports/parseTransportTasks.ts
|
|
@@ -3793,7 +3846,7 @@ async function whereUsed(state, requestor, object) {
|
|
|
3793
3846
|
// src/client/methods/transport/createTransport.ts
|
|
3794
3847
|
async function createTransport2(state, requestor, transportConfig) {
|
|
3795
3848
|
if (!state.session) return err(new Error("Not logged in"));
|
|
3796
|
-
return createTransport(requestor, transportConfig);
|
|
3849
|
+
return createTransport(requestor, transportConfig, state.session.username);
|
|
3797
3850
|
}
|
|
3798
3851
|
|
|
3799
3852
|
// src/client/methods/transport/deleteTransport.ts
|