/**
 * Introspects on the Skill Management API (SMAPI) model.
 */ export class ModelIntrospector { private operations : Map < string , ApiOperation > ; private definitions : Map < string , TypeDefinition > ; private modelJson : any ; private customizationProcessor : CustomizationProcessor ; constructor ( modelJson ? , customizationProcessor ? ) { if ( ! modelJson ) { const modelContent = require ( 'ask-smapi-model/spec.json' ) ; this . modelJson = modelContent ; } else { this . modelJson = modelJson ; } this . customizationProcessor = customizationProcessor ; this . processModel ( ) ; } param operationName public getOperationDefinition ( operationName ) { return this . operations . get ( operationName ) ; } /**
     * Returns a Map of all Skill Management API (SMAPI) operations
     */ public getOperations ( ) { return this . operations ; } private processModel ( ) { const modelDefinitions = this . modelJson . definitions ; this . definitions = new Map ( Object . keys ( modelDefinitions ) . map ( ( key ) => [ key , modelDefinitions [ key ] ] ) ) ; const operationDefinitions = [ ] ; Object . keys ( this . modelJson . paths ) . forEach ( ( pathKey ) => { Object . keys ( this . modelJson . paths [ pathKey ] ) . forEach ( ( operationKey ) => { operationDefinitions . push ( this . modelJson . paths [ pathKey ] [ operationKey ] ) ; } ) ; } ) ; this . operations = new Map ( ) ; for ( const operationDefinition of operationDefinitions ) { const apiOperationName = operationDefinition [ 'x-operation-name' ] ; if ( apiOperationName ) { const apiVersion = parseInt ( apiOperationName . substring ( apiOperationName . length - 1 ) , 10 ) ; const apiOperation = { apiOperationName , apiVersion , description : operationDefinition . description , params : operationDefinition . parameters , customizationMetadata : { } , } ; const processedOperationName = this . customizationProcessor ? this . customizationProcessor . processOperationName ( apiOperationName ) : apiOperationName ; if ( this . customizationProcessor ) { this . customizationProcessor . processOperation ( processedOperationName , apiOperation , this . definitions ) ; for ( const param of apiOperation . params ) { this . customizationProcessor . processParameter ( param , apiOperation , this . definitions ) ; } } if ( ! this . operations . has ( processedOperationName ) || apiVersion > this . operations . get ( processedOperationName ) . apiVersion ) { this . operations . set ( processedOperationName , apiOperation ) ; } } } } } /**
 * Customization processors are executed while processing a specification and can apply custom logic.
 */ export interface CustomizationProcessor { param operationName processOperationName ( operationName ) : string ; param operationName param operation param definitions processOperation ( operationName , operation , definitions ) : void ; param parameter param parentOperation param definitions processParameter ( parameter , parentOperation , definitions ) : void ; } /**
 * Represents an API operation.
 */ export interface ApiOperation { apiOperationName : string ; apiVersion : number ; description : string ; params : ApiParameter [ ] ; customizationMetadata : { [ key ] : any ; } ; } /**
 * Represents an API type definition.
 */ export interface TypeDefinition { type : string ; description : string ; required : boolean ; enum : string [ ] ; items : { } ; properties : { [ key ] : ApiParameter ; } ; } /**
 * Represents an API parameter.
 */ export interface ApiParameter extends TypeDefinition { name : string ; schema : { $ref : string ; } ; $ref : string ; customizationMetadata : { [ key ] : any ; } ; }