Skip to content

Commit 2e319d6

Browse files
more consistent return structure
1 parent be83148 commit 2e319d6

15 files changed

+169
-149
lines changed

src/handlers/AtcHandlers.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ export class AtcHandlers extends BaseHandler {
109109
type: 'object',
110110
properties: {
111111
proposal: {
112-
type: 'object',
112+
type: 'string',
113113
description: 'The ATC exemption proposal.'
114114
}
115115
},

src/handlers/BaseHandler.ts

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -24,41 +24,6 @@ export abstract class BaseHandler {
2424
this.adtclient = adtclient;
2525
}
2626

27-
protected validateArgs(args: any, schema: {
28-
type: string;
29-
properties: Record<string, any>;
30-
required?: string[];
31-
}): void {
32-
const errors: string[] = [];
33-
34-
// Validate type
35-
if (schema.type && typeof args !== schema.type) {
36-
errors.push(`Expected ${schema.type} but got ${typeof args}`);
37-
}
38-
39-
// Validate properties
40-
if (schema.properties) {
41-
for (const [key, propSchema] of Object.entries(schema.properties)) {
42-
if (args[key] === undefined && schema.required?.includes(key)) {
43-
errors.push(`Missing required property: ${key}`);
44-
continue;
45-
}
46-
47-
if (args[key] !== undefined && typeof args[key] !== propSchema.type) {
48-
errors.push(`Property ${key} expected ${propSchema.type} but got ${typeof args[key]}`);
49-
}
50-
}
51-
}
52-
53-
if (errors.length > 0) {
54-
this.logger.warn('Validation failed', { errors });
55-
throw new McpError(
56-
CustomErrorCode.InvalidParameters,
57-
`Invalid arguments: ${errors.join(', ')}`
58-
);
59-
}
60-
}
61-
6227
protected trackRequest(startTime: number, success: boolean): void {
6328
const duration = performance.now() - startTime;
6429
this.metrics.requestCount++;

src/handlers/CodeAnalysisHandlers.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ export class CodeAnalysisHandlers extends BaseHandler {
155155
inputSchema: {
156156
type: 'object',
157157
properties: {
158-
proposal: { type: 'object' },
158+
proposal: { type: 'string' },
159159
source: { type: 'string' }
160160
},
161161
required: ['proposal', 'source']
@@ -253,7 +253,7 @@ export class CodeAnalysisHandlers extends BaseHandler {
253253
async handleSyntaxCheckCode(args: any): Promise<any> {
254254
const startTime = performance.now();
255255
try {
256-
const result = await this.adtclient.syntaxCheck(args.url, args.mainUrl, args.code, args.mainProgram, args.version);
256+
const result = await this.adtclient.syntaxCheck(args.url, args?.mainUrl, args?.code, args?.mainProgram, args?.version);
257257
this.trackRequest(startTime, true);
258258
return {
259259
content: [

src/handlers/DebugHandlers.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ export class DebugHandlers extends BaseHandler {
160160
type: 'object',
161161
properties: {
162162
breakpoint: {
163-
type: 'object',
163+
type: 'string',
164164
description: 'The breakpoint to delete.'
165165
},
166166
debuggingMode: {
@@ -222,7 +222,7 @@ export class DebugHandlers extends BaseHandler {
222222
type: 'object',
223223
properties: {
224224
settings: {
225-
type: 'object',
225+
type: 'string',
226226
description: 'The debugger settings.'
227227
}
228228
},

src/handlers/GitHandlers.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ export class GitHandlers extends BaseHandler {
131131
type: 'object',
132132
properties: {
133133
repo: {
134-
type: 'object',
134+
type: 'string',
135135
description: 'The Git repository.'
136136
},
137137
user: {
@@ -155,11 +155,11 @@ export class GitHandlers extends BaseHandler {
155155
type: 'object',
156156
properties: {
157157
repo: {
158-
type: 'object',
158+
type: 'string',
159159
description: 'The Git repository.'
160160
},
161161
staging: {
162-
type: 'object',
162+
type: 'string',
163163
description: 'The staging information.'
164164
},
165165
user: {
@@ -183,7 +183,7 @@ export class GitHandlers extends BaseHandler {
183183
type: 'object',
184184
properties: {
185185
repo: {
186-
type: 'object',
186+
type: 'string',
187187
description: 'The Git repository.'
188188
},
189189
user: {
@@ -207,7 +207,7 @@ export class GitHandlers extends BaseHandler {
207207
type: 'object',
208208
properties: {
209209
repo: {
210-
type: 'object',
210+
type: 'string',
211211
description: 'The Git repository.'
212212
},
213213
user: {
@@ -231,7 +231,7 @@ export class GitHandlers extends BaseHandler {
231231
type: 'object',
232232
properties: {
233233
repo: {
234-
type: 'object',
234+
type: 'string',
235235
description: 'The Git repository.'
236236
},
237237
branch: {

src/handlers/ObjectManagementHandlers.ts

Lines changed: 140 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,86 @@ import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js";
22
import { BaseHandler } from './BaseHandler';
33
import type { ToolDefinition } from '../types/tools';
44

5+
interface InactiveObject {
6+
"adtcore:uri": string;
7+
"adtcore:type": string;
8+
"adtcore:name": string;
9+
"adtcore:parentUri": string;
10+
}
11+
12+
interface ActivationResultMessage {
13+
objDescr: string;
14+
type: string;
15+
line: number;
16+
href: string;
17+
forceSupported: boolean;
18+
shortText: string;
19+
}
20+
21+
interface ActivationResult {
22+
success: boolean;
23+
messages: ActivationResultMessage[];
24+
inactive: InactiveObjectRecord[];
25+
}
26+
27+
interface InactiveObjectElement extends InactiveObject {
28+
user: string;
29+
deleted: boolean;
30+
}
31+
32+
interface InactiveObjectRecord {
33+
object?: InactiveObjectElement;
34+
transport?: InactiveObjectElement;
35+
}
36+
537
export class ObjectManagementHandlers extends BaseHandler {
638
getTools(): ToolDefinition[] {
739
return [
840
{
9-
name: 'activate',
10-
description: 'Activate ABAP objects',
41+
name: 'activateObjects',
42+
description: 'Activate ABAP objects using object references',
1143
inputSchema: {
1244
type: 'object',
1345
properties: {
14-
object: {
15-
type: "object",
16-
description: 'Single object or array of objects to activate'
46+
objects: {
47+
type: 'string',
48+
description: 'JSON array of objects to activate. Each object must have adtcore:uri, adtcore:type, adtcore:name, and adtcore:parentUri properties'
1749
},
18-
preauditRequested: {
50+
preauditRequested: {
1951
type: 'boolean',
2052
description: 'Whether to perform pre-audit checks',
2153
optional: true
2254
}
2355
},
24-
required: ['object']
56+
required: ['objects']
57+
}
58+
},
59+
{
60+
name: 'activateByName',
61+
description: 'Activate an ABAP object using name and URL',
62+
inputSchema: {
63+
type: 'object',
64+
properties: {
65+
objectName: {
66+
type: 'string',
67+
description: 'Name of the object'
68+
},
69+
objectUrl: {
70+
type: 'string',
71+
description: 'URL of the object'
72+
},
73+
mainInclude: {
74+
type: 'string',
75+
description: 'Main include context',
76+
optional: true
77+
},
78+
preauditRequested: {
79+
type: 'boolean',
80+
description: 'Whether to perform pre-audit checks',
81+
optional: true
82+
}
83+
},
84+
required: ['objectName', 'objectUrl']
2585
}
2686
},
2787
{
@@ -34,44 +94,93 @@ export class ObjectManagementHandlers extends BaseHandler {
3494
}
3595
];
3696
}
97+
3798
async handle(toolName: string, args: any): Promise<any> {
3899
switch (toolName) {
39-
case 'activate':
40-
return this.handleActivate(args);
100+
case 'activateObjects':
101+
return this.handleActivateObjects(args);
102+
case 'activateByName':
103+
return this.handleActivateByName(args);
41104
case 'inactiveObjects':
42105
return this.handleInactiveObjects(args);
43106
default:
44107
throw new McpError(ErrorCode.MethodNotFound, `Unknown object management tool: ${toolName}`);
45108
}
46109
}
47110

48-
async handleActivate(args: any): Promise<any> {
49-
this.validateArgs(args, {
50-
type: 'object',
51-
properties: {
52-
object: {
53-
type: "object"
54-
},
55-
preauditRequested: { type: 'boolean' }
56-
},
57-
required: ['object']
58-
});
59-
111+
async handleActivateObjects(args: any): Promise<any> {
60112
const startTime = performance.now();
61113
try {
62-
const result = await this.adtclient.activate(args.object, args.preauditRequested);
114+
if (!args.objects || typeof args.objects !== 'string') {
115+
throw new McpError(ErrorCode.InvalidParams, "objects parameter must be a JSON string");
116+
}
117+
118+
let objects: InactiveObject[];
119+
try {
120+
objects = JSON.parse(args.objects);
121+
if (!Array.isArray(objects)) {
122+
throw new Error("Parsed objects must be an array");
123+
}
124+
125+
// Validate each object has required properties
126+
objects.forEach((obj, index) => {
127+
if (!obj["adtcore:uri"] || !obj["adtcore:type"] ||
128+
!obj["adtcore:name"] || !obj["adtcore:parentUri"]) {
129+
throw new Error(`Object at index ${index} is missing required properties`);
130+
}
131+
});
132+
} catch (parseError: any) {
133+
throw new McpError(
134+
ErrorCode.InvalidParams,
135+
`Invalid objects JSON: ${parseError.message}`
136+
);
137+
}
138+
139+
const result = await this.adtclient.activate(objects, args.preauditRequested);
63140
this.trackRequest(startTime, true);
64141
return {
65142
content: [{
66143
type: 'text',
67-
text: JSON.stringify({
68-
status: 'success',
69-
result
70-
})
144+
text: JSON.stringify(result)
71145
}]
72146
};
73147
} catch (error: any) {
74148
this.trackRequest(startTime, false);
149+
if (error instanceof McpError) {
150+
throw error;
151+
}
152+
throw new McpError(
153+
ErrorCode.InternalError,
154+
`Failed to activate objects: ${error.message || 'Unknown error'}`
155+
);
156+
}
157+
}
158+
159+
async handleActivateByName(args: any): Promise<any> {
160+
const startTime = performance.now();
161+
try {
162+
if (!args.objectName || !args.objectUrl) {
163+
throw new McpError(ErrorCode.InvalidParams, "objectName and objectUrl parameters are required");
164+
}
165+
166+
const result = await this.adtclient.activate(
167+
args.objectName,
168+
args.objectUrl,
169+
args.mainInclude,
170+
args.preauditRequested
171+
);
172+
this.trackRequest(startTime, true);
173+
return {
174+
content: [{
175+
type: 'text',
176+
text: JSON.stringify(result)
177+
}]
178+
};
179+
} catch (error: any) {
180+
this.trackRequest(startTime, false);
181+
if (error instanceof McpError) {
182+
throw error;
183+
}
75184
throw new McpError(
76185
ErrorCode.InternalError,
77186
`Failed to activate object: ${error.message || 'Unknown error'}`
@@ -80,27 +189,21 @@ export class ObjectManagementHandlers extends BaseHandler {
80189
}
81190

82191
async handleInactiveObjects(args: any): Promise<any> {
83-
this.validateArgs(args, {
84-
type: 'object',
85-
properties: {},
86-
required: []
87-
});
88-
89192
const startTime = performance.now();
90193
try {
91-
const result = await this.adtclient.inactiveObjects();
194+
const result: InactiveObjectRecord[] = await this.adtclient.inactiveObjects();
92195
this.trackRequest(startTime, true);
93196
return {
94197
content: [{
95198
type: 'text',
96-
text: JSON.stringify({
97-
status: 'success',
98-
result
99-
})
199+
text: JSON.stringify(result)
100200
}]
101201
};
102202
} catch (error: any) {
103203
this.trackRequest(startTime, false);
204+
if (error instanceof McpError) {
205+
throw error;
206+
}
104207
throw new McpError(
105208
ErrorCode.InternalError,
106209
`Failed to get inactive objects: ${error.message || 'Unknown error'}`

0 commit comments

Comments
 (0)