11import { ResponseError , ErrorCodes , RequestHandler } from 'vscode-languageserver' ;
22import { TopLevelSection } from '../context/ContextType' ;
33import { getEntityMap } from '../context/SectionContextBuilder' ;
4- import { Parameter } from '../context/semantic/Entity' ;
4+ import { Parameter , Resource } from '../context/semantic/Entity' ;
55import { parseIdentifiable } from '../protocol/LspParser' ;
66import { Identifiable } from '../protocol/LspTypes' ;
77import { ServerComponents } from '../server/ServerComponents' ;
@@ -16,6 +16,7 @@ import {
1616 GetStackActionStatusResult ,
1717 DescribeValidationStatusResult ,
1818 DescribeDeploymentStatusResult ,
19+ GetTemplateResourcesResult ,
1920} from '../stacks/actions/StackActionRequestType' ;
2021import { ListStacksParams , ListStacksResult } from '../stacks/StackRequestType' ;
2122import { LoggerFactory } from '../telemetry/LoggerFactory' ;
@@ -164,6 +165,72 @@ export function getCapabilitiesHandler(
164165 } ;
165166}
166167
168+ export function getTemplateResourcesHandler (
169+ components : ServerComponents ,
170+ ) : RequestHandler < TemplateUri , GetTemplateResourcesResult , void > {
171+ return ( rawParams ) => {
172+ log . debug ( { Handler : 'getTemplateResourcesHandler' , rawParams } ) ;
173+
174+ try {
175+ const params = parseWithPrettyError ( parseTemplateUriParams , rawParams ) ;
176+ const syntaxTree = components . syntaxTreeManager . getSyntaxTree ( params ) ;
177+ if ( ! syntaxTree ) return { resources : [ ] } ;
178+
179+ const resourcesMap = getEntityMap ( syntaxTree , TopLevelSection . Resources ) ;
180+ if ( ! resourcesMap ) return { resources : [ ] } ;
181+
182+ const schemas = components . schemaRetriever . getDefault ( ) ;
183+ const resources = [ ...resourcesMap . values ( ) ] . flatMap ( ( context ) => {
184+ const resource = context . entity as Resource ;
185+ const resourceType = resource . Type ?? '' ;
186+ if ( ! resourceType ) return [ ] ;
187+
188+ const schema = schemas . schemas . get ( resourceType ) ;
189+ const primaryIdentifierKeys = extractPrimaryIdentifierKeys ( schema ?. primaryIdentifier ) ;
190+ const primaryIdentifier = primaryIdentifierKeys
191+ ? buildPrimaryIdentifierFromMetadata ( resource . Metadata ?. PrimaryIdentifier , primaryIdentifierKeys )
192+ : undefined ;
193+
194+ return [
195+ {
196+ logicalId : resource . name ,
197+ type : resourceType ,
198+ primaryIdentifierKeys,
199+ primaryIdentifier,
200+ } ,
201+ ] ;
202+ } ) ;
203+
204+ return { resources } ;
205+ } catch ( error ) {
206+ handleStackActionError ( error , 'Failed to get template resources' ) ;
207+ }
208+ } ;
209+ }
210+
211+ function extractPrimaryIdentifierKeys ( primaryIdentifierPaths ?: string [ ] ) : string [ ] | undefined {
212+ return primaryIdentifierPaths
213+ ?. map ( ( path ) => {
214+ const match = path . match ( / \/ p r o p e r t i e s \/ ( .+ ) / ) ;
215+ return match ?. [ 1 ] ;
216+ } )
217+ . filter ( ( key ) : key is string => key !== undefined ) ;
218+ }
219+
220+ function buildPrimaryIdentifierFromMetadata (
221+ metadataValue : unknown ,
222+ keys : string [ ] ,
223+ ) : Record < string , string > | undefined {
224+ if ( ! metadataValue || keys . length === 0 || typeof metadataValue !== 'string' ) return undefined ;
225+
226+ const values = metadataValue . split ( '|' ) . map ( ( v ) => v . trim ( ) ) ;
227+ const identifier : Record < string , string > = { } ;
228+ for ( const [ index , key ] of keys . entries ( ) ) {
229+ identifier [ key ] = values [ index ] || values [ 0 ] ;
230+ }
231+ return identifier ;
232+ }
233+
167234export function listStacksHandler (
168235 components : ServerComponents ,
169236) : RequestHandler < ListStacksParams , ListStacksResult , void > {
0 commit comments