<commit_before>import * as sdk from 'botpress/sdk'
import { WellKnownFlags } from 'core/sdk/enums'
import { NextFunction, Request, Response } from 'express'
import { inject, injectable } from 'inversify'
import Knex from 'knex'
import { Memoize } from 'lodash-decorators'
import MLToolkit from 'ml/toolkit'

import { container } from './app.inversify'
import { ConfigProvider } from './config/config-loader'
import Database from './database'
import { LoggerProvider } from './logger'
import { renderRecursive } from './misc/templating'
import { ModuleLoader } from './module-loader'
import { SessionRepository, UserRepository } from './repositories'
import { Event, RealTimePayload } from './sdk/impl'
import HTTPServer from './server'
import { GhostService } from './services'
import { BotService } from './services/bot-service'
import { CMSService } from './services/cms'
import { DialogEngine } from './services/dialog/dialog-engine'
import { SessionIdFactory } from './services/dialog/session/id-factory'
import { ScopedGhostService } from './services/ghost/service'
import { HookService } from './services/hook/hook-service'
import { KeyValueStore } from './services/kvs'
import MediaService from './services/media'
import { EventEngine } from './services/middleware/event-engine'
import { NotificationsService } from './services/notification/service'
import RealtimeService from './services/realtime'
import { TYPES } from './types'

const http = (httpServer: HTTPServer) => (identity: string): typeof sdk.http => {
  return {
    createShortLink(name: string, destination: string, params?: any): void {
      httpServer.createShortLink(name, destination, params)
    },
    deleteShortLink(name: string): void {
      httpServer.deleteShortLink(name)
    },
    createRouterForBot(routerName: string, options?: sdk.RouterOptions): any & sdk.http.RouterExtension {
      const defaultRouterOptions = { checkAuthentication: true, enableJsonBodyParser: true }
      return httpServer.createRouterForBot(routerName, identity, options || defaultRouterOptions)
    },
    deleteRouterForBot: httpServer.deleteRouterForBot.bind(httpServer),
    async getAxiosConfigForBot(botId: string, options?: sdk.AxiosOptions): Promise<any> {
      return httpServer.getAxiosConfigForBot(botId, options)
    },
    extractExternalToken(req: Request, res: Response, next: NextFunction): Promise<void> {
      return httpServer.extractExternalToken(req, res, next)
    },
    decodeExternalToken(token: string): Promise<any> {
      return httpServer.decodeExternalToken(token)
    }
  }
}

const event = (eventEngine: EventEngine): typeof sdk.events => {
  return {
    registerMiddleware(middleware: sdk.IO.MiddlewareDefinition) {
      eventEngine.register(middleware)
    },
    removeMiddleware: eventEngine.removeMiddleware.bind(eventEngine),
    sendEvent(event: sdk.IO.Event): void {
      eventEngine.sendEvent(event)
    },
    replyToEvent(eventDestination: sdk.IO.EventDestination, payloads: any[], incomingEventId?: string): void {
      eventEngine.replyToEvent(eventDestination, payloads, incomingEventId)
    }
  }
}

const dialog = (dialogEngine: DialogEngine, sessionRepo: SessionRepository): typeof sdk.dialog => {
  return {
    createId(eventDestination: sdk.IO.EventDestination) {
      return SessionIdFactory.createIdFromEvent(eventDestination)
    },
    async processEvent(sessionId: string, event: sdk.IO.IncomingEvent): Promise<sdk.IO.IncomingEvent> {
      return dialogEngine.processEvent(sessionId, event)
    },
    async deleteSession(userId: string): Promise<void> {
      await sessionRepo.delete(userId)
    },
    async jumpTo(sessionId: string, event: any, flowName: string, nodeName?: string): Promise<void> {
      await dialogEngine.jumpTo(sessionId, event, flowName, nodeName)
    }
  }
}

const config = (moduleLoader: ModuleLoader, configProfider: ConfigProvider): typeof sdk.config => {
  return {
    getModuleConfig(moduleId: string): Promise<any> {
      return moduleLoader.configReader.getGlobal(moduleId)
    },
    getModuleConfigForBot(moduleId: string, botId: string): Promise<any> {
      return moduleLoader.configReader.getForBot(moduleId, botId)
    },
    getBotpressConfig(): Promise<any> {
      return configProfider.getBotpressConfig()
    }
  }
}

const bots = (botService: BotService): typeof sdk.bots => {
  return {
    getAllBots(): Promise<Map<string, sdk.BotConfig>> {
      return botService.getBots()
    },
    getBotById(botId: string): Promise<sdk.BotConfig | undefined> {
      return botService.findBotById(botId)
    },
    exportBot(botId: string): Promise<Buffer> {
      return botService.exportBot(botId)
    },
    importBot(botId: string, archive: Buffer, allowOverwrite?: boolean): Promise<void> {
      return botService.importBot(botId, archive, allowOverwrite)
    }
  }
}

const users = (userRepo: UserRepository): typeof sdk.users => {
  return {
    getOrCreateUser: userRepo.getOrCreate.bind(userRepo),
    updateAttributes: userRepo.updateAttributes.bind(userRepo),
    setAttributes: userRepo.setAttributes.bind(userRepo),
    getAllUsers: userRepo.getAllUsers.bind(userRepo),
    getUserCount: userRepo.getUserCount.bind(userRepo)
  }
}

