Skip to content

Commit

Permalink
Merge pull request #131 from pimbrouwers/develop
Browse files Browse the repository at this point in the history
v5.0.0
  • Loading branch information
pimbrouwers authored Jan 29, 2025
2 parents 25d828d + 07a9a87 commit ee91fca
Show file tree
Hide file tree
Showing 134 changed files with 5,228 additions and 7,128 deletions.
18 changes: 10 additions & 8 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,15 @@ on:
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
dotnet-version: ['8.0.x']
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4

- name: Setup .NET Core SDK ${{ matrix.dotnet-version }}
uses: actions/setup-dotnet@v3
- name: Setup .NET Core SDK
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ matrix.dotnet-version }}
dotnet-version: |
8.0.x
9.0.x
- name: Install dependencies
run: dotnet restore src/Falco
Expand All @@ -26,4 +25,7 @@ jobs:
run: dotnet build src/Falco -c Release

- name: Test
run: dotnet test test/Falco.Tests -c Release
run: dotnet test test/Falco.Tests -c Release

- name: Integration Test
run: dotnet test test/Falco.IntegrationTests -c Release
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
*.user
*.userosscache
*.sln.docstates
[Ss]amples/[Ss]andbox/
[Ee]xamples/[Ss]andbox/
[Ss]andbox/
*.sqlite
[Mm]emory

# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
Expand Down Expand Up @@ -354,3 +356,5 @@ MigrationBackup/

# Rider (JetBrain's cross-platform .NET IDE) working folder
.idea/
.vscode/launch.json
.vscode/launch.json
34 changes: 20 additions & 14 deletions Build.ps1
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
[CmdletBinding()]
param (
[Parameter(HelpMessage="The action to execute.")]
[ValidateSet("Build", "Test", "Pack", "BuildSite", "DevelopSite")]
[ValidateSet("Build", "Test", "IntegrationTest", "Pack", "BuildSite", "DevelopSite")]
[string] $Action = "Build",

[Parameter(HelpMessage="The msbuild configuration to use.")]
[ValidateSet("Debug", "Release")]
[string] $Configuration = "Debug",

[switch] $SkipClean
[switch] $NoRestore,

[switch] $Clean
)

