arc-1 0.9.27 → 1.0.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/README.md +28 -11
- package/dist/adt/abapgit.d.ts +19 -6
- package/dist/adt/abapgit.d.ts.map +1 -1
- package/dist/adt/abapgit.js +141 -36
- package/dist/adt/abapgit.js.map +1 -1
- package/dist/adt/client.d.ts +21 -8
- package/dist/adt/client.d.ts.map +1 -1
- package/dist/adt/client.js +47 -7
- package/dist/adt/client.js.map +1 -1
- package/dist/adt/config.d.ts +15 -0
- package/dist/adt/config.d.ts.map +1 -1
- package/dist/adt/config.js.map +1 -1
- package/dist/adt/crud.d.ts +7 -2
- package/dist/adt/crud.d.ts.map +1 -1
- package/dist/adt/crud.js +12 -4
- package/dist/adt/crud.js.map +1 -1
- package/dist/adt/ddic-xml.d.ts +27 -17
- package/dist/adt/ddic-xml.d.ts.map +1 -1
- package/dist/adt/ddic-xml.js +45 -34
- package/dist/adt/ddic-xml.js.map +1 -1
- package/dist/adt/devtools.d.ts +13 -0
- package/dist/adt/devtools.d.ts.map +1 -1
- package/dist/adt/devtools.js +120 -50
- package/dist/adt/devtools.js.map +1 -1
- package/dist/adt/errors.d.ts +1 -1
- package/dist/adt/errors.d.ts.map +1 -1
- package/dist/adt/errors.js +18 -0
- package/dist/adt/errors.js.map +1 -1
- package/dist/adt/http.d.ts +17 -1
- package/dist/adt/http.d.ts.map +1 -1
- package/dist/adt/http.js +102 -19
- package/dist/adt/http.js.map +1 -1
- package/dist/adt/server-driven.d.ts +154 -34
- package/dist/adt/server-driven.d.ts.map +1 -1
- package/dist/adt/server-driven.js +178 -53
- package/dist/adt/server-driven.js.map +1 -1
- package/dist/adt/transport.d.ts +6 -6
- package/dist/adt/transport.d.ts.map +1 -1
- package/dist/adt/transport.js +23 -34
- package/dist/adt/transport.js.map +1 -1
- package/dist/adt/types.d.ts +47 -6
- package/dist/adt/types.d.ts.map +1 -1
- package/dist/adt/xml-parser.d.ts +52 -12
- package/dist/adt/xml-parser.d.ts.map +1 -1
- package/dist/adt/xml-parser.js +120 -10
- package/dist/adt/xml-parser.js.map +1 -1
- package/dist/authz/policy.d.ts +8 -0
- package/dist/authz/policy.d.ts.map +1 -1
- package/dist/authz/policy.js +23 -0
- package/dist/authz/policy.js.map +1 -1
- package/dist/cache/cache.d.ts +2 -34
- package/dist/cache/cache.d.ts.map +1 -1
- package/dist/cache/cache.js +2 -3
- package/dist/cache/cache.js.map +1 -1
- package/dist/cache/caching-layer.d.ts +3 -19
- package/dist/cache/caching-layer.d.ts.map +1 -1
- package/dist/cache/caching-layer.js +2 -26
- package/dist/cache/caching-layer.js.map +1 -1
- package/dist/cache/memory.d.ts +1 -12
- package/dist/cache/memory.d.ts.map +1 -1
- package/dist/cache/memory.js +0 -69
- package/dist/cache/memory.js.map +1 -1
- package/dist/cache/sqlite.d.ts +2 -9
- package/dist/cache/sqlite.d.ts.map +1 -1
- package/dist/cache/sqlite.js +8 -84
- package/dist/cache/sqlite.js.map +1 -1
- package/dist/cli.js +6 -3
- package/dist/cli.js.map +1 -1
- package/dist/context/unit-surgery.d.ts +28 -0
- package/dist/context/unit-surgery.d.ts.map +1 -0
- package/dist/context/unit-surgery.js +150 -0
- package/dist/context/unit-surgery.js.map +1 -0
- package/dist/handlers/activate.d.ts.map +1 -1
- package/dist/handlers/activate.js +44 -6
- package/dist/handlers/activate.js.map +1 -1
- package/dist/handlers/context.d.ts +1 -1
- package/dist/handlers/context.d.ts.map +1 -1
- package/dist/handlers/context.js +98 -28
- package/dist/handlers/context.js.map +1 -1
- package/dist/handlers/diagnose.d.ts.map +1 -1
- package/dist/handlers/diagnose.js +55 -31
- package/dist/handlers/diagnose.js.map +1 -1
- package/dist/handlers/dispatch.d.ts +12 -1
- package/dist/handlers/dispatch.d.ts.map +1 -1
- package/dist/handlers/dispatch.js +160 -25
- package/dist/handlers/dispatch.js.map +1 -1
- package/dist/handlers/feature-cache.d.ts +27 -14
- package/dist/handlers/feature-cache.d.ts.map +1 -1
- package/dist/handlers/feature-cache.js +63 -25
- package/dist/handlers/feature-cache.js.map +1 -1
- package/dist/handlers/function-processing.d.ts +61 -0
- package/dist/handlers/function-processing.d.ts.map +1 -0
- package/dist/handlers/function-processing.js +45 -0
- package/dist/handlers/function-processing.js.map +1 -0
- package/dist/handlers/git.d.ts.map +1 -1
- package/dist/handlers/git.js +44 -19
- package/dist/handlers/git.js.map +1 -1
- package/dist/handlers/hyperfocused.d.ts.map +1 -1
- package/dist/handlers/hyperfocused.js +2 -3
- package/dist/handlers/hyperfocused.js.map +1 -1
- package/dist/handlers/lint.d.ts.map +1 -1
- package/dist/handlers/lint.js +7 -7
- package/dist/handlers/lint.js.map +1 -1
- package/dist/handlers/manage.d.ts.map +1 -1
- package/dist/handlers/manage.js +42 -25
- package/dist/handlers/manage.js.map +1 -1
- package/dist/handlers/navigate.d.ts.map +1 -1
- package/dist/handlers/navigate.js +27 -90
- package/dist/handlers/navigate.js.map +1 -1
- package/dist/handlers/object-types.d.ts +2 -0
- package/dist/handlers/object-types.d.ts.map +1 -1
- package/dist/handlers/object-types.js +10 -0
- package/dist/handlers/object-types.js.map +1 -1
- package/dist/handlers/query.d.ts.map +1 -1
- package/dist/handlers/query.js +2 -2
- package/dist/handlers/query.js.map +1 -1
- package/dist/handlers/read.d.ts.map +1 -1
- package/dist/handlers/read.js +64 -41
- package/dist/handlers/read.js.map +1 -1
- package/dist/handlers/schemas.d.ts +64 -16
- package/dist/handlers/schemas.d.ts.map +1 -1
- package/dist/handlers/schemas.js +123 -32
- package/dist/handlers/schemas.js.map +1 -1
- package/dist/handlers/search.d.ts.map +1 -1
- package/dist/handlers/search.js +8 -7
- package/dist/handlers/search.js.map +1 -1
- package/dist/handlers/shared.d.ts +13 -0
- package/dist/handlers/shared.d.ts.map +1 -1
- package/dist/handlers/shared.js +15 -0
- package/dist/handlers/shared.js.map +1 -1
- package/dist/handlers/tool-descriptions.d.ts +4 -0
- package/dist/handlers/tool-descriptions.d.ts.map +1 -0
- package/dist/handlers/tool-descriptions.js +52 -0
- package/dist/handlers/tool-descriptions.js.map +1 -0
- package/dist/handlers/tool-registry.d.ts +18 -4
- package/dist/handlers/tool-registry.d.ts.map +1 -1
- package/dist/handlers/tool-registry.js +18 -0
- package/dist/handlers/tool-registry.js.map +1 -1
- package/dist/handlers/tools.d.ts.map +1 -1
- package/dist/handlers/tools.js +113 -90
- package/dist/handlers/tools.js.map +1 -1
- package/dist/handlers/transport.d.ts +1 -1
- package/dist/handlers/transport.d.ts.map +1 -1
- package/dist/handlers/transport.js +37 -10
- package/dist/handlers/transport.js.map +1 -1
- package/dist/handlers/where-used.d.ts +25 -0
- package/dist/handlers/where-used.d.ts.map +1 -0
- package/dist/handlers/where-used.js +94 -0
- package/dist/handlers/where-used.js.map +1 -0
- package/dist/handlers/write/class-surgery.d.ts.map +1 -1
- package/dist/handlers/write/class-surgery.js +11 -12
- package/dist/handlers/write/class-surgery.js.map +1 -1
- package/dist/handlers/write/create.d.ts.map +1 -1
- package/dist/handlers/write/create.js +194 -84
- package/dist/handlers/write/create.js.map +1 -1
- package/dist/handlers/write/rap.d.ts.map +1 -1
- package/dist/handlers/write/rap.js +9 -9
- package/dist/handlers/write/rap.js.map +1 -1
- package/dist/handlers/write/unit-surgery.d.ts +5 -0
- package/dist/handlers/write/unit-surgery.d.ts.map +1 -0
- package/dist/handlers/write/unit-surgery.js +47 -0
- package/dist/handlers/write/unit-surgery.js.map +1 -0
- package/dist/handlers/write/update-delete.js +8 -8
- package/dist/handlers/write/update-delete.js.map +1 -1
- package/dist/handlers/write-helpers.d.ts +7 -4
- package/dist/handlers/write-helpers.d.ts.map +1 -1
- package/dist/handlers/write-helpers.js +118 -63
- package/dist/handlers/write-helpers.js.map +1 -1
- package/dist/handlers/write.d.ts.map +1 -1
- package/dist/handlers/write.js +35 -13
- package/dist/handlers/write.js.map +1 -1
- package/dist/lint/lint.d.ts.map +1 -1
- package/dist/lint/lint.js +4 -2
- package/dist/lint/lint.js.map +1 -1
- package/dist/probe/catalog.js +1 -1
- package/dist/probe/catalog.js.map +1 -1
- package/dist/public/ui/app.js +1 -14
- package/dist/server/audit.d.ts +27 -15
- package/dist/server/audit.d.ts.map +1 -1
- package/dist/server/audit.js.map +1 -1
- package/dist/server/auth-rate-limit.d.ts +18 -9
- package/dist/server/auth-rate-limit.d.ts.map +1 -1
- package/dist/server/auth-rate-limit.js +31 -6
- package/dist/server/auth-rate-limit.js.map +1 -1
- package/dist/server/auth-summary.d.ts +4 -0
- package/dist/server/auth-summary.d.ts.map +1 -0
- package/dist/server/auth-summary.js +67 -0
- package/dist/server/auth-summary.js.map +1 -0
- package/dist/server/config.d.ts.map +1 -1
- package/dist/server/config.js +106 -3
- package/dist/server/config.js.map +1 -1
- package/dist/server/context.d.ts +12 -0
- package/dist/server/context.d.ts.map +1 -1
- package/dist/server/context.js.map +1 -1
- package/dist/server/destination-discovery.d.ts +36 -0
- package/dist/server/destination-discovery.d.ts.map +1 -0
- package/dist/server/destination-discovery.js +130 -0
- package/dist/server/destination-discovery.js.map +1 -0
- package/dist/server/destination-registry.d.ts +111 -0
- package/dist/server/destination-registry.d.ts.map +1 -0
- package/dist/server/destination-registry.js +449 -0
- package/dist/server/destination-registry.js.map +1 -0
- package/dist/server/http.d.ts +43 -1
- package/dist/server/http.d.ts.map +1 -1
- package/dist/server/http.js +283 -73
- package/dist/server/http.js.map +1 -1
- package/dist/server/logger.d.ts.map +1 -1
- package/dist/server/logger.js +58 -13
- package/dist/server/logger.js.map +1 -1
- package/dist/server/mcp-rate-limit.d.ts +6 -4
- package/dist/server/mcp-rate-limit.d.ts.map +1 -1
- package/dist/server/mcp-rate-limit.js +6 -4
- package/dist/server/mcp-rate-limit.js.map +1 -1
- package/dist/server/multi-target-basic-auth.d.ts +49 -0
- package/dist/server/multi-target-basic-auth.d.ts.map +1 -0
- package/dist/server/multi-target-basic-auth.js +246 -0
- package/dist/server/multi-target-basic-auth.js.map +1 -0
- package/dist/server/multi-target-catalog.d.ts +33 -0
- package/dist/server/multi-target-catalog.d.ts.map +1 -0
- package/dist/server/multi-target-catalog.js +130 -0
- package/dist/server/multi-target-catalog.js.map +1 -0
- package/dist/server/multi-target-destination-config.d.ts +12 -0
- package/dist/server/multi-target-destination-config.d.ts.map +1 -0
- package/dist/server/multi-target-destination-config.js +37 -0
- package/dist/server/multi-target-destination-config.js.map +1 -0
- package/dist/server/multi-target-destination-runtime.d.ts +20 -0
- package/dist/server/multi-target-destination-runtime.d.ts.map +1 -0
- package/dist/server/multi-target-destination-runtime.js +191 -0
- package/dist/server/multi-target-destination-runtime.js.map +1 -0
- package/dist/server/multi-target-feature-state.d.ts +6 -0
- package/dist/server/multi-target-feature-state.d.ts.map +1 -0
- package/dist/server/multi-target-feature-state.js +41 -0
- package/dist/server/multi-target-feature-state.js.map +1 -0
- package/dist/server/multi-target-identity.d.ts +10 -0
- package/dist/server/multi-target-identity.d.ts.map +1 -0
- package/dist/server/multi-target-identity.js +18 -0
- package/dist/server/multi-target-identity.js.map +1 -0
- package/dist/server/multi-target-runtime.d.ts +27 -0
- package/dist/server/multi-target-runtime.d.ts.map +1 -0
- package/dist/server/multi-target-runtime.js +110 -0
- package/dist/server/multi-target-runtime.js.map +1 -0
- package/dist/server/multi-target-server.d.ts +53 -0
- package/dist/server/multi-target-server.d.ts.map +1 -0
- package/dist/server/multi-target-server.js +434 -0
- package/dist/server/multi-target-server.js.map +1 -0
- package/dist/server/multi-target-shared-auth-state.d.ts +82 -0
- package/dist/server/multi-target-shared-auth-state.d.ts.map +1 -0
- package/dist/server/multi-target-shared-auth-state.js +226 -0
- package/dist/server/multi-target-shared-auth-state.js.map +1 -0
- package/dist/server/multi-target-tools.d.ts +20 -0
- package/dist/server/multi-target-tools.d.ts.map +1 -0
- package/dist/server/multi-target-tools.js +191 -0
- package/dist/server/multi-target-tools.js.map +1 -0
- package/dist/server/oauth-session-recovery.d.ts +22 -0
- package/dist/server/oauth-session-recovery.d.ts.map +1 -0
- package/dist/server/oauth-session-recovery.js +69 -0
- package/dist/server/oauth-session-recovery.js.map +1 -0
- package/dist/server/server.d.ts +39 -27
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +433 -300
- package/dist/server/server.js.map +1 -1
- package/dist/server/sinks/btp-auditlog.d.ts.map +1 -1
- package/dist/server/sinks/btp-auditlog.js +83 -11
- package/dist/server/sinks/btp-auditlog.js.map +1 -1
- package/dist/server/tool-auth.d.ts +10 -0
- package/dist/server/tool-auth.d.ts.map +1 -0
- package/dist/server/tool-auth.js +75 -0
- package/dist/server/tool-auth.js.map +1 -0
- package/dist/server/trace-context.d.ts +51 -0
- package/dist/server/trace-context.d.ts.map +1 -0
- package/dist/server/trace-context.js +100 -0
- package/dist/server/trace-context.js.map +1 -0
- package/dist/server/types.d.ts +27 -6
- package/dist/server/types.d.ts.map +1 -1
- package/dist/server/types.js +5 -2
- package/dist/server/types.js.map +1 -1
- package/dist/server/ui-state.d.ts +0 -2
- package/dist/server/ui-state.d.ts.map +1 -1
- package/dist/server/ui-state.js +0 -4
- package/dist/server/ui-state.js.map +1 -1
- package/dist/server/ui.d.ts.map +1 -1
- package/dist/server/ui.js +0 -7
- package/dist/server/ui.js.map +1 -1
- package/package.json +16 -13
- package/dist/cache/warmup.d.ts +0 -41
- package/dist/cache/warmup.d.ts.map +0 -1
- package/dist/cache/warmup.js +0 -337
- package/dist/cache/warmup.js.map +0 -1
- package/dist/server/elicit.d.ts +0 -43
- package/dist/server/elicit.d.ts.map +0 -1
- package/dist/server/elicit.js +0 -183
- package/dist/server/elicit.js.map +0 -1
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/** Secret-safe reader and administrator views for the SAPTargets MCP tool. */
|
|
2
|
+
import type { DestinationRegistry, TargetDescriptor } from './destination-registry.js';
|
|
3
|
+
export declare const TARGET_CATALOG_DIAGNOSTIC_LIMIT = 50;
|
|
4
|
+
export declare const TARGET_CATALOG_SHARED_AUTH_EXCEPTION_LIMIT = 8;
|
|
5
|
+
export declare const TARGET_CATALOG_MAX_OFFSET = 1000000;
|
|
6
|
+
export declare const TARGET_CATALOG_MAX_QUERY_LENGTH = 160;
|
|
7
|
+
export interface TargetCatalogOptions {
|
|
8
|
+
admin: boolean;
|
|
9
|
+
query?: string;
|
|
10
|
+
offset?: number;
|
|
11
|
+
/** Passive process-local health only; this callback must never probe SAP. */
|
|
12
|
+
runtimeAuth?: (target: string) => {
|
|
13
|
+
status: string;
|
|
14
|
+
checkedAt?: string;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Build the role-sensitive SAPTargets result.
|
|
19
|
+
*
|
|
20
|
+
* Readers retain the deliberately small `{target, description}[]` response. Admins additionally
|
|
21
|
+
* receive registry state and diagnostics. To keep the default result practical at 100–256 targets,
|
|
22
|
+
* the unfiltered admin view includes details only for non-active destinations; accepted targets in
|
|
23
|
+
* the public list are active by definition. Supplying `query` includes matching active diagnostics,
|
|
24
|
+
* and `offset` pages the deterministically sorted, bounded diagnostic result.
|
|
25
|
+
* Destination URLs, credentials, tokens, certificates, and raw Cloud Connector location IDs are not
|
|
26
|
+
* retained by DestinationRegistry and cannot enter this result.
|
|
27
|
+
*/
|
|
28
|
+
export declare function buildTargetCatalog(registry: DestinationRegistry, options: TargetCatalogOptions): Record<string, unknown> | Array<{
|
|
29
|
+
target: string;
|
|
30
|
+
description: string;
|
|
31
|
+
identity: TargetDescriptor['identity'];
|
|
32
|
+
}>;
|
|
33
|
+
//# sourceMappingURL=multi-target-catalog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multi-target-catalog.d.ts","sourceRoot":"","sources":["../../src/server/multi-target-catalog.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAE9E,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAoB,MAAM,2BAA2B,CAAC;AAEzG,eAAO,MAAM,+BAA+B,KAAK,CAAC;AAClD,eAAO,MAAM,0CAA0C,IAAI,CAAC;AAC5D,eAAO,MAAM,yBAAyB,UAAY,CAAC;AACnD,eAAO,MAAM,+BAA+B,MAAM,CAAC;AAanD,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6EAA6E;IAC7E,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC1E;AAgCD;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,mBAAmB,EAC7B,OAAO,EAAE,oBAAoB,GAC5B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,gBAAgB,CAAC,UAAU,CAAC,CAAA;CAAE,CAAC,CAsFlH"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/** Secret-safe reader and administrator views for the SAPTargets MCP tool. */
|
|
2
|
+
export const TARGET_CATALOG_DIAGNOSTIC_LIMIT = 50;
|
|
3
|
+
export const TARGET_CATALOG_SHARED_AUTH_EXCEPTION_LIMIT = 8;
|
|
4
|
+
export const TARGET_CATALOG_MAX_OFFSET = 1_000_000;
|
|
5
|
+
export const TARGET_CATALOG_MAX_QUERY_LENGTH = 160;
|
|
6
|
+
function targetMatches(target, query) {
|
|
7
|
+
return !query || target.target.toLowerCase().includes(query) || target.description.toLowerCase().includes(query);
|
|
8
|
+
}
|
|
9
|
+
function diagnosticMatches(entry, query) {
|
|
10
|
+
if (!query)
|
|
11
|
+
return true;
|
|
12
|
+
return [entry.destinationName, entry.target, entry.status, entry.code, entry.message, entry.description]
|
|
13
|
+
.filter((value) => typeof value === 'string')
|
|
14
|
+
.some((value) => value.toLowerCase().includes(query));
|
|
15
|
+
}
|
|
16
|
+
// `checking` is an ordinary in-flight canary, not an operator exception. Completed failures such
|
|
17
|
+
// as `temporarily_unavailable` deliberately remain exceptional and visible to administrators.
|
|
18
|
+
const NORMAL_SHARED_AUTH_STATES = new Set(['not_checked', 'checking', 'healthy']);
|
|
19
|
+
function incrementStatus(counts, status) {
|
|
20
|
+
counts[status] = (counts[status] ?? 0) + 1;
|
|
21
|
+
}
|
|
22
|
+
function safeDiagnostic(entry) {
|
|
23
|
+
return {
|
|
24
|
+
destinationName: entry.destinationName,
|
|
25
|
+
target: entry.target,
|
|
26
|
+
status: entry.status,
|
|
27
|
+
code: entry.code,
|
|
28
|
+
message: entry.message,
|
|
29
|
+
description: entry.description,
|
|
30
|
+
type: entry.type,
|
|
31
|
+
proxyType: entry.proxyType,
|
|
32
|
+
sid: entry.sid,
|
|
33
|
+
client: entry.client,
|
|
34
|
+
language: entry.language,
|
|
35
|
+
hasCloudConnectorLocationId: entry.hasCloudConnectorLocationId,
|
|
36
|
+
arcConfig: entry.arcConfig,
|
|
37
|
+
requestedPolicy: entry.requestedPolicy,
|
|
38
|
+
effectivePolicy: entry.effectivePolicy,
|
|
39
|
+
limitedByInstance: entry.limitedByInstance,
|
|
40
|
+
warnings: entry.warnings,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Build the role-sensitive SAPTargets result.
|
|
45
|
+
*
|
|
46
|
+
* Readers retain the deliberately small `{target, description}[]` response. Admins additionally
|
|
47
|
+
* receive registry state and diagnostics. To keep the default result practical at 100–256 targets,
|
|
48
|
+
* the unfiltered admin view includes details only for non-active destinations; accepted targets in
|
|
49
|
+
* the public list are active by definition. Supplying `query` includes matching active diagnostics,
|
|
50
|
+
* and `offset` pages the deterministically sorted, bounded diagnostic result.
|
|
51
|
+
* Destination URLs, credentials, tokens, certificates, and raw Cloud Connector location IDs are not
|
|
52
|
+
* retained by DestinationRegistry and cannot enter this result.
|
|
53
|
+
*/
|
|
54
|
+
export function buildTargetCatalog(registry, options) {
|
|
55
|
+
const query = options.query?.trim().toLowerCase() ?? '';
|
|
56
|
+
const targets = registry.targets.filter((target) => targetMatches(target, query));
|
|
57
|
+
if (!options.admin) {
|
|
58
|
+
return targets.map((target) => ({
|
|
59
|
+
target: target.target,
|
|
60
|
+
description: target.description,
|
|
61
|
+
identity: target.identity,
|
|
62
|
+
}));
|
|
63
|
+
}
|
|
64
|
+
const sharedAuthStatusCounts = {};
|
|
65
|
+
const sharedAuthExceptions = [];
|
|
66
|
+
let sharedAuthTargetCount = 0;
|
|
67
|
+
const publicTargets = targets.map((target) => {
|
|
68
|
+
const runtimeAuth = target.authentication === 'BasicAuthentication' && options.runtimeAuth
|
|
69
|
+
? options.runtimeAuth(target.target)
|
|
70
|
+
: undefined;
|
|
71
|
+
if (runtimeAuth) {
|
|
72
|
+
sharedAuthTargetCount += 1;
|
|
73
|
+
incrementStatus(sharedAuthStatusCounts, runtimeAuth.status);
|
|
74
|
+
if (!NORMAL_SHARED_AUTH_STATES.has(runtimeAuth.status)) {
|
|
75
|
+
sharedAuthExceptions.push({ target: target.target, ...runtimeAuth });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return {
|
|
79
|
+
target: target.target,
|
|
80
|
+
description: target.description,
|
|
81
|
+
identity: target.identity,
|
|
82
|
+
};
|
|
83
|
+
});
|
|
84
|
+
const diagnosticOffset = options.offset ?? 0;
|
|
85
|
+
const matchingDiagnostics = registry.diagnostics
|
|
86
|
+
.filter((entry) => (query ? diagnosticMatches(entry, query) : entry.status !== 'active'))
|
|
87
|
+
.sort((left, right) => `${left.destinationName}\0${left.target ?? ''}\0${left.code}`.localeCompare(`${right.destinationName}\0${right.target ?? ''}\0${right.code}`));
|
|
88
|
+
const diagnostics = matchingDiagnostics
|
|
89
|
+
.slice(diagnosticOffset, diagnosticOffset + TARGET_CATALOG_DIAGNOSTIC_LIMIT)
|
|
90
|
+
.map(safeDiagnostic);
|
|
91
|
+
const diagnosticNextOffset = diagnosticOffset + diagnostics.length < matchingDiagnostics.length
|
|
92
|
+
? diagnosticOffset + diagnostics.length
|
|
93
|
+
: undefined;
|
|
94
|
+
sharedAuthExceptions.sort((left, right) => String(left.target).localeCompare(String(right.target)));
|
|
95
|
+
return {
|
|
96
|
+
targets: publicTargets,
|
|
97
|
+
admin: {
|
|
98
|
+
state: registry.failure ? 'error' : registry.counts.quarantined > 0 ? 'degraded' : 'ready',
|
|
99
|
+
source: 'btp-subaccount',
|
|
100
|
+
loadedAt: registry.loadedAt,
|
|
101
|
+
revision: registry.revision,
|
|
102
|
+
counts: registry.counts,
|
|
103
|
+
...(sharedAuthTargetCount > 0
|
|
104
|
+
? {
|
|
105
|
+
sharedAuthentication: {
|
|
106
|
+
targets: sharedAuthTargetCount,
|
|
107
|
+
statusCounts: sharedAuthStatusCounts,
|
|
108
|
+
...(sharedAuthExceptions.length > 0
|
|
109
|
+
? {
|
|
110
|
+
exceptionTotal: sharedAuthExceptions.length,
|
|
111
|
+
exceptionReturned: Math.min(sharedAuthExceptions.length, TARGET_CATALOG_SHARED_AUTH_EXCEPTION_LIMIT),
|
|
112
|
+
exceptionsTruncated: sharedAuthExceptions.length > TARGET_CATALOG_SHARED_AUTH_EXCEPTION_LIMIT,
|
|
113
|
+
exceptions: sharedAuthExceptions.slice(0, TARGET_CATALOG_SHARED_AUTH_EXCEPTION_LIMIT),
|
|
114
|
+
}
|
|
115
|
+
: {}),
|
|
116
|
+
},
|
|
117
|
+
}
|
|
118
|
+
: {}),
|
|
119
|
+
failure: registry.failure,
|
|
120
|
+
diagnosticMode: query ? 'matching' : 'exceptions',
|
|
121
|
+
diagnosticOffset,
|
|
122
|
+
diagnosticTotal: matchingDiagnostics.length,
|
|
123
|
+
diagnosticReturned: diagnostics.length,
|
|
124
|
+
diagnosticsTruncated: diagnosticOffset > 0 || diagnosticNextOffset !== undefined,
|
|
125
|
+
diagnosticNextOffset,
|
|
126
|
+
destinations: diagnostics,
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=multi-target-catalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multi-target-catalog.js","sourceRoot":"","sources":["../../src/server/multi-target-catalog.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Destination-property contract for multi-target v1.
|
|
3
|
+
*
|
|
4
|
+
* Keep this file deliberately small: discovery, startup validation, and runtime
|
|
5
|
+
* drift checks must all agree on the exact same property names and value syntax.
|
|
6
|
+
*/
|
|
7
|
+
export declare const MULTI_TARGET_ARC_PROPERTIES: readonly string[];
|
|
8
|
+
export declare function isSupportedMultiTargetArcProperty(key: string): boolean;
|
|
9
|
+
export declare function isWriteRelatedArcProperty(key: string): boolean;
|
|
10
|
+
/** Parse the destination-service boolean format without inventing a default. */
|
|
11
|
+
export declare function parseDestinationBoolean(value: string | undefined): boolean | undefined;
|
|
12
|
+
//# sourceMappingURL=multi-target-destination-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multi-target-destination-config.d.ts","sourceRoot":"","sources":["../../src/server/multi-target-destination-config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,2BAA2B,mBAKtC,CAAC;AAUH,wBAAgB,iCAAiC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEtE;AAED,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED,gFAAgF;AAChF,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAMtF"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Destination-property contract for multi-target v1.
|
|
3
|
+
*
|
|
4
|
+
* Keep this file deliberately small: discovery, startup validation, and runtime
|
|
5
|
+
* drift checks must all agree on the exact same property names and value syntax.
|
|
6
|
+
*/
|
|
7
|
+
export const MULTI_TARGET_ARC_PROPERTIES = Object.freeze([
|
|
8
|
+
'arc1.enabled',
|
|
9
|
+
'arc1.allow_data_preview',
|
|
10
|
+
'arc1.allow_free_sql',
|
|
11
|
+
'arc1.target_alias',
|
|
12
|
+
]);
|
|
13
|
+
const SUPPORTED_ARC_PROPERTIES = new Set(MULTI_TARGET_ARC_PROPERTIES);
|
|
14
|
+
const WRITE_ARC_PROPERTIES = new Set([
|
|
15
|
+
'arc1.allow_writes',
|
|
16
|
+
'arc1.allowed_packages',
|
|
17
|
+
'arc1.allow_transport_writes',
|
|
18
|
+
'arc1.allow_git_writes',
|
|
19
|
+
]);
|
|
20
|
+
export function isSupportedMultiTargetArcProperty(key) {
|
|
21
|
+
return SUPPORTED_ARC_PROPERTIES.has(key);
|
|
22
|
+
}
|
|
23
|
+
export function isWriteRelatedArcProperty(key) {
|
|
24
|
+
return WRITE_ARC_PROPERTIES.has(key);
|
|
25
|
+
}
|
|
26
|
+
/** Parse the destination-service boolean format without inventing a default. */
|
|
27
|
+
export function parseDestinationBoolean(value) {
|
|
28
|
+
if (value === undefined)
|
|
29
|
+
return undefined;
|
|
30
|
+
const normalized = value.trim().toLowerCase();
|
|
31
|
+
if (normalized === 'true')
|
|
32
|
+
return true;
|
|
33
|
+
if (normalized === 'false')
|
|
34
|
+
return false;
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=multi-target-destination-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multi-target-destination-config.js","sourceRoot":"","sources":["../../src/server/multi-target-destination-config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,2BAA2B,GAAG,MAAM,CAAC,MAAM,CAAC;IACvD,cAAc;IACd,yBAAyB;IACzB,qBAAqB;IACrB,mBAAmB;CACpB,CAAC,CAAC;AAEH,MAAM,wBAAwB,GAAG,IAAI,GAAG,CAAC,2BAA2B,CAAC,CAAC;AACtE,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC;IACnC,mBAAmB;IACnB,uBAAuB;IACvB,6BAA6B;IAC7B,uBAAuB;CACxB,CAAC,CAAC;AAEH,MAAM,UAAU,iCAAiC,CAAC,GAAW;IAC3D,OAAO,wBAAwB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,GAAW;IACnD,OAAO,oBAAoB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACvC,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,uBAAuB,CAAC,KAAyB;IAC/D,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC1C,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC9C,IAAI,UAAU,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IACvC,IAAI,UAAU,KAAK,OAAO;QAAE,OAAO,KAAK,CAAC;IACzC,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/** Level-pinned Destination Service resolution for multi-target request paths. */
|
|
2
|
+
import type { BTPConfig, Destination, PerUserAuthTokens } from '@arc-mcp/xsuaa-auth/btp';
|
|
3
|
+
export type RuntimeDestinationLevelCode = 'DESTINATION_NOT_FOUND_AT_SUBACCOUNT' | 'INSTANCE_DESTINATION_SHADOW';
|
|
4
|
+
export declare class RuntimeDestinationLevelError extends Error {
|
|
5
|
+
readonly code: RuntimeDestinationLevelCode;
|
|
6
|
+
readonly destinationName: string;
|
|
7
|
+
constructor(code: RuntimeDestinationLevelCode, destinationName: string);
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Resolve the current destination through Find, but accept it only when Destination Service reports
|
|
11
|
+
* a subaccount owner. This keeps request-time Basic rotation and PP drift checks efficient while
|
|
12
|
+
* rejecting the instance-over-subaccount precedence that the generic Find API normally applies.
|
|
13
|
+
*/
|
|
14
|
+
export declare function resolveRuntimeSubaccountDestination(btpConfig: BTPConfig, destinationName: string): Promise<Destination>;
|
|
15
|
+
/** Resolve PP from an owner-confirmed subaccount destination and verified user JWT. */
|
|
16
|
+
export declare function resolveRuntimeSubaccountPpDestination(btpConfig: BTPConfig, destinationName: string, userJwt: string): Promise<{
|
|
17
|
+
destination: Destination;
|
|
18
|
+
authTokens: PerUserAuthTokens;
|
|
19
|
+
}>;
|
|
20
|
+
//# sourceMappingURL=multi-target-destination-runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multi-target-destination-runtime.d.ts","sourceRoot":"","sources":["../../src/server/multi-target-destination-runtime.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAElF,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAOzF,MAAM,MAAM,2BAA2B,GAAG,qCAAqC,GAAG,6BAA6B,CAAC;AAEhH,qBAAa,4BAA6B,SAAQ,KAAK;IAEnD,QAAQ,CAAC,IAAI,EAAE,2BAA2B;IAC1C,QAAQ,CAAC,eAAe,EAAE,MAAM;IAFlC,YACW,IAAI,EAAE,2BAA2B,EACjC,eAAe,EAAE,MAAM,EAQjC;CACF;AAmGD;;;;GAIG;AACH,wBAAsB,mCAAmC,CACvD,SAAS,EAAE,SAAS,EACpB,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,WAAW,CAAC,CAgCtB;AAwCD,uFAAuF;AACvF,wBAAsB,qCAAqC,CACzD,SAAS,EAAE,SAAS,EACpB,eAAe,EAAE,MAAM,EACvB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC;IAAE,WAAW,EAAE,WAAW,CAAC;IAAC,UAAU,EAAE,iBAAiB,CAAA;CAAE,CAAC,CAStE"}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/** Level-pinned Destination Service resolution for multi-target request paths. */
|
|
2
|
+
import { logger } from './logger.js';
|
|
3
|
+
import { isSupportedMultiTargetArcProperty } from './multi-target-destination-config.js';
|
|
4
|
+
const DEFAULT_REQUEST_TIMEOUT_MS = 10_000;
|
|
5
|
+
const MAX_REQUEST_TIMEOUT_MS = 60_000;
|
|
6
|
+
export class RuntimeDestinationLevelError extends Error {
|
|
7
|
+
code;
|
|
8
|
+
destinationName;
|
|
9
|
+
constructor(code, destinationName) {
|
|
10
|
+
super(code === 'INSTANCE_DESTINATION_SHADOW'
|
|
11
|
+
? `Destination '${destinationName}' is shadowed by a service-instance destination. Remove the instance-level destination and restart ARC-1.`
|
|
12
|
+
: `Destination '${destinationName}' no longer exists at subaccount level. Restore it and restart ARC-1.`);
|
|
13
|
+
this.code = code;
|
|
14
|
+
this.destinationName = destinationName;
|
|
15
|
+
this.name = 'RuntimeDestinationLevelError';
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function isRecord(value) {
|
|
19
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
20
|
+
}
|
|
21
|
+
function stringProperty(properties, key) {
|
|
22
|
+
const value = properties[key];
|
|
23
|
+
return typeof value === 'string' ? value : '';
|
|
24
|
+
}
|
|
25
|
+
function boundedTimeoutMs(configured) {
|
|
26
|
+
if (configured === undefined || !Number.isFinite(configured) || configured <= 0) {
|
|
27
|
+
return DEFAULT_REQUEST_TIMEOUT_MS;
|
|
28
|
+
}
|
|
29
|
+
return Math.max(1, Math.min(Math.floor(configured), MAX_REQUEST_TIMEOUT_MS));
|
|
30
|
+
}
|
|
31
|
+
async function withRequestTimeout(configuredTimeoutMs, operation) {
|
|
32
|
+
const controller = new AbortController();
|
|
33
|
+
const timer = setTimeout(() => controller.abort(), boundedTimeoutMs(configuredTimeoutMs));
|
|
34
|
+
timer.unref?.();
|
|
35
|
+
try {
|
|
36
|
+
return await operation(controller.signal);
|
|
37
|
+
}
|
|
38
|
+
finally {
|
|
39
|
+
clearTimeout(timer);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
async function destinationServiceAccessToken(btpConfig) {
|
|
43
|
+
const tokenUrl = btpConfig.destinationTokenUrl || `${btpConfig.xsuaaUrl.replace(/\/$/, '')}/oauth/token`;
|
|
44
|
+
return withRequestTimeout(btpConfig.requestTimeoutMs, async (signal) => {
|
|
45
|
+
const response = await fetch(tokenUrl, {
|
|
46
|
+
method: 'POST',
|
|
47
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
48
|
+
body: new URLSearchParams({
|
|
49
|
+
grant_type: 'client_credentials',
|
|
50
|
+
client_id: btpConfig.destinationClientId,
|
|
51
|
+
client_secret: btpConfig.destinationSecret,
|
|
52
|
+
}).toString(),
|
|
53
|
+
signal,
|
|
54
|
+
});
|
|
55
|
+
if (!response.ok) {
|
|
56
|
+
await response.body?.cancel().catch(() => undefined);
|
|
57
|
+
throw new Error(`Destination Service token request returned HTTP ${response.status}`);
|
|
58
|
+
}
|
|
59
|
+
const data = await response.json();
|
|
60
|
+
if (!isRecord(data) || typeof data.access_token !== 'string' || data.access_token.length === 0) {
|
|
61
|
+
throw new Error('Destination Service token response was invalid');
|
|
62
|
+
}
|
|
63
|
+
return data.access_token;
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
function safeOriginalProperties(configuration) {
|
|
67
|
+
const safe = {};
|
|
68
|
+
const standardKeys = [
|
|
69
|
+
'Name',
|
|
70
|
+
'Type',
|
|
71
|
+
'URL',
|
|
72
|
+
'Authentication',
|
|
73
|
+
'ProxyType',
|
|
74
|
+
'sap-sysid',
|
|
75
|
+
'sap-client',
|
|
76
|
+
'sap-language',
|
|
77
|
+
'Description',
|
|
78
|
+
'CloudConnectorLocationId',
|
|
79
|
+
'Preemptive',
|
|
80
|
+
];
|
|
81
|
+
for (const key of standardKeys) {
|
|
82
|
+
if (configuration[key] !== undefined)
|
|
83
|
+
safe[key] = configuration[key];
|
|
84
|
+
}
|
|
85
|
+
for (const [key, value] of Object.entries(configuration)) {
|
|
86
|
+
if (!key.toLowerCase().startsWith('arc1.'))
|
|
87
|
+
continue;
|
|
88
|
+
// Unknown/wrong-case ARC keys must remain visible to fail-closed validation, but their
|
|
89
|
+
// untrusted values are unnecessary and could themselves contain sensitive material.
|
|
90
|
+
safe[key] = isSupportedMultiTargetArcProperty(key) ? value : '';
|
|
91
|
+
}
|
|
92
|
+
return Object.freeze(safe);
|
|
93
|
+
}
|
|
94
|
+
function destinationFromConfiguration(configuration) {
|
|
95
|
+
return {
|
|
96
|
+
Name: stringProperty(configuration, 'Name'),
|
|
97
|
+
URL: stringProperty(configuration, 'URL'),
|
|
98
|
+
Authentication: stringProperty(configuration, 'Authentication'),
|
|
99
|
+
ProxyType: stringProperty(configuration, 'ProxyType'),
|
|
100
|
+
User: stringProperty(configuration, 'User'),
|
|
101
|
+
Password: stringProperty(configuration, 'Password'),
|
|
102
|
+
Type: stringProperty(configuration, 'Type') || undefined,
|
|
103
|
+
'sap-client': stringProperty(configuration, 'sap-client') || undefined,
|
|
104
|
+
CloudConnectorLocationId: stringProperty(configuration, 'CloudConnectorLocationId') || undefined,
|
|
105
|
+
originalProperties: safeOriginalProperties(configuration),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Resolve the current destination through Find, but accept it only when Destination Service reports
|
|
110
|
+
* a subaccount owner. This keeps request-time Basic rotation and PP drift checks efficient while
|
|
111
|
+
* rejecting the instance-over-subaccount precedence that the generic Find API normally applies.
|
|
112
|
+
*/
|
|
113
|
+
export async function resolveRuntimeSubaccountDestination(btpConfig, destinationName) {
|
|
114
|
+
const accessToken = await destinationServiceAccessToken(btpConfig);
|
|
115
|
+
const baseUrl = btpConfig.destinationUrl.replace(/\/$/, '');
|
|
116
|
+
const url = `${baseUrl}/destination-configuration/v1/destinations/${encodeURIComponent(destinationName)}?$skipTokenRetrieval=true`;
|
|
117
|
+
return withRequestTimeout(btpConfig.requestTimeoutMs, async (signal) => {
|
|
118
|
+
const response = await fetch(url, {
|
|
119
|
+
headers: { Authorization: `Bearer ${accessToken}` },
|
|
120
|
+
signal,
|
|
121
|
+
});
|
|
122
|
+
if (response.status === 404) {
|
|
123
|
+
await response.body?.cancel().catch(() => undefined);
|
|
124
|
+
throw new RuntimeDestinationLevelError('DESTINATION_NOT_FOUND_AT_SUBACCOUNT', destinationName);
|
|
125
|
+
}
|
|
126
|
+
if (!response.ok) {
|
|
127
|
+
await response.body?.cancel().catch(() => undefined);
|
|
128
|
+
throw new Error(`Destination Service runtime lookup returned HTTP ${response.status}`);
|
|
129
|
+
}
|
|
130
|
+
const data = await response.json();
|
|
131
|
+
if (!isRecord(data) || !isRecord(data.owner)) {
|
|
132
|
+
throw new Error('Destination Service runtime lookup returned an invalid response');
|
|
133
|
+
}
|
|
134
|
+
if (typeof data.owner.InstanceId === 'string' && data.owner.InstanceId.length > 0) {
|
|
135
|
+
throw new RuntimeDestinationLevelError('INSTANCE_DESTINATION_SHADOW', destinationName);
|
|
136
|
+
}
|
|
137
|
+
if (typeof data.owner.SubaccountId !== 'string' || data.owner.SubaccountId.length === 0) {
|
|
138
|
+
throw new RuntimeDestinationLevelError('DESTINATION_NOT_FOUND_AT_SUBACCOUNT', destinationName);
|
|
139
|
+
}
|
|
140
|
+
if (!isRecord(data.destinationConfiguration)) {
|
|
141
|
+
throw new Error('Destination Service runtime lookup returned an invalid destination configuration');
|
|
142
|
+
}
|
|
143
|
+
return destinationFromConfiguration(data.destinationConfiguration);
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
async function validateJwtForConnectivity(btpConfig, destinationName, userJwt) {
|
|
147
|
+
if (!btpConfig.connectivityClientId || !btpConfig.connectivitySecret || !btpConfig.connectivityTokenUrl) {
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
try {
|
|
151
|
+
return await withRequestTimeout(btpConfig.requestTimeoutMs, async (signal) => {
|
|
152
|
+
const response = await fetch(btpConfig.connectivityTokenUrl, {
|
|
153
|
+
method: 'POST',
|
|
154
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
155
|
+
body: new URLSearchParams({
|
|
156
|
+
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
|
|
157
|
+
client_id: btpConfig.connectivityClientId,
|
|
158
|
+
client_secret: btpConfig.connectivitySecret,
|
|
159
|
+
assertion: userJwt,
|
|
160
|
+
token_format: 'jwt',
|
|
161
|
+
response_type: 'token',
|
|
162
|
+
}).toString(),
|
|
163
|
+
signal,
|
|
164
|
+
});
|
|
165
|
+
await response.arrayBuffer();
|
|
166
|
+
if (!response.ok) {
|
|
167
|
+
logger.warn('PP jwt-bearer validation failed', { destination: destinationName, status: response.status });
|
|
168
|
+
}
|
|
169
|
+
return response.ok;
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
logger.warn('PP jwt-bearer validation failed', {
|
|
174
|
+
destination: destinationName,
|
|
175
|
+
reason: error instanceof Error && error.name === 'AbortError' ? 'timeout' : 'request_failed',
|
|
176
|
+
});
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
/** Resolve PP from an owner-confirmed subaccount destination and verified user JWT. */
|
|
181
|
+
export async function resolveRuntimeSubaccountPpDestination(btpConfig, destinationName, userJwt) {
|
|
182
|
+
const destination = await resolveRuntimeSubaccountDestination(btpConfig, destinationName);
|
|
183
|
+
const authTokens = {};
|
|
184
|
+
if (await validateJwtForConnectivity(btpConfig, destinationName, userJwt)) {
|
|
185
|
+
// PP Option 2: the exchange validates the user token; Cloud Connector consumes the original
|
|
186
|
+
// token from SAP-Connectivity-Authentication to create the short-lived user certificate.
|
|
187
|
+
authTokens.sapConnectivityAuth = `Bearer ${userJwt}`;
|
|
188
|
+
}
|
|
189
|
+
return { destination, authTokens };
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=multi-target-destination-runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multi-target-destination-runtime.js","sourceRoot":"","sources":["../../src/server/multi-target-destination-runtime.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Authorization-safe, success-only feature state for discovered targets. */
|
|
2
|
+
import type { ResolvedFeatures } from '../adt/types.js';
|
|
3
|
+
export declare function hasAuthorizationLimitedFeatureEvidence(features: ResolvedFeatures): boolean;
|
|
4
|
+
/** One in-flight probe per target. Rejections are observed, cleared, and never cached. */
|
|
5
|
+
export declare function ensureMultiTargetFeatureProbe(target: string | undefined, alreadyKnown: boolean, probe: () => Promise<void>, clearFailedEvidence: () => void): Promise<void>;
|
|
6
|
+
//# sourceMappingURL=multi-target-feature-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multi-target-feature-state.d.ts","sourceRoot":"","sources":["../../src/server/multi-target-feature-state.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAE7E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAIxD,wBAAgB,sCAAsC,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAkB1F;AAED,0FAA0F;AAC1F,wBAAsB,6BAA6B,CACjD,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,YAAY,EAAE,OAAO,EACrB,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EAC1B,mBAAmB,EAAE,MAAM,IAAI,GAC9B,OAAO,CAAC,IAAI,CAAC,CAef"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/** Authorization-safe, success-only feature state for discovered targets. */
|
|
2
|
+
const probeFlights = new Map();
|
|
3
|
+
export function hasAuthorizationLimitedFeatureEvidence(features) {
|
|
4
|
+
const authMarker = /(authorization|auth failure|forbidden|\b401\b|\b403\b)/i;
|
|
5
|
+
const featureStatuses = [
|
|
6
|
+
features.hana,
|
|
7
|
+
features.abapGit,
|
|
8
|
+
features.gcts,
|
|
9
|
+
features.rap,
|
|
10
|
+
features.amdp,
|
|
11
|
+
features.ui5,
|
|
12
|
+
features.transport,
|
|
13
|
+
features.ui5repo,
|
|
14
|
+
features.flp,
|
|
15
|
+
];
|
|
16
|
+
if (featureStatuses.some((status) => !status.available && authMarker.test(status.message ?? '')))
|
|
17
|
+
return true;
|
|
18
|
+
if (!features.textSearch?.available && authMarker.test(features.textSearch?.reason ?? ''))
|
|
19
|
+
return true;
|
|
20
|
+
return [features.authProbe?.searchReason, features.authProbe?.transportReason].some((reason) => authMarker.test(reason ?? ''));
|
|
21
|
+
}
|
|
22
|
+
/** One in-flight probe per target. Rejections are observed, cleared, and never cached. */
|
|
23
|
+
export async function ensureMultiTargetFeatureProbe(target, alreadyKnown, probe, clearFailedEvidence) {
|
|
24
|
+
if (!target || alreadyKnown)
|
|
25
|
+
return;
|
|
26
|
+
let flight = probeFlights.get(target);
|
|
27
|
+
if (!flight) {
|
|
28
|
+
flight = probe();
|
|
29
|
+
probeFlights.set(target, flight);
|
|
30
|
+
const cleanup = () => {
|
|
31
|
+
if (probeFlights.get(target) === flight)
|
|
32
|
+
probeFlights.delete(target);
|
|
33
|
+
};
|
|
34
|
+
flight.then(cleanup, () => {
|
|
35
|
+
clearFailedEvidence();
|
|
36
|
+
cleanup();
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
await flight;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=multi-target-feature-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multi-target-feature-state.js","sourceRoot":"","sources":["../../src/server/multi-target-feature-state.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAI7E,MAAM,YAAY,GAAG,IAAI,GAAG,EAAyB,CAAC;AAEtD,MAAM,UAAU,sCAAsC,CAAC,QAA0B;IAC/E,MAAM,UAAU,GAAG,yDAAyD,CAAC;IAC7E,MAAM,eAAe,GAAG;QACtB,QAAQ,CAAC,IAAI;QACb,QAAQ,CAAC,OAAO;QAChB,QAAQ,CAAC,IAAI;QACb,QAAQ,CAAC,GAAG;QACZ,QAAQ,CAAC,IAAI;QACb,QAAQ,CAAC,GAAG;QACZ,QAAQ,CAAC,SAAS;QAClB,QAAQ,CAAC,OAAO;QAChB,QAAQ,CAAC,GAAG;KACb,CAAC;IACF,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,SAAS,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAC9G,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,SAAS,IAAI,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,IAAI,EAAE,CAAC;QAAE,OAAO,IAAI,CAAC;IACvG,OAAO,CAAC,QAAQ,CAAC,SAAS,EAAE,YAAY,EAAE,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAC7F,UAAU,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAC9B,CAAC;AACJ,CAAC;AAED,0FAA0F;AAC1F,MAAM,CAAC,KAAK,UAAU,6BAA6B,CACjD,MAA0B,EAC1B,YAAqB,EACrB,KAA0B,EAC1B,mBAA+B;IAE/B,IAAI,CAAC,MAAM,IAAI,YAAY;QAAE,OAAO;IACpC,IAAI,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACtC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,GAAG,KAAK,EAAE,CAAC;QACjB,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACjC,MAAM,OAAO,GAAG,GAAG,EAAE;YACnB,IAAI,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,MAAM;gBAAE,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACvE,CAAC,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;YACxB,mBAAmB,EAAE,CAAC;YACtB,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC;IACD,MAAM,MAAM,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Public target-ID and HTTP-route syntax for destination-discovered multi-target mode. */
|
|
2
|
+
export declare const SAP_SYSID_PATTERN: RegExp;
|
|
3
|
+
export declare const TARGET_SYSTEM_SEGMENT_SOURCE = "[A-Z][A-Z0-9-]{1,30}[A-Z0-9]";
|
|
4
|
+
export declare const TARGET_SYSTEM_ALIAS_PATTERN: RegExp;
|
|
5
|
+
export declare const TARGET_ID_PATTERN: RegExp;
|
|
6
|
+
export declare const PINNED_MCP_PATH_PATTERN: RegExp;
|
|
7
|
+
export declare const PINNED_RESOURCE_METADATA_PATH_PATTERN: RegExp;
|
|
8
|
+
export declare function buildTargetId(sid: string, client: string, alias?: string): string;
|
|
9
|
+
export declare function targetFromPinnedMcpPath(path: string): string | undefined;
|
|
10
|
+
//# sourceMappingURL=multi-target-identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multi-target-identity.d.ts","sourceRoot":"","sources":["../../src/server/multi-target-identity.ts"],"names":[],"mappings":"AAAA,2FAA2F;AAE3F,eAAO,MAAM,iBAAiB,QAAuB,CAAC;AAKtD,eAAO,MAAM,4BAA4B,iCAAiC,CAAC;AAC3E,eAAO,MAAM,2BAA2B,QAAkD,CAAC;AAC3F,eAAO,MAAM,iBAAiB,QAA2D,CAAC;AAC1F,eAAO,MAAM,uBAAuB,QAAoE,CAAC;AACzG,eAAO,MAAM,qCAAqC,QAEjD,CAAC;AAEF,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAEjF;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGxE"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** Public target-ID and HTTP-route syntax for destination-discovered multi-target mode. */
|
|
2
|
+
export const SAP_SYSID_PATTERN = /^[A-Z][A-Z0-9]{2}$/;
|
|
3
|
+
// A route alias is useful when separate SAP systems reuse the same SID and client.
|
|
4
|
+
// Keep it URL-friendly, case-sensitive, and bounded: 3-32 characters, with no
|
|
5
|
+
// leading or trailing hyphen. The real SAP identity remains sap-sysid/sap-client.
|
|
6
|
+
export const TARGET_SYSTEM_SEGMENT_SOURCE = '[A-Z][A-Z0-9-]{1,30}[A-Z0-9]';
|
|
7
|
+
export const TARGET_SYSTEM_ALIAS_PATTERN = new RegExp(`^${TARGET_SYSTEM_SEGMENT_SOURCE}$`);
|
|
8
|
+
export const TARGET_ID_PATTERN = new RegExp(`^${TARGET_SYSTEM_SEGMENT_SOURCE}/[0-9]{3}$`);
|
|
9
|
+
export const PINNED_MCP_PATH_PATTERN = new RegExp(`^/(${TARGET_SYSTEM_SEGMENT_SOURCE})/([0-9]{3})/mcp$`);
|
|
10
|
+
export const PINNED_RESOURCE_METADATA_PATH_PATTERN = new RegExp(`^/\\.well-known/oauth-protected-resource/(${TARGET_SYSTEM_SEGMENT_SOURCE})/([0-9]{3})/mcp$`);
|
|
11
|
+
export function buildTargetId(sid, client, alias) {
|
|
12
|
+
return `${alias ?? sid}/${client}`;
|
|
13
|
+
}
|
|
14
|
+
export function targetFromPinnedMcpPath(path) {
|
|
15
|
+
const match = path.match(PINNED_MCP_PATH_PATTERN);
|
|
16
|
+
return match ? `${match[1]}/${match[2]}` : undefined;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=multi-target-identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multi-target-identity.js","sourceRoot":"","sources":["../../src/server/multi-target-identity.ts"],"names":[],"mappings":"AAAA,2FAA2F;AAE3F,MAAM,CAAC,MAAM,iBAAiB,GAAG,oBAAoB,CAAC;AAEtD,mFAAmF;AACnF,8EAA8E;AAC9E,kFAAkF;AAClF,MAAM,CAAC,MAAM,4BAA4B,GAAG,8BAA8B,CAAC;AAC3E,MAAM,CAAC,MAAM,2BAA2B,GAAG,IAAI,MAAM,CAAC,IAAI,4BAA4B,GAAG,CAAC,CAAC;AAC3F,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,MAAM,CAAC,IAAI,4BAA4B,YAAY,CAAC,CAAC;AAC1F,MAAM,CAAC,MAAM,uBAAuB,GAAG,IAAI,MAAM,CAAC,MAAM,4BAA4B,mBAAmB,CAAC,CAAC;AACzG,MAAM,CAAC,MAAM,qCAAqC,GAAG,IAAI,MAAM,CAC7D,6CAA6C,4BAA4B,mBAAmB,CAC7F,CAAC;AAEF,MAAM,UAAU,aAAa,CAAC,GAAW,EAAE,MAAc,EAAE,KAAc;IACvE,OAAO,GAAG,KAAK,IAAI,GAAG,IAAI,MAAM,EAAE,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,IAAY;IAClD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAClD,OAAO,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AACvD,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** Per-target configuration construction and uncached Destination drift validation. */
|
|
2
|
+
import type { Destination } from '@arc-mcp/xsuaa-auth/btp';
|
|
3
|
+
import { type TargetDescriptor } from './destination-registry.js';
|
|
4
|
+
import type { ServerConfig } from './types.js';
|
|
5
|
+
/** Build the isolated runtime for one discovered target. */
|
|
6
|
+
export declare function buildMultiTargetConfig(base: ServerConfig, target: TargetDescriptor): ServerConfig;
|
|
7
|
+
/**
|
|
8
|
+
* Build only the union needed to advertise the aggregate tools/list surface.
|
|
9
|
+
* Every tool call replaces this with buildMultiTargetConfig for its selected target.
|
|
10
|
+
*/
|
|
11
|
+
export declare function buildAggregateToolSurfaceConfig(base: ServerConfig, targets: readonly TargetDescriptor[]): ServerConfig;
|
|
12
|
+
export type DriftResult = {
|
|
13
|
+
ok: true;
|
|
14
|
+
url: string;
|
|
15
|
+
} | {
|
|
16
|
+
ok: false;
|
|
17
|
+
code: 'TARGET_CONFIG_CHANGED';
|
|
18
|
+
message: string;
|
|
19
|
+
};
|
|
20
|
+
export declare class TargetConfigChangedError extends Error {
|
|
21
|
+
readonly target: string;
|
|
22
|
+
readonly code = "TARGET_CONFIG_CHANGED";
|
|
23
|
+
constructor(target: string, message: string);
|
|
24
|
+
}
|
|
25
|
+
/** Compare a fresh uncached Find result with the immutable startup snapshot. */
|
|
26
|
+
export declare function validateTargetDrift(destination: Destination, target: TargetDescriptor, base: ServerConfig): DriftResult;
|
|
27
|
+
//# sourceMappingURL=multi-target-runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multi-target-runtime.d.ts","sourceRoot":"","sources":["../../src/server/multi-target-runtime.ts"],"names":[],"mappings":"AAAA,uFAAuF;AAEvF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D,OAAO,EAGL,KAAK,gBAAgB,EAEtB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAyE/C,4DAA4D;AAC5D,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,gBAAgB,GAAG,YAAY,CAEjG;AAED;;;GAGG;AACH,wBAAgB,+BAA+B,CAC7C,IAAI,EAAE,YAAY,EAClB,OAAO,EAAE,SAAS,gBAAgB,EAAE,GACnC,YAAY,CAQd;AAED,MAAM,MAAM,WAAW,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,uBAAuB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpH,qBAAa,wBAAyB,SAAQ,KAAK;IAI/C,QAAQ,CAAC,MAAM,EAAE,MAAM;IAHzB,QAAQ,CAAC,IAAI,2BAA2B;IAExC,YACW,MAAM,EAAE,MAAM,EACvB,OAAO,EAAE,MAAM,EAIhB;CACF;AAUD,gFAAgF;AAChF,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,gBAAgB,EACxB,IAAI,EAAE,YAAY,GACjB,WAAW,CAQb"}
|