const kvs = (kvs: KeyValueStore): typeof sdk.kvs => {
  return {<commit_msg>fix: expose getAttributes from UserRepository<commit_after>import * as sdk from 'botpress/sdk'
import { WellKnownFlags } from 'core/sdk/enums'
import { NextFunction, Request, Response } from 'express'
import { inject, injectable } from 'inversify'
import Knex from 'knex'
import { Memoize } from 'lodash-decorators'
import MLToolkit from 'ml/toolkit'

import { container } from './app.inversify'
import { ConfigProvider } from './config/config-loader'
import Database from './database'
import { LoggerProvider } from './logger'
import { renderRecursive } from './misc/templating'
import { ModuleLoader } from './module-loader'
import { SessionRepository, UserRepository } from './repositories'
import { Event, RealTimePayload } from './sdk/impl'
import HTTPServer from './server'
import { GhostService } from './services'
import { BotService } from './services/bot-service'
import { CMSService } from './services/cms'
import { DialogEngine } from './services/dialog/dialog-engine'
import { SessionIdFactory } from './services/dialog/session/id-factory'
import { ScopedGhostService } from './services/ghost/service'
import { HookService } from './services/hook/hook-service'
import { KeyValueStore } from './services/kvs'
import MediaService from './services/media'
import { EventEngine } from './services/middleware/event-engine'
import { NotificationsService } from './services/notification/service'
import RealtimeService from './services/realtime'
import { TYPES } from './types'

const http = (httpServer: HTTPServer) => (identity: string): typeof sdk.http => {
  return {
    createShortLink(name: string, destination: string, params?: any): void {
      httpServer.createShortLink(name, destination, params)
    },
    deleteShortLink(name: string): void {
      httpServer.deleteShortLink(name)
    },
    createRouterForBot(routerName: string, options?: sdk.RouterOptions): any & sdk.http.RouterExtension {
      const defaultRouterOptions = { checkAuthentication: true, enableJsonBodyParser: true }
      return httpServer.createRouterForBot(routerName, identity, options || defaultRouterOptions)
    },
    deleteRouterForBot: httpServer.deleteRouterForBot.bind(httpServer),
    async getAxiosConfigForBot(botId: string, options?: sdk.AxiosOptions): Promise<any> {
      return httpServer.getAxiosConfigForBot(botId, options)
    },
    extractExternalToken(req: Request, res: Response, next: NextFunction): Promise<void> {
      return httpServer.extractExternalToken(req, res, next)
    },
    decodeExternalToken(token: string): Promise<any> {
      return httpServer.decodeExternalToken(token)
    }
  }
}

const event = (eventEngine: EventEngine): typeof sdk.events => {
  return {
    registerMiddleware(middleware: sdk.IO.MiddlewareDefinition) {
      eventEngine.register(middleware)
    },
    removeMiddleware: eventEngine.removeMiddleware.bind(eventEngine),
    sendEvent(event: sdk.IO.Event): void {
      eventEngine.sendEvent(event)
    },
    replyToEvent(eventDestination: sdk.IO.EventDestination, payloads: any[], incomingEventId?: string): void {
      eventEngine.replyToEvent(eventDestination, payloads, incomingEventId)
    }
  }
}

const dialog = (dialogEngine: DialogEngine, sessionRepo: SessionRepository): typeof sdk.dialog => {
  return {
    createId(eventDestination: sdk.IO.EventDestination) {
      return SessionIdFactory.createIdFromEvent(eventDestination)
    },
    async processEvent(sessionId: string, event: sdk.IO.IncomingEvent): Promise<sdk.IO.IncomingEvent> {
      return dialogEngine.processEvent(sessionId, event)
    },
    async deleteSession(userId: string): Promise<void> {
      await sessionRepo.delete(userId)
    },
    async jumpTo(sessionId: string, event: any, flowName: string, nodeName?: string): Promise<void> {
      await dialogEngine.jumpTo(sessionId, event, flowName, nodeName)
    }
  }
}

const config = (moduleLoader: ModuleLoader, configProfider: ConfigProvider): typeof sdk.config => {
  return {
    getModuleConfig(moduleId: string): Promise<any> {
      return moduleLoader.configReader.getGlobal(moduleId)
    },
    getModuleConfigForBot(moduleId: string, botId: string): Promise<any> {
      return moduleLoader.configReader.getForBot(moduleId, botId)
    },
    getBotpressConfig(): Promise<any> {
      return configProfider.getBotpressConfig()
    }
  }
}

const bots = (botService: BotService): typeof sdk.bots => {
  return {
    getAllBots(): Promise<Map<string, sdk.BotConfig>> {
      return botService.getBots()
    },
    getBotById(botId: string): Promise<sdk.BotConfig | undefined> {
      return botService.findBotById(botId)
    },
    exportBot(botId: string): Promise<Buffer> {
      return botService.exportBot(botId)
    },
    importBot(botId: string, archive: Buffer, allowOverwrite?: boolean): Promise<void> {
      return botService.importBot(botId, archive, allowOverwrite)
    }
  }
}

const users = (userRepo: UserRepository): typeof sdk.users => {
  return {
    getOrCreateUser: userRepo.getOrCreate.bind(userRepo),
    updateAttributes: userRepo.updateAttributes.bind(userRepo),
    getAttributes: userRepo.getAttributes.bind(userRepo),
    setAttributes: userRepo.setAttributes.bind(userRepo),
    getAllUsers: userRepo.getAllUsers.bind(userRepo),
    getUserCount: userRepo.getUserCount.bind(userRepo)
  }
}

const kvs = (kvs: KeyValueStore): typeof sdk.kvs => {
  return {
{'fraction_non_alphanumeric': 0.11769662921348314, 'fraction_numerical': 0.0, 'mean_word_length': 4.525607863424728, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 47, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1633682', 'n_tokens_mistral': 3092, 'n_tokens_neox': 3137, 'n_words': 690}