function RunCommand {
Expand All @@ -22,23 +24,27 @@ $srcDir = Join-Path -Path $rootDir -ChildPath 'src'
$testDir = Join-Path -Path $rootDir -ChildPath 'test'

switch ($Action) {
"Test" { $projectdir = Join-Path -Path $testDir -ChildPath 'Falco.Tests' }
"Pack" { $projectDir = Join-Path -Path $srcDir -ChildPath 'Falco' }
"BuildSite" { $projectDir = Join-Path -Path $rootDir -ChildPath 'site' }
"DevelopSite" { $projectDir = Join-Path -Path $rootDir -ChildPath 'site' }
Default { $projectDir = Join-Path -Path $srcDir -ChildPath 'Falco' }
"Test" { $projectdir = Join-Path -Path $testDir -ChildPath 'Falco.Tests' }
"IntegrationTest" { $projectdir = Join-Path -Path $testDir -ChildPath 'Falco.IntegrationTests' }
"Pack" { $projectDir = Join-Path -Path $srcDir -ChildPath 'Falco' }
"BuildSite" { $projectDir = Join-Path -Path $rootDir -ChildPath 'site' }
"DevelopSite" { $projectDir = Join-Path -Path $rootDir -ChildPath 'site' }
Default { $projectDir = Join-Path -Path $srcDir -ChildPath 'Falco' }
}

if (!$SkipClean.IsPresent)
{
if(!$NoRestore.IsPresent) {
RunCommand "dotnet restore $projectDir --force --force-evaluate --nologo --verbosity quiet"
}

if ($Clean) {
RunCommand "dotnet clean $projectDir -c $Configuration --nologo --verbosity quiet"
}

switch ($Action) {
"Test" { RunCommand "dotnet test `"$projectDir`"" }
"Pack" { RunCommand "dotnet pack `"$projectDir`" -c $Configuration --include-symbols --include-source" }
"BuildSite" { RunCommand "dotnet build `"$projectDir`" -t:Generate" }
"DevelopSite" { RunCommand "dotnet build `"$projectDir`" -t:Develop" }
Default { RunCommand "dotnet build `"$projectDir`" -c $Configuration" }
"Test" { RunCommand "dotnet test `"$projectDir`"" }
"IntegrationTest" { RunCommand "dotnet test `"$projectDir`"" }
"Pack" { RunCommand "dotnet pack `"$projectDir`" -c $Configuration --include-symbols --include-source" }
"BuildSite" { RunCommand "dotnet build `"$projectDir`" -t:Generate" }
"DevelopSite" { RunCommand "dotnet build `"$projectDir`" -t:Develop" }
Default { RunCommand "dotnet build `"$projectDir`" -c $Configuration" }
}
46 changes: 46 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,52 @@

All notable changes to this project will be documented in this file.

## [5.0.0] - 2025-01-28

### Added

- Declarative OpenAPI support.
- `RequestData` (and `RequestValue`) to support complex form & query submissions,
- Provided by an HTTP key/value pair (i.e., `name=falco&classification=toolkit`) parser.
- A derivative `FormData` contains parsed `RequestValue` and access to `IFormFileCollection`.
- `HttpContext.Plug<T>` for generic injection support of dependencies within `HttpHandler`'s (service locator pattern).
- `Request.getJson<T>` for generic JSON request deserialization, using default settings (property name case-insensitive, trailing commas allowed).
- `Request.getCookies`, replacing `Request.getCookie`.
- `Response.signInOptions` to sign in claim principal for provided scheme and options then responds with a 301 redirect to provided URL.
- `Response.challengeAndRedirect`, replacing `Response.challengeWithRedirect`.
- `Routing.map[Get|Head|Post|Put|Patch|Delete|Options|Trace|Any]` which produces `HttpEndpoint` by associating a route pattern to an `HttpHandler` after mapping route.
- `Routing.setDisplayName` to set the display name of the endpoint.
- `Routing.setOrder` to set the order number of the endpoint.
- `WebApplication.run`, registers the provided `HttpHandler` as the terminal middleware and runs the application.

### Changed

- `Xss` module renamed to `Xsrf`. Functions: `Xsrf.antiforgeryInput`, `Xsrf.getToken` & `Xsrf.validateToken`.


### Fixed

- Missing cancellation token pass-through during form reading, `multipart/form-data` streaming and JSON serialization/deserialization.
- Empty request body support for JSON request methods.
- `WebApplication.UseFalcoNotFound` & `IApplicationBuilder.UseFalcoNotFound` to correctly terminate by returning `unit` akin to the native method.

### Removed

- `net6.0` support dropped (end of life 2024-11-12).
- `webHost [||] {}` builder removed.
- `config {}` builder removed.
- `HttpContext.GetLogger<T>()` extension removed.
- `IApplicationBuilder.IsDevelopment()`, `IApplicationBuilder.UseWhen()` extensions removed.
- `Services.inject<T>` (and overloads) removed.
- `Response.withContentLength` removed (unsupported).
- `StringCollectionReader` and derivatives removed (`FormCollectionReader`, `QueryCollectionReader`, `RouteCollectionReader`, `HeaderCollectionReader`, and `CookieCollectionReader`).
- All replaced by homogenous `RequestData` type.
- `Request.streamForm`, `Request.streamFormSecure`, `Request.mapFormStream` and `Request.mapFormStreamSecure` removed.
- `Falco.Security.Crypto` and `Falco.Security.Auth` modules removed.
- Removed `Request.getCookie`, renamed `Request.getCookies`.
- Removed `Response.challengeWithRedirect`, renamed `Response.challengeAndRedirect`.
- Removed `Response.debugRequest`.

## [4.0.6] - 2023-12-12

- `net7.0` and `net8.0` support added.
Expand Down
43 changes: 43 additions & 0 deletions Falco.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{0DDD542C-01AF-4E41-96C8-C8294378CB09}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Falco", "src\Falco\Falco.fsproj", "{5906904E-00A0-4ED3-8E7A-85B7A7A1A7C9}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{A56030AE-D35C-4EA6-A089-E7950A8DBDBF}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Falco.IntegrationTests", "test\Falco.IntegrationTests\Falco.IntegrationTests.fsproj", "{D9E5D9CF-D7A8-4DBF-87C0-49FDD3C62848}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Falco.IntegrationTests.App", "test\Falco.IntegrationTests.App\Falco.IntegrationTests.App.fsproj", "{6BB75729-1E0C-4936-A255-FA2B55CF22BD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{5906904E-00A0-4ED3-8E7A-85B7A7A1A7C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5906904E-00A0-4ED3-8E7A-85B7A7A1A7C9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5906904E-00A0-4ED3-8E7A-85B7A7A1A7C9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5906904E-00A0-4ED3-8E7A-85B7A7A1A7C9}.Release|Any CPU.Build.0 = Release|Any CPU
{D9E5D9CF-D7A8-4DBF-87C0-49FDD3C62848}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D9E5D9CF-D7A8-4DBF-87C0-49FDD3C62848}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D9E5D9CF-D7A8-4DBF-87C0-49FDD3C62848}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D9E5D9CF-D7A8-4DBF-87C0-49FDD3C62848}.Release|Any CPU.Build.0 = Release|Any CPU
{6BB75729-1E0C-4936-A255-FA2B55CF22BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6BB75729-1E0C-4936-A255-FA2B55CF22BD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6BB75729-1E0C-4936-A255-FA2B55CF22BD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6BB75729-1E0C-4936-A255-FA2B55CF22BD}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{5906904E-00A0-4ED3-8E7A-85B7A7A1A7C9} = {0DDD542C-01AF-4E41-96C8-C8294378CB09}
{D9E5D9CF-D7A8-4DBF-87C0-49FDD3C62848} = {A56030AE-D35C-4EA6-A089-E7950A8DBDBF}
{6BB75729-1E0C-4936-A255-FA2B55CF22BD} = {A56030AE-D35C-4EA6-A089-E7950A8DBDBF}
EndGlobalSection
EndGlobal
61 changes: 27 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,55 +5,49 @@

```fsharp
open Falco
open Falco.Routing
open Falco.HostBuilder
webHost [||] {
endpoints [
get "/" (Response.ofPlainText "Hello World")
]
}
open Microsoft.AspNetCore.Builder
let wapp = WebApplication.Create()
wapp.Run(Response.ofPlainText "Hello world")
```

[Falco](https://github.com/pimbrouwers/Falco) is a toolkit for building fast and functional-first web applications using F#.
[Falco](https://github.com/pimbrouwers/Falco) is a toolkit for building fast and functional-first web applications using F#. You can think of it as [minimal API](https://learn.microsoft.com/en-us/aspnet/core/tutorials/min-web-api?view=aspnetcore-8.0&tabs=visual-studio) on *steroids*.

- Built upon the high-performance components of ASP.NET Core.
- Optimized for building HTTP applications quickly.
- Designed for building pure F# full-stack web applications.
- Built on the high-performance components of ASP.NET Core.
- Seamlessly integrates with existing .NET Core middleware and libraries.

## Key Features

- Asynchronous [request handling](https://github.com/pimbrouwers/Falco/tree/master/documentation/response.md).
- Simple and powerful [routing](https://github.com/pimbrouwers/Falco/tree/master/documentation/routing.md) API.
- Fast, secure and configurable [web server](https://github.com/pimbrouwers/Falco/tree/master/documentation/host.md).
- Native F# [view engine](https://github.com/pimbrouwers/Falco.Markup).
- Uniform API for [accessing request data](https://github.com/pimbrouwers/Falco/tree/master/documentation/request.md).
- [Authentication and security](https://github.com/pimbrouwers/Falco/tree/master/documentation/security.md) utilities.
- Built-in support for [large uploads](https://github.com/pimbrouwers/Falco/tree/master/documentation/request.md#multipartform-data-binding) and [binary responses](https://github.com/pimbrouwers/Falco/tree/master/documentation/response.md#content-disposition).
- Simple and powerful [routing](documentation/routing.md) API.
- Uniform API for [accessing _any_ request data](documentation/request.md).
- Native F# [view engine](documentation/markup.md).
- Asynchronous [request handling](documentation/response.md).
- [Authentication](documentation/authentication.md) and [security](documentation/cross-site-request-forgery.md) utilities.
- Built-in support for [large uploads](documentation/request.md#multipartform-data-binding) and [binary responses](documentation/response.md#content-disposition).


## Design Goals

- Provide a toolset to build a working full-stack web application.
- Provide a toolset to build full-stack web application in F#.
- Should be simple, extensible and integrate with existing .NET libraries.
- Can be easily learned.

## Learn

The best way to get started is by visiting the [documentation](https://falcoframework.com/docs). For questions and support please use [discussions](https://github.com/pimbrouwers/Falco/discussions). The issue list of this repo is **exclusively** for bug reports and feature requests. For chronological updates refer to the [changelog](CHANGELOG.md) is the best place to find chronological updates.

If you want to stay in touch, feel free to reach out on [Twitter](https://twitter.com/falco_framework).
## Learn

Have an article or video that you want to share? We'd love to hear from you! To add your content, visit this [discussion](https://github.com/pimbrouwers/Falco/discussions/82).
The best way to get started is by visiting the [documentation](https://falcoframework.com/docs). For questions and support please use [discussions](https://github.com/pimbrouwers/Falco/discussions). For chronological updates refer to the [changelog](CHANGELOG.md) is the best place to find chronological updates.

### Related Libraries

- [Falco.Markup](https://github.com/pimbrouwers/Falco.Markup) - an XML markup module primary used as the syntax for [authoring HTML with Falco](https://www.falcoframework.com/docs/markup.html).
- [Falco.Htmx](https://github.com/dpraimeyuu/Falco.Htmx) - a full featured integration with [htmx JS package](https://htmx.org/).
- [Falco.OpenApi](https://github.com/pimbrouwers/Falco.OpenApi) - a library for generating OpenAPI documentation from Falco applications.
- [Falco.Template](https://github.com/pimbrouwers/Falco.Template) - a .NET SDK [project template](https://learn.microsoft.com/en-us/dotnet/core/tools/custom-templates) to help get started with Falco quickly.
- [Falco.Htmx](https://github.com/dpraimeyuu/Falco.Htmx) - An experimental Falco integration with [htmx JS package](https://htmx.org/).

### Community Projects

- [FalcoJournal](https://github.com/pimbrouwers/FalcoJournal) - A bullet journal built with Falco, .NET 5.x and ASP.NET Core.
- [Falco GraphQL Sample](https://github.com/adelarsq/falco_graphql_sample) - A sample showing how to use GraphQL on Falco using .NET 6.
- [Falco API with Tests Sample](https://github.com/jasiozet/falco-api-with-tests-template) - A sample project using Falco and unit testing.
- [Falco + SQLite + Donald](https://github.com/galassie/FalcoSample) - A demo project using Falco, [Donald](https://github.com/pimbrouwers/Donald), and SQLite
Expand All @@ -67,29 +61,28 @@ Have an article or video that you want to share? We'd love to hear from you! To

- Ben Gobeil - [Why I'm Using Falco Instead Of Saturn | How To Switch Your Backend In SAFE Stack | StonkWatch Ep.13](https://youtu.be/DTy5gIUWvpo)

## Contribute

Thank you for considering contributing to Falco, and to those who have already contributed! We appreciate (and actively resolve) PRs of all shapes and sizes.
## Contribute

We kindly ask that before submitting a pull request, you first submit an [issue](https://github.com/pimbrouwers/Falco/issues) or open a [discussion](https://github.com/pimbrouwers/Falco/discussions).

If functionality is added to the API, or changed, please kindly update the relevant [document](docs). Unit tests must also be added and/or updated before a pull request can be successfully merged.

If functionality is added to the API, or changed, please kindly update the relevant [document](https://github.com/pimbrouwers/Falco/tree/master/docs). Unit tests must also be added and/or updated before a pull request can be successfully merged.

All pull requests should originate from the `develop` branch. A merge into this branch means that your changes are scheduled to go into production with the very next release, which could happen any time from the same day up to a couple weeks (depending on priorities and urgency).

Only pull requests which pass all build checks and comply with the general coding guidelines can be approved.
Only pull requests which pass all build checks and comply with the general coding standard can be approved.

If you have any further questions, submit an [issue](https://github.com/pimbrouwers/Falco/issues) or open a [discussion](https://github.com/pimbrouwers/Falco/discussions) or reach out on [Twitter](https://twitter.com/falco_framework).


## Why "Falco"?

[Kestrel](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel) has been a game changer for the .NET web stack. In the animal kingdom, "Kestrel" is a name given to several members of the falcon genus. Also known as "Falco".


## Find a bug?

There's an [issue](https://github.com/pimbrouwers/Falco/issues) for that.


## License

Built with ♥ by [Pim Brouwers](https://github.com/pimbrouwers) in Toronto, ON. Licensed under [Apache License 2.0](https://github.com/pimbrouwers/Falco/blob/master/LICENSE).
Licensed under [Apache License 2.0](https://github.com/pimbrouwers/Falco/blob/master/LICENSE).
Loading

0 comments on commit ee91fca

Please sign in to comment.