Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const exec = promisify(execAsync);
* @returns Application generation execution output.
*/
export async function command(params: ExecuteFunctionalityInput): Promise<ExecuteFunctionalityOutput> {
const generatorConfigCAP: GeneratorConfigCAP = validateWithSchema(GeneratorConfigSchemaCAP, params?.parameters);
const generatorConfigCAP: GeneratorConfigCAP = validateWithSchema(GeneratorConfigSchemaCAP(), params?.parameters);
const generatorConfig: GeneratorConfigCAPWithAPI = {
...PREDEFINED_GENERATOR_VALUES,
...generatorConfigCAP,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type {
ExecuteFunctionalityInput,
ExecuteFunctionalityOutput,
FunctionalityHandlers,
GetFunctionalityDetailsInput,
GetFunctionalityDetailsOutput
} from '../../../types';
import { convertToSchema } from '../../utils';
Expand All @@ -18,16 +19,21 @@ export const GENERATE_FIORI_UI_APP: GetFunctionalityDetailsOutput = {
The data obtained from either method must then be formatted into a JSON object and passed as the parameters.
The configuration **MUST** be a valid JSON object corresponding to the inputSchema of the tool.
The configuration **MUST** be based on the project files in the projectPath.`,
parameters: convertToSchema(GeneratorConfigSchemaCAP)
parameters: convertToSchema(GeneratorConfigSchemaCAP())
};

/**
* Retrieves the details of the Generate SAP Fiori UI Application functionality.
*
* @param input
* @returns A promise that resolves to the functionality details output.
*/
async function getFunctionalityDetails(): Promise<GetFunctionalityDetailsOutput> {
return GENERATE_FIORI_UI_APP;
async function getFunctionalityDetails(input: GetFunctionalityDetailsInput): Promise<GetFunctionalityDetailsOutput> {
const details = GENERATE_FIORI_UI_APP;
return {
...details,
parameters: convertToSchema(GeneratorConfigSchemaCAP(input.appPath))
};
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,70 +1,74 @@
import { LATEST_UI5_VERSION } from '../../../constant';
import * as z from 'zod';

export const GeneratorConfigSchemaCAP = z.object({
floorplan: z
.literal(['FE_LROP', 'FE_FEOP', 'FE_FPM', 'FE_OVP', 'FE_ALP', 'FE_WORKLIST', 'FF_SIMPLE'])
.describe('SAP Fiori Elements floor plan type.'),
project: z.object({
name: z
.string()
.describe("Must be lowercase with dashes, e.g., 'sales-order-management'.")
.regex(/^[a-z0-9-]+$/),
targetFolder: z.string().describe('Absolute path to the CAP project folder (projectPath).'),
namespace: z.optional(z.string()),
title: z.optional(z.string()),
description: z.string(),
ui5Theme: z.optional(z.string()),
ui5Version: z.string().default(LATEST_UI5_VERSION),
localUI5Version: z.optional(z.string()).default(LATEST_UI5_VERSION)
}),
service: z.object({
servicePath: z
.string()
.describe(
'The odata endpoint as provided by the cds mcp or as fallback in case that tool is not available from the service cds file.'
)
.meta({
examples: [
'/odata/v4/<servicename>/',
'/odata/v4/MyRiskService/',
'/odata/v2/MyOdataV2Service/',
'/odata/v4/MyOdataV4Service/',
"/odata/v4/<relative '@path' annotation from service cds file>/",
"<absolute '@path' annotation from service cds file>/",
'/myAbsolutePathFromServiceCdsFile/'
]
}),
capService: z.object({
projectPath: z.string(),
serviceName: z.string(),
serviceCdsPath: z
export const GeneratorConfigSchemaCAP = (projectPath?: string) => {
return z.object({
floorplan: z
.literal(['FE_LROP', 'FE_FEOP', 'FE_FPM', 'FE_OVP', 'FE_ALP', 'FE_WORKLIST', 'FF_SIMPLE'])
.describe('SAP Fiori Elements floor plan type.'),
project: z.object({
name: z
.string()
.describe("Must be lowercase with dashes, e.g., 'sales-order-management'.")
.regex(/^[a-z0-9-]+$/),
targetFolder: z
.string()
.describe('The path to the service cds file')
.describe(`Absolute path to the CAP project folder (${projectPath ?? 'project path'}).`),
namespace: z.optional(z.string()),
title: z.optional(z.string()),
description: z.string(),
ui5Theme: z.optional(z.string()),
ui5Version: z.string().default(LATEST_UI5_VERSION),
localUI5Version: z.optional(z.string()).default(LATEST_UI5_VERSION)
}),
service: z.object({
servicePath: z
.string()
.describe(
'The odata endpoint as provided by the cds mcp or as fallback in case that tool is not available from the service cds file.'
)
.meta({
examples: [
'srv/service.cds',
'srv/my-service.cds',
'path/to/srv/service.cds',
'path/to/srv/my-service.cds'
'/odata/v4/<servicename>/',
'/odata/v4/MyRiskService/',
'/odata/v2/MyOdataV2Service/',
'/odata/v4/MyOdataV4Service/',
"/odata/v4/<relative '@path' annotation from service cds file>/",
"<absolute '@path' annotation from service cds file>/",
'/myAbsolutePathFromServiceCdsFile/'
]
}),
capType: z.optional(z.literal(['Node.js', 'Java']))
})
}),
entityConfig: z.object({
mainEntity: z.object({
entityName: z
.string()
.describe('The name of the main entity')
.meta({
examples: ["'SalesOrder'", "'PurchaseOrderHeader'", "'MyEntity'"]
})
capService: z.object({
projectPath: z.string(),
serviceName: z.string(),
serviceCdsPath: z
.string()
.describe('The path to the service cds file')
.meta({
examples: [
'srv/service.cds',
'srv/my-service.cds',
'path/to/srv/service.cds',
'path/to/srv/my-service.cds'
]
}),
capType: z.optional(z.literal(['Node.js', 'Java']))
})
}),
generateFormAnnotations: z.boolean(),
generateLROPAnnotations: z.boolean()
})
});
entityConfig: z.object({
mainEntity: z.object({
entityName: z
.string()
.describe('The name of the main entity')
.meta({
examples: ["'SalesOrder'", "'PurchaseOrderHeader'", "'MyEntity'"]
})
}),
generateFormAnnotations: z.boolean(),
generateLROPAnnotations: z.boolean()
})
});
};

// Input type for generator config
export type GeneratorConfigCAP = z.infer<typeof GeneratorConfigSchemaCAP>;
export type GeneratorConfigCAP = z.infer<ReturnType<typeof GeneratorConfigSchemaCAP>>;
Loading