license import { JsonAstObject , JsonParseMode , parseJsonAst } from '@angular-devkit/core' ; import { SchematicsException , Tree } from '@angular-devkit/schematics' ; import { appendPropertyInAstObject , findPropertyInAstObject , insertPropertyInAstObjectInOrder , } from './json-utils' ; const pkgJsonPath = '/package.json' ; export enum NodeDependencyType { Default = 'dependencies' , Dev = 'devDependencies' , Peer = 'peerDependencies' , Optional = 'optionalDependencies' } export interface NodeDependency { type : NodeDependencyType ; name : string ; version : string ; overwrite ? : boolean ; } export function addPackageJsonDependency ( tree , dependency ) { const packageJsonAst = _readPackageJson ( tree ) ; const depsNode = findPropertyInAstObject ( packageJsonAst , dependency . type ) ; const recorder = tree . beginUpdate ( pkgJsonPath ) ; if ( ! depsNode ) { appendPropertyInAstObject ( recorder , packageJsonAst , dependency . type , { [ dependency . name ] : dependency . version , } , 2 ) ; } else if ( depsNode . kind === 'object' ) { const depNode = findPropertyInAstObject ( depsNode , dependency . name ) ; if ( ! depNode ) { insertPropertyInAstObjectInOrder ( recorder , depsNode , dependency . name , dependency . version , 4 ) ; } else if ( dependency . overwrite ) { const { end , start } = depNode ; recorder . remove ( start . offset , end . offset - start . offset ) ; recorder . insertRight ( start . offset , JSON . stringify ( dependency . version ) ) ; } } tree . commitUpdate ( recorder ) ; } export function getPackageJsonDependency ( tree , name ) { const packageJson = _readPackageJson ( tree ) ; let dep = null ; [ NodeDependencyType . Default , NodeDependencyType . Dev , NodeDependencyType . Optional , NodeDependencyType . Peer , ] . forEach ( depType => { if ( dep !== null ) { return ; } const depsNode = findPropertyInAstObject ( packageJson , depType ) ; if ( depsNode !== null && depsNode . kind === 'object' ) { const depNode = findPropertyInAstObject ( depsNode , name ) ; if ( depNode !== null && depNode . kind === 'string' ) { const version = depNode . value ; dep = { type : depType , name : name , version : version , } ; } } } ) ; return dep ; } function _readPackageJson ( tree ) { const buffer = tree . read ( pkgJsonPath ) ; if ( buffer === null ) { throw new SchematicsException ( 'Could not read package.json.' ) ; } const content = buffer . toString ( ) ; const packageJson = parseJsonAst ( content , JsonParseMode . Strict ) ; if ( packageJson . kind !== 'object' ) { throw new SchematicsException ( 'Invalid package.json. Was expecting an object' ) ; } return packageJson ; }