import * as path from 'path' ; import { loadJSONFile } from '@hint/utils-fs' ; import { Engine , FetchEnd , Parser } from 'hint' ; import { IJSONResult , parseJSON , SchemaValidationResult , validate } from '@hint/utils-json' ; import { PackageJsonEvents } from './types' ; import { IJsonSchemaForNpmPackageJsonFiles } from './schema' ; export * from './types' ; export default class PackageJsonParser extends Parser < PackageJsonEvents > { private schema : IJsonSchemaForNpmPackageJsonFiles ; public constructor ( engine ) { super ( engine , 'package-json' ) ; this . schema = loadJSONFile ( path . join ( __dirname , 'schema.json' ) ) ; engine . on ( 'fetch::end::json' , this . parsePackageJson . bind ( this ) ) ; } private validateSchema ( config , resource , result ) { return validate ( this . schema , config , result . getLocation ) ; } private async emitInvalidPackageJson ( validationResult , resource ) { await this . engine . emitAsync ( 'parse::error::package-json::schema' , { error : new Error ( 'Invalid package.json configuration' ) , errors : validationResult . errors , groupedErrors : validationResult . groupedErrors , prettifiedErrors : validationResult . prettifiedErrors , resource } ) ; } private async parsePackageJson ( fetchEnd ) { const resource = fetchEnd . resource ; const resourceFileName = path . basename ( resource ) ; const isPackageJson = resourceFileName === 'package.json' ; if ( ! isPackageJson ) { return ; } try { const response = fetchEnd . response ; const result = parseJSON ( response . body . content ) ; await this . engine . emitAsync ( 'parse::start::package-json' , { resource } ) ; const config = result . data ; const validationResult = await this . validateSchema ( config , resource , result ) ; if ( ! validationResult . valid ) { await this . emitInvalidPackageJson ( validationResult , resource ) ; return ; } await this . engine . emitAsync ( 'parse::end::package-json' , { config : validationResult . data , getLocation : result . getLocation , resource } ) ; } catch ( err ) { await this . engine . emitAsync ( 'parse::error::package-json::json' , { error : err , resource } ) ; } } }