import { TextDocument } from 'vscode-languageserver-textdocument' ; import { IRuleResult , Spectral , Parsers , Document as SpectralDocument , KNOWN_FORMATS , KNOWN_RULESETS , SPECTRAL_PKG_VERSION , } from '@stoplight/spectral' ; import { DEFAULT_REQUEST_OPTIONS } from '@stoplight/spectral/dist/request' ; import { IRuleset } from '@stoplight/spectral/dist/types/ruleset' ; import { URI } from 'vscode-uri' ; import { createResolveHttp , resolveFile } from '@stoplight/json-ref-readers' ; import { ICache } from '@stoplight/json-ref-resolver/types' ; import { Resolver , Cache } from '@stoplight/json-ref-resolver' ; import { RemoteConsole , TextDocuments } from 'vscode-languageserver' ; import * as URIjs from 'urijs' ; const buildFileResolver = ( documents , console ) => { return ( ref ) : Promise < unknown > => { console . log ( `[DBG] documents.keys => ${ JSON . stringify ( documents . keys ( ) ) }` ) ; console . log ( `[DBG] fileResolver.resolve => ${ ref . toString ( ) }` ) ; const lookedUpUri = URI . file ( ref . toString ( ) ) ; console . log ( `[DBG] lookedUpUri => ${ lookedUpUri }` ) ; const lookedUpUriStr = lookedUpUri . toString ( ) ; for ( const key of documents . keys ( ) ) { console . log ( `[DBG] uri => ${ key }` ) ; console . log ( `[DBG] key ==? lookedUpUri => ${ key === lookedUpUriStr }` ) ; if ( key === lookedUpUriStr ) { const doc = documents . get ( lookedUpUriStr ) ; if ( doc === undefined ) { throw new Error ( `Unexpected undefined doc '${ lookedUpUriStr }'` ) ; } return Promise . resolve ( doc . getText ( ) ) ; } } return resolveFile ( ref ) ; } ; } ; export function createHttpAndFileResolver ( documents , uriCache , console ) { const resolveHttp = createResolveHttp ( { ... DEFAULT_REQUEST_OPTIONS } ) ; return new Resolver ( { resolvers : { https : { resolve : resolveHttp } , http : { resolve : resolveHttp } , file : { resolve : buildFileResolver ( documents , console ) } , } , uriCache , } ) ; } const useNimma = true ; const buildSpectralInstance = ( documents , uriCache , console ) : Spectral => { const spectral = new Spectral ( { resolver : createHttpAndFileResolver ( documents , uriCache , console ) , useNimma , } ) ; for ( const [ format , lookup ] of KNOWN_FORMATS ) { spectral . registerFormat ( format , ( document ) => lookup ( document ) ) ; } return spectral ; } ; /**
 * Wrapper for the Spectral linter that runs linting against VS Code document
 * content in a manner similar to the Spectral CLI.
 */ export class Linter { static version = `${ SPECTRAL_PKG_VERSION }[useNimma=${ useNimma }]` ; static builtInRulesets = KNOWN_RULESETS ; private readonly spectral : Spectral ; private readonly cache : ICache ; constructor ( documents , console ) { this . cache = new Cache ( ) ; this . spectral = buildSpectralInstance ( documents , this . cache , console ) ; } param { TextDocument } document param { IRuleset | undefined } ruleset return { Promise < IRuleResult [ ] > } public async lint ( document , ruleset ) { if ( ruleset ) { this . spectral . setRuleset ( ruleset ) ; } else { this . spectral . setRuleset ( { functions : { } , rules : { } , exceptions : { } , } ) ; } const text = document . getText ( ) ; const file = URI . parse ( document . uri ) . fsPath ; const doc = new SpectralDocument ( text , Parsers . Yaml , file ) ; this . cache . purge ( ) ; return this . spectral . run ( doc , { ignoreUnknownFormat : true , resolve : { documentUri : file } } ) ; } }