Skip to content

Commit 5fbb860

Browse files
CopilotThePlenkov
andauthored
feat: add package CRUD and object CRUD commands (class, program, interface)
Agent-Logs-Url: https://github.com/abapify/adt-cli/sessions/b58ce1f9-9bbb-4ab0-b740-3c2f096ef999 Co-authored-by: ThePlenkov <6381507+ThePlenkov@users.noreply.github.com>
1 parent cfd8b70 commit 5fbb860

16 files changed

Lines changed: 1318 additions & 5 deletions

File tree

packages/adk/src/objects/repository/clas/clas.model.ts

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,13 +289,80 @@ export class AdkClass extends AdkMainObject<typeof ClassKind, ClassXml> {
289289
}
290290

291291
// ============================================
292-
// Static Factory Method
292+
// Static Factory Methods
293293
// ============================================
294294

295295
static async get(name: string, ctx?: AdkContext): Promise<AdkClass> {
296296
const context = ctx ?? getGlobalContext();
297297
return new AdkClass(context, name).load();
298298
}
299+
300+
/**
301+
* Check if a class exists on SAP
302+
*/
303+
static async exists(name: string, ctx?: AdkContext): Promise<boolean> {
304+
try {
305+
await AdkClass.get(name, ctx);
306+
return true;
307+
} catch {
308+
return false;
309+
}
310+
}
311+
312+
/**
313+
* Create a new ABAP class on SAP
314+
*
315+
* @param name - Class name (e.g., 'ZCL_MY_CLASS')
316+
* @param description - Short description
317+
* @param packageName - Package to assign the class to
318+
* @param options - Save options (transport)
319+
* @param ctx - Optional ADK context
320+
*/
321+
static async create(
322+
name: string,
323+
description: string,
324+
packageName: string,
325+
options?: { transport?: string },
326+
ctx?: AdkContext,
327+
): Promise<AdkClass> {
328+
const context = ctx ?? getGlobalContext();
329+
const cls = new AdkClass(context, name.toUpperCase());
330+
cls.setData({
331+
name: name.toUpperCase(),
332+
type: 'CLAS/OC',
333+
description,
334+
language: 'EN',
335+
masterLanguage: 'EN',
336+
packageRef: {
337+
name: packageName.toUpperCase(),
338+
uri: `/sap/bc/adt/packages/${encodeURIComponent(packageName.toUpperCase())}`,
339+
type: 'DEVC/K',
340+
},
341+
} as unknown as ClassXml);
342+
await cls.save({ transport: options?.transport, mode: 'create' });
343+
return cls;
344+
}
345+
346+
/**
347+
* Delete an ABAP class from SAP
348+
*
349+
* @param name - Class name
350+
* @param options - Delete options (transport)
351+
* @param ctx - Optional ADK context
352+
*/
353+
static async delete(
354+
name: string,
355+
options?: { transport?: string; lockHandle?: string },
356+
ctx?: AdkContext,
357+
): Promise<void> {
358+
const context = ctx ?? getGlobalContext();
359+
const cls = new AdkClass(context, name.toUpperCase());
360+
const contract = cls.crudContract;
361+
await contract.delete(name.toUpperCase(), {
362+
corrNr: options?.transport,
363+
lockHandle: options?.lockHandle,
364+
});
365+
}
299366
}
300367

301368
// Self-register with ADK registry

packages/adk/src/objects/repository/devc/devc.model.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,26 @@ export class AdkPackage
341341
await pkg.save({ transport: options?.transport, mode: 'create' });
342342
return pkg;
343343
}
344+
345+
/**
346+
* Delete an ABAP package from SAP
347+
*
348+
* @param name - Package name
349+
* @param options - Delete options (transport, lockHandle)
350+
* @param ctx - Optional ADK context (uses global context if not provided)
351+
*/
352+
static async delete(
353+
name: string,
354+
options?: { transport?: string; lockHandle?: string },
355+
ctx?: AdkContext,
356+
): Promise<void> {
357+
const context = ctx ?? getGlobalContext();
358+
const pkg = new AdkPackage(context, name.toUpperCase());
359+
await pkg.crudContract.delete(name.toUpperCase(), {
360+
...(options?.transport && { corrNr: options.transport }),
361+
...(options?.lockHandle && { lockHandle: options.lockHandle }),
362+
});
363+
}
344364
}
345365

