import { RouterOSAPI , RosException , RStream } from "node-routeros" ; import { RouterOSAPICrud } from "./RosApiCrud" ; import { RosApiModel } from "./RosApiModel" ; import * as Types from "./Types" ; import * as debug from "debug" ; const info = debug ( "routeros-client:commands:info" ) ; const error = debug ( "routeros-client:commands:error" ) ; export class RosApiCommands extends RouterOSAPICrud { param rosApi param path param snakeCase constructor ( rosApi , path , snakeCase ) { super ( rosApi , path , snakeCase ) ; } param fields public select ( fields ) { let commaFields = "=.proplist=" ; if ( typeof fields === "string" ) fields = [ fields ] ; for ( let i = 0 ; i < fields . length ; i ++ ) { const field = fields [ i ] ; if ( /^(id|dead|nextid)$/ . test ( field ) ) fields [ i ] = "." + field ; } commaFields += fields ; this . proplistVal = commaFields ; return this ; } param from param to public move ( from , to ? ) { return super . moveEntry ( from , to ) ; } param fields public only ( fields ) { return this . select ( fields ) ; } param opts param args public options ( opts , ... args ) { if ( typeof opts === "string" ) opts = [ opts ] ; opts = opts . concat ( args || [ ] ) ; const optObj = { } ; for ( const opt of opts ) optObj [ opt ] = "" ; return this . where ( optObj , "" , false ) ; } param fields public proplist ( fields ) { return this . select ( fields ) ; } param key param value param addQuestionMark public where ( key , value = "" , addQuestionMark = true ) { let search = new Object ( ) ; if ( typeof key === "string" ) { search [ key ] = value ; } else { search = key ; } this . makeQuery ( search , addQuestionMark ) ; return this ; } param key param value public query ( key , value ? ) { return this . where ( key , value , false ) ; } param key param value public filter ( key , value ? ) { return this . where ( key , value , false ) ; } param search public whereRaw ( search ) { this . queryVal = this . queryVal . concat ( search ) ; return this ; } param key param value public orWhere ( key , value ? ) { this . where ( key , value ) ; this . queryVal . push ( "?#|" ) ; return this ; } param key param value public orWhereNot ( key , value ? ) { this . where ( key , value ) ; this . queryVal . push ( "?#!" , "?#|" ) ; return this ; } param key param value public andWhere ( key , value ? ) { this . where ( key , value ) ; this . queryVal . push ( "?#&" ) ; return this ; } param key param value public andWhereNot ( key , value ? ) { this . where ( key , value ) ; this . queryVal . push ( "?#!" , "?#&" ) ; return this ; } param key param value public whereNot ( key , value ? ) { this . where ( key , value ) ; this . queryVal . push ( "?#!" ) ; return this ; } param key param value public whereHigher ( key , value ? ) { this . where ( ">" + key , value ) ; return this ; } param key param value public whereLower ( key , value ? ) { this . where ( "<" + key , value ) ; return this ; } param key public whereExists ( key ) { return this . whereHigher ( key ) ; } param key public whereNotEmpty ( key ) { return this . whereHigher ( key ) ; } param key public whereEmpty ( key ) { this . where ( "-" + key ) ; return this ; } param key public whereNotExists ( key ) { return this . whereEmpty ( key ) ; } param data public get ( data ? ) { if ( data ) this . makeQuery ( data , true ) ; const query = this . fullQuery ( "/print" ) ; return this . write ( query ) ; } param data public getAll ( data ? ) { return this . get ( data ) ; } param data public getModel ( data ? ) { return this . get ( data ) . then ( ( results ) => { for ( let i = 0 ; i < results . length ; i ++ ) { results [ i ] = new RosApiModel ( this . rosApi , results [ i ] , this . snakeCase ) ; } return Promise . resolve ( results ) ; } ) . catch ( ( err ) => { return Promise . reject ( err ) ; } ) ; } param data public print ( data ? ) { return this . get ( data ) ; } param data public first ( data ? ) { return this . find ( data ) ; } param data public find ( data ? ) { return this . get ( data ) . then ( ( results ) => { let result = new Object ( ) ; if ( results . length > 0 ) result = results [ 0 ] ; else result = null ; return Promise . resolve ( result ) ; } ) . catch ( ( err ) => { return Promise . reject ( err ) ; } ) ; } param data public getOne ( data ? ) { return this . find ( data ) ; } param data public getOnly ( data ? ) { return this . find ( data ) ; } /**
     * Remove all entries of the current menu
     */ public purge ( ) { return this . write ( [ this . pathVal + "/print" , "=.proplist=.id" ] ) . then ( ( results ) => { const ids = results . map ( ( result ) => { return result [ ".id" ] ; } ) ; return this . write ( [ this . pathVal + "/remove" , "=numbers=" + ids ] ) ; } ) . catch ( ( err ) => { return Promise . reject ( err ) ; } ) ; } param action param callback public stream ( action , callback ? ) { if ( typeof action === "function" ) { callback = action ; action = "" ; } else if ( action && typeof action === "string" ) { action = "/" + action . replace ( /^\// , "" ) ; } const query = this . fullQuery ( action ) ; info ( "Streaming query %o" , query ) ; this . queryVal = [ ] ; this . proplistVal = "" ; if ( ! callback ) { const stream = this . rosApi . stream ( query ) ; stream . on ( "data" , ( packet ) => { if ( ! Array . isArray ( packet ) ) { packet = this . treatMikrotikProperties ( [ packet ] ) [ 0 ] ; } else { packet = this . treatMikrotikProperties ( packet ) ; } stream . emit ( "parsed-data" , packet ) ; } ) ; stream . on ( "error" , ( err ) => { err = this . treatMikrotikProperties ( [ err ] ) [ 0 ] ; stream . emit ( "parsed-error" , err ) ; } ) ; return stream ; } return this . rosApi . stream ( query , ( err , packet , stream ) => { if ( err ) error ( "When streaming, got error: %o" , err ) ; if ( typeof callback === "function" ) { if ( packet ) { info ( "Received stream packet: %o" , packet ) ; if ( ! Array . isArray ( packet ) ) { packet = this . treatMikrotikProperties ( [ packet ] ) [ 0 ] ; } else { packet = this . treatMikrotikProperties ( packet ) ; } } callback ( err , packet , stream ) ; } } ) ; } }