import * as fs from 'fs' ; import * as querystring from 'querystring' ; param Type param col param assert returns export const isCollectionOf = ( type , col , assert = false ) => { if ( ! Array . isArray ( col ) ) { return false ; } for ( let i = 0 ; i < col . length ; ++ i ) { const invalid = ( typeof type === 'string' && typeof col [ i ] !== type ) || ( typeof type === 'function' && ! ( col [ i ] instanceof type ) ) ; if ( invalid ) { if ( assert ) { throw new Error ( `Expected collection containing only values of type ${ type }.` ) ; } return false ; } } return true ; } ; export const tryParseJSON = ( json ) => { try { return JSON . parse ( json ) ; } catch ( err ) { return undefined ; } } ; export const requireAll = ( path ) => { const files = fs . readdirSync ( path ) ; return files . map ( ( file ) => require ( `${ path }/${ file }` ) ) ; } ; export const mergePaths = ( ... paths ) => { let result = '' ; for ( let i = 0 ; i < paths . length ; ++ i ) { let path = paths [ i ] ; if ( ! path ) { return undefined ; } if ( path [ 0 ] !== '/' ) { path = `/${ path }` ; } const end = path . length - 1 ; if ( path [ end ] === '/' ) { path = path . substr ( 0 , end ) ; } result += path ; } return result || '/' ; } ; export const parseEndpoint = ( endpoint , custom = [ ] , root = '/' ) => { if ( ! endpoint || typeof endpoint !== 'string' ) { return { } ; } let [ method , path , _flags ] = endpoint . split ( ' ' ) ; method = method . toLowerCase ( ) ; path = mergePaths ( root , path ) ; const standard = [ 'get' , 'post' , 'put' , 'patch' , 'delete' , 'options' ] ; if ( ! standard . includes ( method ) && ! custom . includes ( method ) ) { return { } ; } const flags = _flags ? _flags . split ( '|' ) . map ( ( flag ) => flag . toLowerCase ( ) ) : [ ] ; return { method , path , flags } ; } ; export const routeToPath = ( route , args , query = false ) => { const segs = [ ] ; const data = query ? { ... args } : { } ; route . split ( '/' ) . forEach ( ( seg ) => { if ( seg [ 0 ] === ':' ) { const key = seg . substr ( 1 ) ; segs . push ( args [ key ] ) ; delete data [ key ] ; } else { segs . push ( seg ) ; } } ) ; const qs = query ? `?${ querystring . encode ( data ) }` : '' ; return segs . join ( '/' ) + qs ; } ; export const invokeChain = async ( middleware , ... args ) => { const chain = [ ... middleware ] ; let baton = args ; while ( chain . length ) { const current = chain . shift ( ) ; baton = await current ( ... baton ) ; if ( ! Array . isArray ( baton ) ) { break ; } } return baton ; } ; export const makeChain = ( ) => { const chain = [ ] ; async function caller ( ... args ) { let index = 0 ; const next = ( ) => { if ( index < chain . length ) { chain [ index ++ ] ( ... args , next ) ; } } ; next ( ) ; } caller . add = ( ... middleware ) => chain . push ( ... middleware ) ; return caller ; } ; export { default as Callable } from './Callable' ; export { default as Relation } from './Relation' ;