import Hummingbird import Logging /// A type that sets and builds an application that should be ready to run. public struct AppBuilder { // MARK: Properties private let appName: String private let archivesFolder: String private let environment: Environment // MARK: Initialisers /// Initialises this type. /// - Parameters: /// - appName: A name for the app to build. /// - archivesFolder: A relative path to the location of the *DocC* archive containers. public init( appName: String, archivesFolder: String ) { self.appName = appName self.archivesFolder = archivesFolder self.environment = Environment() } // MARK: Functions /// Sets and builds a ready-to-use application. /// /// The application this function builds have the following features: /// * proxy requests to any available *DocC* archive container in the `archivesFolder` location; /// * log any request to any available *DocC* archive container in the application console. /// /// - Parameter arguments: A set in input parameters used while building the application. /// - Returns: A configured, functional application that is ready to use. public func callAsFunction(_ arguments: some AppArguments) async throws -> some ApplicationProtocol { let logger = logger(level: arguments.logLevel) let router = router(logger: logger) return Application( router: router, configuration: .init( address: .hostname(arguments.hostname, port: arguments.port), serverName: appName ), logger: logger ) } } // MARK: - Helpers private extension AppBuilder { // MARK: Type aliases typealias AppRequestContext = BasicRequestContext // MARK: Functions func logger(level: Logger.Level?) -> Logger { var logger = Logger(label: appName) logger.logLevel = level ?? environment.logLevel.flatMap { Logger.Level(rawValue: $0) ?? .info } ?? .info return logger } func router(logger: Logger) -> Router { let router = Router() router.addMiddleware { LogRequestsMiddleware(logger.logLevel) DocCMiddleware(archivesFolder) } ArchiveController().register(to: router) return router } }