Skip to content
This repository has been archived by the owner on Apr 20, 2024. It is now read-only.

Commit

Permalink
Merge pull request #8 from nodes-vapor/feature/align-to-vapor-2-conve…
Browse files Browse the repository at this point in the history
…ntions

Should work in Vapor 2 now..
  • Loading branch information
steffendsommer authored Aug 23, 2017
2 parents fe46e15 + 3c244fd commit 9962531
Show file tree
Hide file tree
Showing 8 changed files with 252 additions and 183 deletions.
8 changes: 4 additions & 4 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import PackageDescription

let package = Package(
name: "Meta",
dependencies: [
.Package(url: "https://github.com/vapor/vapor.git", majorVersion: 2),
]
name: "Meta",
dependencies: [
.Package(url: "https://github.com/vapor/vapor.git", majorVersion: 2),
]
)
111 changes: 52 additions & 59 deletions Sources/Meta/Configuration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,79 +3,72 @@ import Vapor
import HTTP

public struct Configuration {
private enum Keys: String {
case meta
case header
case platforms
case environments
case exceptPaths
case requiredEnvironments
}

public enum Field: String {
case header = "meta.header"
case platforms = "meta.platforms"
case environments = "meta.environments"
case requiredEnvironments = "meta.requiredEnvironments"
case exceptPaths = "meta.exceptPaths"

var path: [String] {
return rawValue.components(separatedBy: ".")
}
internal let headerKey: HeaderKey
internal let platforms: [String]
internal let environments: [String]
internal let exceptPaths: [String]
internal let requiredEnvironments: [String]
internal let environment: Environment

var error: Abort {
return Abort(
internal init(_ config: Config) throws {
guard let metaConfig: Config = config[Keys.meta.rawValue] else {
throw Abort(
.internalServerError,
metadata: nil,
reason: "Meta error - \(rawValue) config is missing."
reason: "Meta error - meta config is missing."
)
}
}

public let headerKey: HeaderKey
public let platforms: [String]
public let environments: [String]
public let requiredEnvironments: [String]
public let exceptPaths: [String]

public init(drop: Droplet) throws {
self.platforms = try Configuration.extract(field: .platforms, drop: drop)
self.environments = try Configuration.extract(field: .environments, drop: drop)
self.requiredEnvironments = try Configuration.extract(field: .requiredEnvironments, drop: drop)
self.exceptPaths = try Configuration.extract(field: .exceptPaths, drop: drop)

let headerString: String = try Configuration.extract(field: .header, drop: drop)
self.headerKey = HeaderKey(headerString)
let key: String = try metaConfig.get(Keys.header.rawValue)
headerKey = HeaderKey(key)
platforms = try Configuration.extractArray(
from: metaConfig,
forKey: .platforms
)
environments = try Configuration.extractArray(
from: metaConfig,
forKey: .environments
)
exceptPaths = try Configuration.extractArray(
from: metaConfig,
forKey: .exceptPaths
)
requiredEnvironments = try Configuration.extractArray(
from: metaConfig,
forKey: .requiredEnvironments
)
environment = metaConfig.environment
}

private static func extract(field: Field , drop: Droplet) throws -> [String] {
// Get array
guard let platforms = drop.config[field.path]?.array else {
throw field.error
private static func extractArray(
from config: Config,
forKey key: Keys
) throws -> [String] {
guard let array = config[key.rawValue]?.array else {
throw Abort(
.internalServerError,
metadata: nil,
reason: "Meta error - \(key.rawValue) key is missing."
)
}

// Get from config and make sure all values are strings
return try platforms.map({
return try array.map({
guard let string = $0.string else {
throw field.error
throw Abort(
.internalServerError,
reason: "Invalid value for key: \(key.rawValue)"
)
}

return string
})
}

private static func extract(field: Field , drop: Droplet) throws -> String {
guard let string = drop.config[field.path]?.string else {
throw field.error
}

return string
}
}

// MARK: - Extract -

extension Configuration {
public func extractHeaderString(withRequest request: Request) throws -> String {
guard let metaString = request.headers[headerKey]?.string else {
throw Abort(
.badRequest,
metadata: nil,
reason: "Missing \(headerKey.key) header."
)
}
return metaString
}
}
123 changes: 71 additions & 52 deletions Sources/Meta/Meta.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,85 +2,104 @@ import Vapor
import Foundation

public struct Meta {
private enum RawMetaConfig {
static let delimiter = ";"
static let webPlatform = "web"
static let webVersion = "0.0.0"
static let webDeviceOs = "N/A"
static let webDevice = "N/A"
}

public let platform: String
public let environment: String
public let version: Version
public let deviceOs: String
public let device: String

public init(configuration: Configuration, meta: String) throws {
var components = meta.components(separatedBy: ";")

// Set platform
guard !components.isEmpty && configuration.platforms.contains(components[0]) else {
throw Abort(
.badRequest,
metadata: nil,
reason: "Platform is not supported."
public init(raw: String) throws {
var components = raw.components(separatedBy: RawMetaConfig.delimiter)

// Platform.
try Meta.assertItemsLeft(components, errorMessage: "Platform missing.")
let platform = components.removeFirst()

// Environment.
try Meta.assertItemsLeft(components, errorMessage: "Environment missing.")
let environment = components.removeFirst()

// Since web is normally using a valid User-Agent there is no reason
// to ask for more.
guard platform != RawMetaConfig.webPlatform else {
try self.init(
platform: platform,
environment: environment,
version: RawMetaConfig.webVersion,
deviceOs: RawMetaConfig.webDeviceOs,
device: RawMetaConfig.webDevice
)
return
}

self.platform = components.removeFirst()

// Set environment
guard !components.isEmpty && configuration.environments.contains(components[0]) else {
throw Abort(
.badRequest,
metadata: nil,
reason: "Environment is not supported."
)
}
// Version.
try Meta.assertItemsLeft(components, errorMessage: "Version missing.")
let version = components.removeFirst()

// Device OS.
try Meta.assertItemsLeft(components, errorMessage: "Device OS missing.")
let deviceOs = components.removeFirst()

// Device.
try Meta.assertItemsLeft(components, errorMessage: "Device missing.")
let device = components.removeFirst()

try self.init(
platform: platform,
environment: environment,
version: version,
deviceOs: deviceOs,
device: device
)
}

self.environment = components.removeFirst()
public init(
platform: String,
environment: String,
version: String,
deviceOs: String,
device: String
) throws {
// Set platform
self.platform = platform

// Since web is normally using a valid User-Agent there is no reason for asking for more
if platform == "web" {
self.version = try Version(string: "0.0.0")
self.deviceOs = "N/A"
self.device = "N/A"
return
}
// Set environment
self.environment = environment

// Set version
guard !components.isEmpty else {
throw Abort(
.badRequest,
metadata: nil,
reason: "Missing version."
)
}

version = try Version(string: components.removeFirst())
self.version = try Version(string: version)

// Set device os
guard !components.isEmpty else {
throw Abort(
.badRequest,
metadata: nil,
reason: "Missing device os."
)
}

self.deviceOs = components.removeFirst()
self.deviceOs = deviceOs

// Set device
guard !components.isEmpty else {
self.device = device
}


// MARK: Helper functions.

private static func assertItemsLeft(_ items: [String], errorMessage: String) throws {
guard !items.isEmpty else {
throw Abort(
.badRequest,
metadata: nil,
reason: "Missing device."
reason: errorMessage
)
}

self.device = components.removeFirst()
}
}

// MARK: - NodeConvertible -

extension Meta: NodeConvertible {

public init(node: Node) throws {
platform = try node.get("platform")
environment = try node.get("environment")
Expand All @@ -96,6 +115,6 @@ extension Meta: NodeConvertible {
"version": Node(node: version),
"deviceOs": Node(deviceOs),
"device": Node(device)
])
])
}
}
Loading

0 comments on commit 9962531

Please sign in to comment.