import { Document } from './Document' ; import { DocCollection } from './DocCollection' ; import { Processor , ProcessorDef } from './Processor' ; import { Module , FactoryDef , TypeDef } from './Module' ; export type PackageRef = Package | string ; param { string } name param { string [ ] } dependencies export class Package { static isPackage ( pkg ) { return isString ( pkg . name ) && Array . isArray ( pkg . dependencies ) && isObject ( pkg . module ) ; } processors = [ ] ; configFns = [ ] ; handlers : { [ key ] : string [ ] ; } = { } ; module : Module = { } ; namedDependencies : string [ ] ; constructor ( public name , public dependencies = [ ] ) { if ( typeof name !== 'string' ) { throw new Error ( 'You must provide a name for the package' ) ; } if ( dependencies && ! Array . isArray ( dependencies ) ) { throw new Error ( 'dependencies must be an array' ) ; } } param { function | object | string } processorDefOrName param { function | object } processorDef return { Package } processor ( processorDefOrName , processorDef ? ) { let name ; if ( isString ( processorDefOrName ) ) { name = processorDefOrName ; } else { processorDef = processorDefOrName ; if ( ! processorDef . name ) { throw new Error ( 'processorDef must be an object or a function with a name' ) ; } name = processorDef . name ; } if ( typeof processorDef === 'function' ) { this . module [ name ] = [ 'factory' , processorDef ] ; } else { this . module [ name ] = [ 'value' , processorDef ] ; } this . processors . push ( name ) ; return this ; } param { function | string } serviceFactoryOrName param { function } serviceFactory return { Package } factory ( serviceFactoryOrName , serviceFactory ? ) { let name ; if ( typeof serviceFactoryOrName === 'string' ) { name = serviceFactoryOrName ; } else { serviceFactory = serviceFactoryOrName ; if ( ! serviceFactory . name ) { throw new Error ( 'serviceFactory must have a name' ) ; } name = serviceFactory . name ; } if ( typeof serviceFactory !== 'function' ) { throw new Error ( 'serviceFactory must be a function.\nGot "' + typeof serviceFactory + '"' ) ; } this . module [ name ] = [ 'factory' , serviceFactory ] ; return this ; } param { function | string } ServiceTypeOrName param { function } ServiceType return { Package } type ( ServiceTypeOrName , ServiceType ? ) { let name ; if ( typeof ServiceTypeOrName === 'string' ) { name = ServiceTypeOrName ; } else { ServiceType = ServiceTypeOrName ; if ( ! ServiceType . name ) { throw new Error ( 'ServiceType must have a name' ) ; } name = ServiceType . name ; } if ( typeof ServiceType !== 'function' ) { throw new Error ( 'ServiceType must be a constructor function' ) ; } this . module [ name ] = [ 'type' , ServiceType ] ; return this ; } param { function } configFn return { Package } config ( configFn ) { if ( typeof configFn !== 'function' ) { throw new Error ( 'configFn must be a function' ) ; } this . configFns . push ( configFn ) ; return this ; } param { string } eventName param { function } handlerFactory return { Package } eventHandler ( eventName , handlerFactory ) { if ( typeof eventName !== 'string' ) { throw new Error ( 'You must provide a string identifying the type of event to handle' ) ; } if ( typeof handlerFactory !== 'function' ) { throw new Error ( 'handlerFactory must be a function.\nGot "' + typeof handlerFactory + '"' ) ; } const handlers = this . handlers [ eventName ] = this . handlers [ eventName ] || [ ] ; const handlerName = handlerFactory . name || ( this . name + '_' + eventName + '_' + handlers . length ) ; this . factory ( handlerName , handlerFactory ) ; handlers . push ( handlerName ) ; return this ; } } function isObject ( value ) { const type = typeof value ; return ! ! value && ( type === 'object' || type === 'function' ) ; } function isString ( value ) { return typeof value === 'string' ; }