{"id":13903094,"url":"https://github.com/pointfreeco/swift-web","last_synced_at":"2025-04-04T22:09:21.626Z","repository":{"id":46567125,"uuid":"96431499","full_name":"pointfreeco/swift-web","owner":"pointfreeco","description":"🕸 A collection of Swift server-side frameworks for handling HTML, CSS, routing and middleware.","archived":false,"fork":false,"pushed_at":"2024-07-04T01:03:32.000Z","size":570,"stargazers_count":484,"open_issues_count":0,"forks_count":36,"subscribers_count":13,"default_branch":"main","last_synced_at":"2025-03-28T21:09:40.519Z","etag":null,"topics":["applicative","composition","css","functional-programming","html","middleware","routing","swift"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pointfreeco.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-07-06T13:09:55.000Z","updated_at":"2025-03-14T02:57:56.000Z","dependencies_parsed_at":"2025-01-04T12:52:44.841Z","dependency_job_id":null,"html_url":"https://github.com/pointfreeco/swift-web","commit_stats":{"total_commits":241,"total_committers":7,"mean_commits":34.42857142857143,"dds":0.5726141078838174,"last_synced_commit":"f17cced2173a45cf1879a888e4bd03ae69bd1c6a"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pointfreeco%2Fswift-web","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pointfreeco%2Fswift-web/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pointfreeco%2Fswift-web/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pointfreeco%2Fswift-web/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pointfreeco","download_url":"https://codeload.github.com/pointfreeco/swift-web/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247256115,"owners_count":20909240,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["applicative","composition","css","functional-programming","html","middleware","routing","swift"],"created_at":"2024-08-06T22:01:36.898Z","updated_at":"2025-04-04T22:09:21.602Z","avatar_url":"https://github.com/pointfreeco.png","language":"Swift","funding_links":[],"categories":["Swift"],"sub_categories":[],"readme":"# swift-web\n\n[![CI](https://github.com/pointfreeco/swift-web/workflows/CI/badge.svg)](https://actions-badge.atrox.dev/pointfreeco/swift-web/goto)\n[![Swift 5.3](https://img.shields.io/badge/swift-5.3-ED523F.svg?style=flat)](https://swift.org/download/)\n[![@pointfreeco](https://img.shields.io/badge/contact-@pointfreeco-5AA9E7.svg?style=flat)](https://twitter.com/pointfreeco)\n\nA collection of frameworks for solving various problems in building a Swift web framework. Each framework focuses on a single problem, like HTML rendering, CSS preprocessing, routing, middleware, and more. They also do not depend on any other framework in the collection. You can choose which pieces you want and don't want, for example you can use `Html` without `Css`.\n\n## Stability\n\nThis library should be considered experimental. If you find its contents useful, please consider maintaining a fork.\n\n## Installation\n\n```swift\nimport PackageDescription\n\nlet package = Package(\n  dependencies: [\n    .package(url: \"https://github.com/pointfreeco/swift-web.git\", .branch(\"master\")),\n  ]\n)\n```\n\n## Getting started\n\nThis library contains an extensive test suite and a set of playgrounds that can be explored. To get it running:\n\n* `git clone https://github.com/pointfreeco/swift-web.git`\n* `cd swift-web`\n* `swift package generate-xcodeproj`\n* `xed .`\n* Run tests: Command+U\n* Build: Command+B\n* Open a playground!\n\n## Included modules\n\n#### Primary modules\n\n* [`Css`](#css)\n* [`HttpPipeline`](#httppipeline)\n* [`ApplicativeRouter`](#applicativerouter)\n\n#### Supporting modules\n\n* [`HttpPipelineHtmlSupport`](#httppipelinehtmlsupport)\n* [`HtmlCssSupport`](#htmlcsssupport)\n* [`CssReset`](#cssreset)\n\n## `Css`\n\nAn EDSL for a CSS preprocessor like [Sass](http://sass-lang.com). A few simple value types and functions allow you to model most of CSS, and allow you express new things not possible in standard CSS.\n\n```swift\nimport Css\n\nlet css = body % (\n  padding(all: .rem(2))\n    \u003c\u003e background(Color.hsl(60, 0.5, 0.8))\n)\n\nrender(css: css)\n```\n```css\nbody {\n  padding-top    : 2rem;\n  padding-right  : 2rem;\n  padding-bottom : 2rem;\n  padding-left   : 2rem;\n  background     : #e6e6b3;\n}\n```\n\n## `HttpPipeline`\n\nA few types and functions for modeling server middleware as a simple function that transforms a request to a response. It uses phantom types express the state transitions of when you are allowed to write the status, headers and response body.\n\n```swift\nimport HttpPipeline\n\nlet middleware = writeStatus(.ok)\n  \u003e\u003e\u003e writeHeader(.contentType(.html))\n  \u003e\u003e\u003e closeHeaders\n  \u003e\u003e\u003e send(render(document).data(using: .utf8))\n  \u003e\u003e\u003e end\n\nlet request = URLRequest(url: URL(string: \"/\")!)\nlet conn = connection(from: request).map(const(Data?.none))\n```\n```text\n▿ Step\n  ResponseEnded\n\n▿ Request\n  GET /\n\n  (Data, 0 bytes)\n\n▿ Response\n  Status 200 OK\n  Content-Type: text/html; charset=utf8\n\n  \u003chtml\u003e\u003cbody\u003e\u003cp\u003eHello world!\u003c/p\u003e\u003cp\u003eGoodbye!\u003c/p\u003e\u003ca href=\"/\"\u003eHome\u003c/a\u003e\u003c/body\u003e\u003c/html\u003e\n```\n\n## `ApplicativeRouter`\n\nA router built on the principles of “applicatives” that unifies parsing requests and printing routes. It is robust, composable and type-safe. Its job is to take the incoming, unstructured `URLRequest` from the browser and turn it into a structured value so that your app can do what it needs to do to produce a response. Additionally, given a value, it can do the reverse in which it generates a request that can be used in a hyperlink. Most of the ideas for this library were taking from [this paper](http://www.informatik.uni-marburg.de/~rendel/unparse/).\n\n```swift\nimport ApplicativeRouter\n\nstruct UserData: Decodable {\n  let email: String\n}\n\nenum Route {\n  case home\n  case episodes\n  case episode(String)\n  case search(String?)\n  case signup(UserData?)\n}\n\nlet router = [\n  // Matches: GET /\n  Route.iso.home\n    \u003c¢\u003e .get \u003c% end,\n\n  // Matches: GET /episode/:str\n  Route.iso.episode\n    \u003c¢\u003e get %\u003e lit(\"episode\") %\u003e pathParam(.string) \u003c% end,\n\n  // Matches: GET /episodes\n  Route.iso.episodes\n    \u003c¢\u003e get %\u003e lit(\"episodes\") \u003c% end,\n\n  // Matches: GET /search?query=:optional_string\n  Route.iso.search\n    \u003c¢\u003e get %\u003e lit(\"search\") %\u003e queryParam(\"query\", opt(.string)) \u003c% end,\n\n  // Matches: POST /signup\n  Route.iso.signup\n    \u003c¢\u003e post %\u003e jsonBody(Episode.self) \u003c%\u003e lit(\"signup\") %\u003e opt(.jsonBody)) \u003c% end,\n  ]\n  .reduce(.empty, \u003c|\u003e)\n\n// Match a route given a request\nlet request = URLRequest(url: URL(string: \"https://www.pointfree.co/episode/001-hello-world\")!)\nlet route = router.match(request: request)\n// =\u003e Route.episode(\"001-hello-world\")\n\n// Generate a string from a route:\nrouter.absoluteString(for: .episode(\"001-hello-world\"))\n// =\u003e /episode/001-hello-world\n```\n\n##  `HttpPipelineHtmlSupport`\n\nAdds middleware for rendering an `Html` view:\n\n```swift\nimport Foundation\nimport Html\nimport HttpPipeline\nimport HttpPipelineHtmlSupport\n\nlet view = View(p([\"Hello world!\"]))\n\nlet middleware = writeStatus(.ok)\n  \u003e\u003e\u003e respond(view)\n\nlet conn = connection(from: URLRequest(url: URL(string: \"/\")!))\nmiddleware(conn).response.description\n```\n```text\nStatus 200\nContent-Type: text/html\n\n\u003cp\u003eHello world!\u003c/p\u003e\n```\n\n## `HtmlCssSupport`\n\nAdds an element and attribute function to `Html` for render `Css` values into an internal stylesheet or inline styles. The element function `style` allows you to provide a `Stylesheet` value that will be rendered to an internal stylesheet:\n\n```swift\nimport Css\nimport Html\nimport HtmlCssSupport\n\nlet css = body % background(red)\nlet document = html([head([style(css)])])\nrender(document)\n```\n```html\n\u003chtml\u003e\n  \u003chead\u003e\n    \u003cstyle\u003ebody{background:#ff0000}\u003c/style\u003e\n  \u003c/head\u003e\n\u003c/html\u003e\n```\n\nThe attribute function `style` allows you to render a stylesheet inline directly on an element:\n\n```swift\nimport Css\nimport Html\nimport HtmlCssSupport\n\nlet anchorStyle = color(.red)\n  \u003c\u003e textTransform(.capitalize)\n\nlet styledDocument = p([\n  \"Go back \",\n  a([style(anchorStyle)], [\"Home\"])\n  ])\n\nprint(render(styledDocument, config: pretty))\n```\n```html\n\u003cp\u003e\n  Go back\n  \u003ca style=\"color:#ff0000;text-transform:capitalize\"\u003e\n    Home\n  \u003c/a\u003e\n\u003c/p\u003e\n```\n\n## `CssReset`\n\nContains a single value `reset` of type `Stylesheet` that resets all of the defaults for a webpage. It can be combined with another stylesheet via `reset \u003c\u003e otherStyles`, or can be directly rendered to a stylesheet string via `render(reset)`.\n\n## License\n\nAll modules are released under the MIT license. See [LICENSE](LICENSE) for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpointfreeco%2Fswift-web","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpointfreeco%2Fswift-web","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpointfreeco%2Fswift-web/lists"}