import CasePathsCore import Foundation @preconcurrency import URLRouting // TODO: Share view and api routes. public enum ViewRoute: Sendable { case employee(EmployeeRoute) case purchaseOrder(PurchaseOrderRoute) case select(SelectRoute) case user(UserRoute) case vendor(VendorRoute) public static let router = OneOf { Route(.case(Self.employee)) { EmployeeRoute.router } Route(.case(Self.purchaseOrder)) { PurchaseOrderRoute.router } Route(.case(Self.select)) { SelectRoute.router } Route(.case(Self.user)) { UserRoute.router } Route(.case(Self.vendor)) { VendorRoute.router } } public enum EmployeeRoute: Sendable { case create(Employee.Create) case delete(id: Employee.ID) case get(id: Employee.ID) case form case index 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(.json(Employee.Create.self)) } Route(.case(Self.index)) { Path { rootPath } Method.get } Route(.case(Self.delete(id:))) { Path { rootPath; UUID.parser() } Method.delete } Route(.case(Self.get(id:))) { Path { rootPath; UUID.parser() } Method.get } Route(.case(Self.form)) { Path { rootPath; "create" } Method.get } Route(.case(Self.update(id:updates:))) { Path { rootPath; UUID.parser() } Method.put Body(.json(Employee.Update.self)) } } } // TODO: Add search. public enum PurchaseOrderRoute: Sendable { case create(PurchaseOrder.Create) case form case get(id: PurchaseOrder.ID) case index case next(page: Int, limit: Int) static let rootPath = "purchase-orders" public static let router = OneOf { Route(.case(Self.create)) { Path { rootPath } Method.post Body(.json(PurchaseOrder.Create.self)) } 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.next(page:limit:))) { Path { rootPath; "next" } Method.get Query { Field("page", default: 1) { Digits() } Field("limit", default: 25) { Digits() } } } } } public enum SelectRoute: Sendable { case employee(context: Context) case vendorBranches(context: Context) public enum Context: String, Codable, Sendable, CaseIterable { case purchaseOrderForm case purchaseOrderSearch } static let rootPath = "select" public static let router = OneOf { Route(.case(Self.employee(context:))) { Path { rootPath; "employee" } Method.get Query { Field("context") { Context.parser() } } } Route(.case(Self.vendorBranches(context:))) { Path { rootPath; "vendor-branches" } Method.get Query { Field("context") { Context.parser() } } } } } public enum UserRoute: Sendable { case create(User.Create) case delete(id: User.ID) case form case get(id: User.ID) case index case login(User.Login) 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.login)) { Path { rootPath } Method.post Body(.json(User.Login.self)) } Route(.case(Self.update(id:updates:))) { Path { rootPath; User.ID.parser() } // TODO: Use put or patch. Method.post Body(.json(User.Update.self)) } } } public enum VendorRoute: Sendable { case create(Vendor.Create) case createBranch(VendorBranch.Create) 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(.json(Vendor.Create.self)) } Route(.case(Self.createBranch)) { Path { rootPath; "branches" } Method.post Body(.json(VendorBranch.Create.self)) } Route(.case(Self.form)) { Path { rootPath; "create" } Method.get } Route(.case(Self.get(id:))) { Path { rootPath; Vendor.ID.parser() } Method.get } Route(.case(Self.index)) { Path { rootPath } Method.get } Route(.case(Self.update(id:updates:))) { Path { rootPath; Vendor.ID.parser() } Method.put Body(.json(Vendor.Update.self)) } } } } public enum ApiRoute: Sendable { case employee(EmployeeApiRoute) case purchaseOrder(PurchaseOrderApiRoute) case user(UserApiRoute) case vendor(VendorApiRoute) case vendorBranch(VendorBranchApiRoute) public static let router = OneOf { Route(.case(Self.employee)) { EmployeeApiRoute.router } Route(.case(Self.purchaseOrder)) { PurchaseOrderApiRoute.router } Route(.case(Self.user)) { UserApiRoute.router } Route(.case(Self.vendor)) { VendorApiRoute.router } Route(.case(Self.vendorBranch)) { VendorBranchApiRoute.router } } public enum EmployeeApiRoute: Sendable { case create(Employee.Create) case delete(id: Employee.ID) case get(id: Employee.ID) case index 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(.json(Employee.Create.self)) } Route(.case(Self.index)) { Path { rootPath } Method.get } Route(.case(Self.delete(id:))) { Path { rootPath; UUID.parser() } Method.delete } Route(.case(Self.get(id:))) { Path { rootPath; UUID.parser() } Method.get } Route(.case(Self.update(id:updates:))) { Path { rootPath; UUID.parser() } Method.put Body(.json(Employee.Update.self)) } } } public enum PurchaseOrderApiRoute: Sendable { case create(PurchaseOrder.Create) case delete(id: PurchaseOrder.ID) case get(id: PurchaseOrder.ID) case index case page(page: Int, limit: Int) static let rootPath = "purchase-orders" public static let router = OneOf { Route(.case(Self.create)) { Path { rootPath } Method.post Body(.json(PurchaseOrder.Create.self)) } Route(.case(Self.delete(id:))) { Path { rootPath; Digits() } Method.delete } 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() } } } } } public enum UserApiRoute: Sendable { case create(User.Create) case delete(id: User.ID) case get(id: User.ID) case index case login(User.Login) 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.get(id:))) { Path { rootPath; User.ID.parser() } Method.get } Route(.case(Self.index)) { Path { rootPath } Method.get } Route(.case(Self.login)) { Path { rootPath } Method.post Body(.json(User.Login.self)) } Route(.case(Self.update(id:updates:))) { Path { rootPath; User.ID.parser() } // TODO: Use put or patch. Method.post Body(.json(User.Update.self)) } } } public enum VendorApiRoute: Sendable { case create(Vendor.Create) 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(.json(Vendor.Create.self)) } Route(.case(Self.get(id:))) { Path { rootPath; Vendor.ID.parser() } Method.get } Route(.case(Self.index)) { Path { rootPath } Method.get } Route(.case(Self.update(id:updates:))) { Path { rootPath; Vendor.ID.parser() } Method.put Body(.json(Vendor.Update.self)) } } } public enum VendorBranchApiRoute: Sendable { case create(VendorBranch.Create) case delete(id: VendorBranch.ID) case get(id: VendorBranch.ID) case update(id: VendorBranch.ID, updates: VendorBranch.Update) public static let router = OneOf { Route(.case(Self.create)) { Path { "vendors"; "branches" } Method.post Body(.json(VendorBranch.Create.self)) } Route(.case(Self.delete(id:))) { Path { "vendors"; "branches"; VendorBranch.ID.parser() } Method.delete } Route(.case(Self.get(id:))) { Path { "vendors"; "branches"; VendorBranch.ID.parser() } Method.get } Route(.case(Self.update(id:updates:))) { Path { "vendors"; "branches"; VendorBranch.ID.parser() } Method.put Body(.json(VendorBranch.Update.self)) } } } }