346366
// Self-register with ADK registry

packages/adk/src/objects/repository/intf/intf.model.ts

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,80 @@ export class AdkInterface extends AdkMainObject<
6565
}
6666

6767
// ============================================
68-
// Static Factory Method
68+
// Static Factory Methods
6969
// ============================================
7070

7171
static async get(name: string, ctx?: AdkContext): Promise<AdkInterface> {
7272
const context = ctx ?? getGlobalContext();
7373
return new AdkInterface(context, name).load();
7474
}
75+
76+
/**
77+
* Check if an interface exists on SAP
78+
*/
79+
static async exists(name: string, ctx?: AdkContext): Promise<boolean> {
80+
try {
81+
await AdkInterface.get(name, ctx);
82+
return true;
83+
} catch {
84+
return false;
85+
}
86+
}
87+
88+
/**
89+
* Create a new ABAP interface on SAP
90+
*
91+
* @param name - Interface name (e.g., 'ZIF_MY_INTERFACE')
92+
* @param description - Short description
93+
* @param packageName - Package to assign the interface to
94+
* @param options - Save options (transport)
95+
* @param ctx - Optional ADK context
96+
*/
97+
static async create(
98+
name: string,
99+
description: string,
100+
packageName: string,
101+
options?: { transport?: string },
102+
ctx?: AdkContext,
103+
): Promise<AdkInterface> {
104+
const context = ctx ?? getGlobalContext();
105+
const intf = new AdkInterface(context, name.toUpperCase());
106+
intf.setData({
107+
name: name.toUpperCase(),
108+
type: 'INTF/OI',
109+
description,
110+
language: 'EN',
111+
masterLanguage: 'EN',
112+
packageRef: {
113+
name: packageName.toUpperCase(),
114+
uri: `/sap/bc/adt/packages/${encodeURIComponent(packageName.toUpperCase())}`,
115+
type: 'DEVC/K',
116+
},
117+
} as unknown as InterfaceXml);
118+
await intf.save({ transport: options?.transport, mode: 'create' });
119+
return intf;
120+
}
121+
122+
/**
123+
* Delete an ABAP interface from SAP
124+
*
125+
* @param name - Interface name
126+
* @param options - Delete options (transport)
127+
* @param ctx - Optional ADK context
128+
*/
129+
static async delete(
130+
name: string,
131+
options?: { transport?: string; lockHandle?: string },
132+
ctx?: AdkContext,
133+
): Promise<void> {
134+
const context = ctx ?? getGlobalContext();
135+
const intf = new AdkInterface(context, name.toUpperCase());
136+
const contract = intf.crudContract;
137+
await contract.delete(name.toUpperCase(), {
138+
corrNr: options?.transport,
139+
lockHandle: options?.lockHandle,
140+
});
141+
}
75142
}
76143

77144
// Self-register with ADK registry

packages/adk/src/objects/repository/prog/prog.model.ts

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,80 @@ export class AdkProgram extends AdkMainObject<typeof ProgramKind, ProgramXml> {
6565
}
6666

6767
// ============================================
68-
// Static Factory Method
68+
// Static Factory Methods
6969
// ============================================
7070

