1+ import { randomUUID } from 'crypto' ;
12import { ServerRequestHandler } from 'vscode-languageserver' ;
3+ import { RequestHandler } from 'vscode-languageserver/node' ;
4+ import { TopLevelSection } from '../context/ContextType' ;
5+ import { getEntityMap } from '../context/SectionContextBuilder' ;
26import {
37 ResourceTypesResult ,
48 ListResourcesParams ,
@@ -12,6 +16,7 @@ import {
1216} from '../resourceState/ResourceStateTypes' ;
1317import { ResourceStackManagementResult } from '../resourceState/StackManagementInfoProvider' ;
1418import { ServerComponents } from '../server/ServerComponents' ;
19+ import { GetStackTemplateParams , GetStackTemplateResult } from '../stacks/StackRequestType' ;
1520import { LoggerFactory } from '../telemetry/LoggerFactory' ;
1621import { extractErrorMessage } from '../utils/Errors' ;
1722
@@ -96,3 +101,63 @@ export function getStackMgmtInfo(
96101 return await components . stackManagementInfoProvider . getResourceManagementState ( id ) ;
97102 } ;
98103}
104+
105+ export function getManagedResourceStackTemplateHandler (
106+ components : ServerComponents ,
107+ ) : RequestHandler < GetStackTemplateParams , GetStackTemplateResult | undefined , void > {
108+ return async ( params , _token ) => {
109+ try {
110+ const template = await components . cfnService . getTemplate ( { StackName : params . stackName } ) ;
111+ if ( ! template ) {
112+ return ;
113+ }
114+
115+ let lineNumber : number | undefined ;
116+
117+ if ( params . primaryIdentifier ) {
118+ const resources = await components . cfnService . describeStackResources ( { StackName : params . stackName } ) ;
119+ const resource = resources . StackResources ?. find (
120+ ( r ) => r . PhysicalResourceId === params . primaryIdentifier ,
121+ ) ;
122+
123+ if ( ! resource ?. LogicalResourceId ) {
124+ throw new Error (
125+ `Resource with PhysicalResourceId ${ params . primaryIdentifier } not found in stack ${ params . stackName } ` ,
126+ ) ;
127+ }
128+
129+ const logicalId = resource . LogicalResourceId ;
130+ const tempUri = `temp://${ randomUUID ( ) } .template` ;
131+
132+ try {
133+ components . syntaxTreeManager . add ( tempUri , template ) ;
134+
135+ const syntaxTree = components . syntaxTreeManager . getSyntaxTree ( tempUri ) ;
136+ if ( syntaxTree ) {
137+ const resourcesMap = getEntityMap ( syntaxTree , TopLevelSection . Resources ) ;
138+ const resourceContext = resourcesMap ?. get ( logicalId ) ;
139+ if ( resourceContext ) {
140+ lineNumber = resourceContext . startPosition . row ;
141+ }
142+ }
143+ } finally {
144+ components . syntaxTreeManager . deleteSyntaxTree ( tempUri ) ;
145+ }
146+ }
147+
148+ return {
149+ templateBody : template ,
150+ lineNumber,
151+ } ;
152+ } catch ( error ) {
153+ log . error ( {
154+ Handler : 'GetManagedResourceStackTemplateHandler' ,
155+ StackName : params . stackName ,
156+ ErrorMessage : error instanceof Error ? error . message : String ( error ) ,
157+ ErrorStack : error instanceof Error ? error . stack : undefined ,
158+ Error : error ,
159+ } ) ;
160+ throw error ;
161+ }
162+ } ;
163+ }
0 commit comments