diff --git a/packages/salesforcedx-vscode-apex/src/commands/apexActionController.ts b/packages/salesforcedx-vscode-apex/src/commands/apexActionController.ts index 31548b65d0..a301d45bfc 100644 --- a/packages/salesforcedx-vscode-apex/src/commands/apexActionController.ts +++ b/packages/salesforcedx-vscode-apex/src/commands/apexActionController.ts @@ -17,7 +17,8 @@ import { nls } from '../messages'; import { ApexClassOASEligibleResponse, ApexClassOASGatherContextResponse, - ApexOASInfo + ApexOASInfo, + ExternalServiceOperation } from '../openApiUtilities/schemas'; import { getTelemetryService } from '../telemetry/telemetry'; import { MetadataOrchestrator } from './metadataOrchestrator'; @@ -244,6 +245,7 @@ export class ApexActionController { const baseName = path.basename(fullPath).split('.')[0]; const safeOasSpec = oasSpec.replaceAll('"', ''').replaceAll('type: Id', 'type: string'); const { description, version } = this.extractInfoProperties(safeOasSpec); + const operations = this.getOperationsFromYaml(safeOasSpec); const orgVersion = await (await WorkspaceContextUtil.getInstance().getConnection()).retrieveMaxApiVersion(); if (!orgVersion) { throw new Error(nls.localize('error_retrieving_org_version')); @@ -258,7 +260,12 @@ export class ApexActionController { if (jsonObj.ExternalServiceRegistration?.schema) { jsonObj.ExternalServiceRegistration.schema = safeOasSpec; } else { - throw new Error('schema_element_not_found'); + throw new Error(nls.localize('schema_element_not_found')); + } + if (jsonObj.ExternalServiceRegistration?.operations?.ExternalServiceOperation) { + jsonObj.ExternalServiceRegistration.operations.ExternalServiceOperation = operations; + } else { + throw new Error(nls.localize('operations_element_not_found')); } } else { // Create a new XML structure @@ -274,6 +281,9 @@ export class ApexActionController { schemaUploadFileName: `${baseName.toLowerCase()}_openapi`, status: 'Complete', systemVersion: '3', + operations: { + ExternalServiceOperation: operations + }, registrationProvider: baseName, ...(this.isVersionGte(orgVersion, '63.0') // Guarded inclusion for API version 254 and above (instance api version 63.0 and above) ? { @@ -309,9 +319,26 @@ export class ApexActionController { if (!parsed?.info?.description || !parsed?.info?.version) { throw new Error(nls.localize('error_parsing_yaml')); } + return { description: parsed?.info?.description, version: parsed?.info?.version }; }; + private getOperationsFromYaml = (oasSpec: string): ExternalServiceOperation[] => { + const parsed = parse(oasSpec); + if (!parsed?.paths) { + throw new Error(nls.localize('error_parsing_yaml')); + } + const operations = parsed.paths + ? Object.keys(parsed.paths).flatMap(p => + Object.keys(parsed.paths[p]).map(operation => ({ + name: parsed.paths[p][operation].operationId, + active: true + })) + ) + : []; + + return operations; + }; } diff --git a/packages/salesforcedx-vscode-apex/src/commands/metadataOrchestrator.ts b/packages/salesforcedx-vscode-apex/src/commands/metadataOrchestrator.ts index cbbf311d17..f607b571b8 100644 --- a/packages/salesforcedx-vscode-apex/src/commands/metadataOrchestrator.ts +++ b/packages/salesforcedx-vscode-apex/src/commands/metadataOrchestrator.ts @@ -203,7 +203,7 @@ export class MetadataOrchestrator { Ensure no sensitive details are included. Decline requests unrelated to OpenAPI v3 specs or asking for sensitive information.`; const userPrompt = - 'Generate an OpenAPI v3 specification for the following Apex class. The OpenAPI v3 specification should be a YAML file. The paths should be in the format of /{ClassName}/{MethodName} for all the @AuraEnabled methods specified. For every `type: object`, generate a `#/components/schemas` entry for that object. The method should have a $ref entry pointing to the generated `#/components/schemas` entry. Only include methods that have the @AuraEnabled annotation in the paths of the OpenAPI v3 specification. I do not want AUTHOR_PLACEHOLDER in the result. Do not forget info.description property'; + 'Generate an OpenAPI v3 specification for the following Apex class. The OpenAPI v3 specification should be a YAML file. The paths should be in the format of /{ClassName}/{MethodName} for all the @AuraEnabled methods specified. For every `type: object`, generate a `#/components/schemas` entry for that object. The method should have a $ref entry pointing to the generated `#/components/schemas` entry. Only include methods that have the @AuraEnabled annotation in the paths of the OpenAPI v3 specification. I do not want AUTHOR_PLACEHOLDER in the result. Do not forget info.description property. For each path, you define operations (HTTP methods) that can be used to access that path. Make sure that each operation includes a mandatory operationId property, which should be a unique string matching the operations name.'; const systemTag = '<|system|>'; const endOfPromptTag = '<|endofprompt|>'; diff --git a/packages/salesforcedx-vscode-apex/src/messages/i18n.ja.ts b/packages/salesforcedx-vscode-apex/src/messages/i18n.ja.ts index d106baf7f0..735ea09128 100644 --- a/packages/salesforcedx-vscode-apex/src/messages/i18n.ja.ts +++ b/packages/salesforcedx-vscode-apex/src/messages/i18n.ja.ts @@ -101,6 +101,7 @@ export const messages = { registry_access_failed: 'Failed to retrieve ESR directory name from the registry.', full_path_failed: 'Failed to determine the full path for the OpenAPI document.', schema_element_not_found: 'The element was not found in the provided XML.', + operations_element_not_found: 'The element was not found in the provided XML.', error_retrieving_org_version: 'Failed to retrieve org version', error_parsing_yaml: 'Error parsing YAML' }; diff --git a/packages/salesforcedx-vscode-apex/src/messages/i18n.ts b/packages/salesforcedx-vscode-apex/src/messages/i18n.ts index de459aefab..e1f1cebe6d 100644 --- a/packages/salesforcedx-vscode-apex/src/messages/i18n.ts +++ b/packages/salesforcedx-vscode-apex/src/messages/i18n.ts @@ -121,6 +121,7 @@ export const messages = { registry_access_failed: 'Failed to retrieve ESR directory name from the registry.', full_path_failed: 'Failed to determine the full path for the OpenAPI document.', schema_element_not_found: 'The element was not found in the provided XML.', + operations_element_not_found: 'The element was not found in the provided XML.', error_retrieving_org_version: 'Failed to retrieve org version', error_parsing_yaml: 'Error parsing YAML' }; diff --git a/packages/salesforcedx-vscode-apex/src/openApiUtilities/schemas.ts b/packages/salesforcedx-vscode-apex/src/openApiUtilities/schemas.ts index 7ab084cfb6..db07931df4 100644 --- a/packages/salesforcedx-vscode-apex/src/openApiUtilities/schemas.ts +++ b/packages/salesforcedx-vscode-apex/src/openApiUtilities/schemas.ts @@ -83,6 +83,11 @@ export type ApexOASInfo = { description: string; version: string; }; + +export type ExternalServiceOperation = { + name: string; + active: boolean; +}; // export interface ApexClassOASFilter { // modifiers: string[] | null; // }