7171
static async get(name: string, ctx?: AdkContext): Promise<AdkProgram> {
7272
const context = ctx ?? getGlobalContext();
7373
return new AdkProgram(context, name).load();
7474
}
75+
76+
/**
77+
* Check if a program exists on SAP
78+
*/
79+
static async exists(name: string, ctx?: AdkContext): Promise<boolean> {
80+
try {
81+
await AdkProgram.get(name, ctx);
82+
return true;
83+
} catch {
84+
return false;
85+
}
86+
}
87+
88+
/**
89+
* Create a new ABAP program on SAP
90+
*
91+
* @param name - Program name (e.g., 'ZMYPROGRAM')
92+
* @param description - Short description
93+
* @param packageName - Package to assign the program to
94+
* @param options - Save options (transport)
95+
* @param ctx - Optional ADK context
96+
*/
97+
static async create(
98+
name: string,
99+
description: string,
100+
packageName: string,
101+
options?: { transport?: string },
102+
ctx?: AdkContext,
103+
): Promise<AdkProgram> {
104+
const context = ctx ?? getGlobalContext();
105+
const prog = new AdkProgram(context, name.toUpperCase());
106+
prog.setData({
107+
name: name.toUpperCase(),
108+
type: 'PROG/P',
109+
description,
110+
language: 'EN',
111+
masterLanguage: 'EN',
112+
packageRef: {
113+
name: packageName.toUpperCase(),
114+
uri: `/sap/bc/adt/packages/${encodeURIComponent(packageName.toUpperCase())}`,
115+
type: 'DEVC/K',
116+
},
117+
} as unknown as ProgramXml);
118+
await prog.save({ transport: options?.transport, mode: 'create' });
119+
return prog;
120+
}
121+
122+
/**
123+
* Delete an ABAP program from SAP
124+
*
125+
* @param name - Program name
126+
* @param options - Delete options (transport)
127+
* @param ctx - Optional ADK context
128+
*/
129+
static async delete(
130+
name: string,
131+
options?: { transport?: string; lockHandle?: string },
132+
ctx?: AdkContext,
133+
): Promise<void> {
134+
const context = ctx ?? getGlobalContext();
135+
const prog = new AdkProgram(context, name.toUpperCase());
136+
const contract = prog.crudContract;
137+
await contract.delete(name.toUpperCase(), {
138+
corrNr: options?.transport,
139+
lockHandle: options?.lockHandle,
140+
});
141+
}
75142
}
76143

77144
// Self-register with ADK registry

packages/adt-cli/src/lib/cli.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ import {
2727
userCommand,
2828
sourceCommand,
2929
} from './commands';
30+
import { createPackageCommand } from './commands/package';
31+
import {
32+
classCommand,
33+
programCommand,
34+
interfaceCommand,
35+
} from './commands/object';
3036
import { refreshCommand } from './commands/auth/refresh';
3137
// Deploy command moved to @abapify/adt-export plugin
3238
// Add '@abapify/adt-export/commands/export' to adt.config.ts commands array to enable
@@ -175,9 +181,12 @@ export async function createCLI(options?: {
175181
// Object inspector command
176182
program.addCommand(getCommand);
177183

178-
// Get subcommands for specific object types
184+
// Get subcommands for specific object types (legacy: adt get package <name>)
179185
getCommand.addCommand(packageGetCommand);
180186

187+
// Package commands (adt package create/list/delete/activate/stat/get)
188+
program.addCommand(createPackageCommand());
189+
181190
// ATC (ABAP Test Cockpit) command - now loaded as plugin from @abapify/adt-atc
182191
// Add '@abapify/adt-atc/commands/atc' to adt.config.ts commands array to enable
183192

@@ -225,6 +234,11 @@ export async function createCLI(options?: {
225234
// User lookup command
226235
program.addCommand(userCommand);
227236

237+
// Object CRUD commands (class, program, interface)
238+
program.addCommand(classCommand);
239+
program.addCommand(programCommand);
240+
program.addCommand(interfaceCommand);
241+
228242
// REPL - Interactive hypermedia navigator
229243
program.addCommand(createReplCommand());
230244

0 commit comments

Comments
 (0)