import CasePathsCore import Foundation @preconcurrency import URLRouting public enum ViewRoute: Sendable { case employee(EmployeeRoute) case login(LoginRoute) case purchaseOrder(PurchaseOrderRoute) case user(UserRoute) case vendor(VendorRoute) case vendorBranch(VendorBranchRoute) public static let router = OneOf { Route(.case(Self.employee)) { EmployeeRoute.router } Route(.case(Self.login)) { LoginRoute.router } Route(.case(Self.purchaseOrder)) { PurchaseOrderRoute.router } Route(.case(Self.user)) { UserRoute.router } Route(.case(Self.vendor)) { VendorRoute.router } Route(.case(Self.vendorBranch)) { VendorBranchRoute.router } } } public extension ViewRoute { enum EmployeeRoute: Sendable { case create(Employee.Create) case delete(id: Employee.ID) case form case get(id: Employee.ID) case index case select(context: SelectContext) case update(id: Employee.ID, updates: Employee.Update) static let rootPath = "employees" public static let router = OneOf { Route(.case(Self.create)) { Path { rootPath } Method.post Body { FormData { Field("firstName", .string) Field("lastName", .string) Field("active") { Optionally { Bool.parser() } } } .map(.memberwise(Employee.Create.init)) } } Route(.case(Self.index)) { Path { rootPath } Method.get } Route(.case(Self.delete(id:))) { Path { rootPath; Employee.ID.parser() } Method.delete } Route(.case(Self.get(id:))) { Path { rootPath; Employee.ID.parser() } Method.get } Route(.case(Self.update(id:updates:))) { Path { rootPath; Employee.ID.parser() } Method.put Body { FormData { Field("firstName") { Optionally { CharacterSet.alphanumerics.map(.string) } } Field("lastName") { Optionally { CharacterSet.alphanumerics.map(.string) } } Field("active") { Optionally { Bool.parser() } } } .map(.memberwise(Employee.Update.init)) } } Route(.case(Self.select(context:))) { Path { rootPath; "select" } Method.get Query { Field("context") { SelectContext.parser() } } } } } } public extension ViewRoute { enum LoginRoute: Sendable { case index(next: String? = nil) case post(Request) static let rootPath = "login" public static let router = OneOf { Route(.case(Self.index)) { Method.get Path { rootPath } Query { Field("next", default: nil) { Optionally { CharacterSet.urlPathAllowed.map(.string) } } } } Route(.case(Self.post)) { Path { rootPath } Method.post Body { FormData { Field("username", .string) Field("password", .string) Field("next", default: nil) { Optionally { CharacterSet.urlPathAllowed.map(.string) } } } .map(.memberwise(Request.init)) } } } public struct Request: Codable, Equatable, Sendable { public let username: String public let password: String public let next: String? } } } public extension ViewRoute { enum PurchaseOrderRoute: Sendable { case create(PurchaseOrder.Create) case delete(id: PurchaseOrder.ID) case form case get(id: PurchaseOrder.ID) case index case page(page: Int, limit: Int) case search(Search) static let rootPath = "purchase-orders" public static let router = OneOf { Route(.case(Self.create)) { Path { rootPath } Method.post Body { FormData { Field("id") { Optionally { PurchaseOrder.ID.parser() } } Field("workOrder") { Optionally { Int.parser() } } Field("materials", .string) Field("customer", .string) Field("truckStock") { Optionally { Bool.parser() } } Field("createdByID") { User.ID.parser() } Field("createdForID") { Employee.ID.parser() } Field("vendorBranchID") { VendorBranch.ID.parser() } } .map(.memberwise(PurchaseOrder.Create.init)) } } Route(.case(Self.delete(id:))) { Path { rootPath; Digits() } Method.delete } Route(.case(Self.form)) { Path { rootPath; "create" } Method.get } Route(.case(Self.get(id:))) { Path { rootPath; Digits() } Method.get } Route(.case(Self.index)) { Path { rootPath } Method.get } Route(.case(Self.page(page:limit:))) { Path { rootPath; "next" } Method.get Query { Field("page", default: 1) { Digits() } Field("limit", default: 25) { Digits() } } } Route(.case(Self.search)) { Search.router } } public enum Search: Sendable { case index(context: Context? = nil, table: Bool? = nil) case search(Request) static let rootPath = Path { "purchase-orders"; "search" } static let router = OneOf { Route(.case(Search.index(context:table:))) { rootPath Method.get Query { Field("context", default: .employee) { Optionally { Search.Context.parser() } } Field("table", default: nil) { Optionally { Bool.parser() } } } } Route(.case(Search.search)) { rootPath Method.post Body(.json(Search.Request.self)) } } public enum Context: String, Codable, CaseIterable, Sendable { case employee case customer case vendor } public struct Request: Codable, Sendable { public let context: Context public let createdForID: Employee.ID? public let customerSearch: String? public let vendorBranchID: VendorBranch.ID? public init( context: Context, createdForID: Employee.ID? = nil, customerSearch: String? = nil, vendorBranchID: VendorBranch.ID? = nil ) { self.context = context self.createdForID = createdForID self.customerSearch = customerSearch self.vendorBranchID = vendorBranchID } } } } } public extension ViewRoute { enum SelectContext: String, Codable, Sendable, CaseIterable { case purchaseOrderForm case purchaseOrderSearch } } public extension ViewRoute { enum UserRoute: Sendable { case create(User.Create) case delete(id: User.ID) case form case get(id: User.ID) case index case update(id: User.ID, updates: User.Update) static let rootPath = "users" public static let router = OneOf { Route(.case(Self.create)) { Path { rootPath } Method.post Body(.json(User.Create.self)) } Route(.case(Self.delete(id:))) { Path { rootPath; User.ID.parser() } Method.delete } Route(.case(Self.form)) { Path { rootPath; "create" } Method.get } Route(.case(Self.get(id:))) { Path { rootPath; User.ID.parser() } Method.get } Route(.case(Self.index)) { Path { rootPath } Method.get } Route(.case(Self.update(id:updates:))) { Path { rootPath; User.ID.parser() } Method.patch Body { FormData { Field("username") { Optionally { CharacterSet.alphanumerics.map(.string) } } Field("email") { Optionally { // TODO: Not sure if this is correct. Rest().map(.string) } } } .map(.memberwise(User.Update.init)) } } } } } public extension ViewRoute { enum VendorRoute: Sendable { case create(Vendor.Create) case delete(id: Vendor.ID) case form case get(id: Vendor.ID) case index case update(id: Vendor.ID, updates: Vendor.Update) static let rootPath = "vendors" public static let router = OneOf { Route(.case(Self.create)) { Path { rootPath } Method.post Body { FormData { Field("name", .string) } .map(.memberwise(Vendor.Create.init)) } } Route(.case(Self.delete(id:))) { Path { rootPath; Vendor.ID.parser() } Method.delete } Route(.case(Self.get(id:))) { Path { rootPath; Vendor.ID.parser() } Method.get } Route(.case(Self.form)) { Path { rootPath; "create" } Method.get } Route(.case(Self.index)) { Path { rootPath } Method.get } Route(.case(Self.update(id:updates:))) { Path { rootPath; Vendor.ID.parser() } Method.put Body { FormData { Field("name", .string) } .map(.memberwise(Vendor.Update.init)) } } } } } public extension ViewRoute { enum VendorBranchRoute: Sendable { case create(VendorBranch.Create) case delete(id: VendorBranch.ID) case select(context: ViewRoute.SelectContext) public static let router = OneOf { Route(.case(Self.create)) { Path { "vendors"; "branches" } Method.post Body { FormData { Field("name", .string) Field("vendorID") { Vendor.ID.parser() } } .map(.memberwise(VendorBranch.Create.init)) } } Route(.case(Self.delete(id:))) { Path { "vendors"; "branches"; VendorBranch.ID.parser() } Method.delete } Route(.case(Self.select(context:))) { Path { "vendors"; "branches"; "select" } Method.get Query { Field("context") { SelectContext.parser() } } } } } }