Skip to content

Commit ee91fca

Browse files
authored
Merge pull request #131 from pimbrouwers/develop
v5.0.0
2 parents 25d828d + 07a9a87 commit ee91fca

File tree

134 files changed

+5228
-7128
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

134 files changed

+5228
-7128
lines changed

.github/workflows/build.yml

+10-8
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,15 @@ on:
88
jobs:
99
build:
1010
runs-on: ubuntu-latest
11-
strategy:
12-
matrix:
13-
dotnet-version: ['8.0.x']
1411
steps:
15-
- uses: actions/checkout@v2
12+
- uses: actions/checkout@v4
1613

17-
- name: Setup .NET Core SDK ${{ matrix.dotnet-version }}
18-
uses: actions/setup-dotnet@v3
14+
- name: Setup .NET Core SDK
15+
uses: actions/setup-dotnet@v4
1916
with:
20-
dotnet-version: ${{ matrix.dotnet-version }}
17+
dotnet-version: |
18+
8.0.x
19+
9.0.x
2120
2221
- name: Install dependencies
2322
run: dotnet restore src/Falco
@@ -26,4 +25,7 @@ jobs:
2625
run: dotnet build src/Falco -c Release
2726

2827
- name: Test
29-
run: dotnet test test/Falco.Tests -c Release
28+
run: dotnet test test/Falco.Tests -c Release
29+
30+
- name: Integration Test
31+
run: dotnet test test/Falco.IntegrationTests -c Release

.gitignore

+5-1
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@
99
*.user
1010
*.userosscache
1111
*.sln.docstates
12-
[Ss]amples/[Ss]andbox/
12+
[Ee]xamples/[Ss]andbox/
13+
[Ss]andbox/
1314
*.sqlite
15+
[Mm]emory
1416

1517
# User-specific files (MonoDevelop/Xamarin Studio)
1618
*.userprefs
@@ -354,3 +356,5 @@ MigrationBackup/
354356

355357
# Rider (JetBrain's cross-platform .NET IDE) working folder
356358
.idea/
359+
.vscode/launch.json
360+
.vscode/launch.json

Build.ps1

+20-14
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
[CmdletBinding()]
22
param (
33
[Parameter(HelpMessage="The action to execute.")]
4-
[ValidateSet("Build", "Test", "Pack", "BuildSite", "DevelopSite")]
4+
[ValidateSet("Build", "Test", "IntegrationTest", "Pack", "BuildSite", "DevelopSite")]
55
[string] $Action = "Build",
66

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

11-
[switch] $SkipClean
11+
[switch] $NoRestore,
12+
13+
[switch] $Clean
1214
)
1315

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

2426
switch ($Action) {
25-
"Test" { $projectdir = Join-Path -Path $testDir -ChildPath 'Falco.Tests' }
26-
"Pack" { $projectDir = Join-Path -Path $srcDir -ChildPath 'Falco' }
27-
"BuildSite" { $projectDir = Join-Path -Path $rootDir -ChildPath 'site' }
28-
"DevelopSite" { $projectDir = Join-Path -Path $rootDir -ChildPath 'site' }
29-
Default { $projectDir = Join-Path -Path $srcDir -ChildPath 'Falco' }
27+
"Test" { $projectdir = Join-Path -Path $testDir -ChildPath 'Falco.Tests' }
28+
"IntegrationTest" { $projectdir = Join-Path -Path $testDir -ChildPath 'Falco.IntegrationTests' }
29+
"Pack" { $projectDir = Join-Path -Path $srcDir -ChildPath 'Falco' }
30+
"BuildSite" { $projectDir = Join-Path -Path $rootDir -ChildPath 'site' }
31+
"DevelopSite" { $projectDir = Join-Path -Path $rootDir -ChildPath 'site' }
32+
Default { $projectDir = Join-Path -Path $srcDir -ChildPath 'Falco' }
3033
}
3134

32-
if (!$SkipClean.IsPresent)
33-
{
35+
if(!$NoRestore.IsPresent) {
3436
RunCommand "dotnet restore $projectDir --force --force-evaluate --nologo --verbosity quiet"
37+
}
38+
39+
if ($Clean) {
3540
RunCommand "dotnet clean $projectDir -c $Configuration --nologo --verbosity quiet"
3641
}
3742

3843
switch ($Action) {
39-
"Test" { RunCommand "dotnet test `"$projectDir`"" }
40-
"Pack" { RunCommand "dotnet pack `"$projectDir`" -c $Configuration --include-symbols --include-source" }
41-
"BuildSite" { RunCommand "dotnet build `"$projectDir`" -t:Generate" }
42-
"DevelopSite" { RunCommand "dotnet build `"$projectDir`" -t:Develop" }
43-
Default { RunCommand "dotnet build `"$projectDir`" -c $Configuration" }
44+
"Test" { RunCommand "dotnet test `"$projectDir`"" }
45+
"IntegrationTest" { RunCommand "dotnet test `"$projectDir`"" }
46+
"Pack" { RunCommand "dotnet pack `"$projectDir`" -c $Configuration --include-symbols --include-source" }
47+
"BuildSite" { RunCommand "dotnet build `"$projectDir`" -t:Generate" }
48+
"DevelopSite" { RunCommand "dotnet build `"$projectDir`" -t:Develop" }
49+
Default { RunCommand "dotnet build `"$projectDir`" -c $Configuration" }
4450
}

CHANGELOG.md

+46
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,52 @@
22

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

5+
## [5.0.0] - 2025-01-28
6+
7+
### Added
8+
9+
- Declarative OpenAPI support.
10+
- `RequestData` (and `RequestValue`) to support complex form & query submissions,
11+
- Provided by an HTTP key/value pair (i.e., `name=falco&classification=toolkit`) parser.
12+
- A derivative `FormData` contains parsed `RequestValue` and access to `IFormFileCollection`.
13+
- `HttpContext.Plug<T>` for generic injection support of dependencies within `HttpHandler`'s (service locator pattern).
14+
- `Request.getJson<T>` for generic JSON request deserialization, using default settings (property name case-insensitive, trailing commas allowed).
15+
- `Request.getCookies`, replacing `Request.getCookie`.
16+
- `Response.signInOptions` to sign in claim principal for provided scheme and options then responds with a 301 redirect to provided URL.
17+
- `Response.challengeAndRedirect`, replacing `Response.challengeWithRedirect`.
18+
- `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.
19+
- `Routing.setDisplayName` to set the display name of the endpoint.
20+
- `Routing.setOrder` to set the order number of the endpoint.
21+
- `WebApplication.run`, registers the provided `HttpHandler` as the terminal middleware and runs the application.
22+
23+
### Changed
24+
25+
- `Xss` module renamed to `Xsrf`. Functions: `Xsrf.antiforgeryInput`, `Xsrf.getToken` & `Xsrf.validateToken`.
26+
27+
28+
### Fixed
29+
30+
- Missing cancellation token pass-through during form reading, `multipart/form-data` streaming and JSON serialization/deserialization.
31+
- Empty request body support for JSON request methods.
32+
- `WebApplication.UseFalcoNotFound` & `IApplicationBuilder.UseFalcoNotFound` to correctly terminate by returning `unit` akin to the native method.
33+
34+
### Removed
35+
36+
- `net6.0` support dropped (end of life 2024-11-12).
37+
- `webHost [||] {}` builder removed.
38+
- `config {}` builder removed.
39+
- `HttpContext.GetLogger<T>()` extension removed.
40+
- `IApplicationBuilder.IsDevelopment()`, `IApplicationBuilder.UseWhen()` extensions removed.
41+
- `Services.inject<T>` (and overloads) removed.
42+
- `Response.withContentLength` removed (unsupported).
43+
- `StringCollectionReader` and derivatives removed (`FormCollectionReader`, `QueryCollectionReader`, `RouteCollectionReader`, `HeaderCollectionReader`, and `CookieCollectionReader`).
44+
- All replaced by homogenous `RequestData` type.
45+
- `Request.streamForm`, `Request.streamFormSecure`, `Request.mapFormStream` and `Request.mapFormStreamSecure` removed.
46+
- `Falco.Security.Crypto` and `Falco.Security.Auth` modules removed.
47+
- Removed `Request.getCookie`, renamed `Request.getCookies`.
48+
- Removed `Response.challengeWithRedirect`, renamed `Response.challengeAndRedirect`.
49+
- Removed `Response.debugRequest`.
50+
551
## [4.0.6] - 2023-12-12
652

753
- `net7.0` and `net8.0` support added.

Falco.sln

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.0.31903.59
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{0DDD542C-01AF-4E41-96C8-C8294378CB09}"
7+
EndProject
8+
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Falco", "src\Falco\Falco.fsproj", "{5906904E-00A0-4ED3-8E7A-85B7A7A1A7C9}"
9+
EndProject
10+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{A56030AE-D35C-4EA6-A089-E7950A8DBDBF}"
11+
EndProject
12+
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Falco.IntegrationTests", "test\Falco.IntegrationTests\Falco.IntegrationTests.fsproj", "{D9E5D9CF-D7A8-4DBF-87C0-49FDD3C62848}"
13+
EndProject
14+
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Falco.IntegrationTests.App", "test\Falco.IntegrationTests.App\Falco.IntegrationTests.App.fsproj", "{6BB75729-1E0C-4936-A255-FA2B55CF22BD}"
15+
EndProject
16+
Global
17+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
18+
Debug|Any CPU = Debug|Any CPU
19+
Release|Any CPU = Release|Any CPU
20+
EndGlobalSection
21+
GlobalSection(SolutionProperties) = preSolution
22+
HideSolutionNode = FALSE
23+
EndGlobalSection
24+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
25+
{5906904E-00A0-4ED3-8E7A-85B7A7A1A7C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
26+
{5906904E-00A0-4ED3-8E7A-85B7A7A1A7C9}.Debug|Any CPU.Build.0 = Debug|Any CPU
27+
{5906904E-00A0-4ED3-8E7A-85B7A7A1A7C9}.Release|Any CPU.ActiveCfg = Release|Any CPU
28+
{5906904E-00A0-4ED3-8E7A-85B7A7A1A7C9}.Release|Any CPU.Build.0 = Release|Any CPU
29+
{D9E5D9CF-D7A8-4DBF-87C0-49FDD3C62848}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
30+
{D9E5D9CF-D7A8-4DBF-87C0-49FDD3C62848}.Debug|Any CPU.Build.0 = Debug|Any CPU
31+
{D9E5D9CF-D7A8-4DBF-87C0-49FDD3C62848}.Release|Any CPU.ActiveCfg = Release|Any CPU
32+
{D9E5D9CF-D7A8-4DBF-87C0-49FDD3C62848}.Release|Any CPU.Build.0 = Release|Any CPU
33+
{6BB75729-1E0C-4936-A255-FA2B55CF22BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
34+
{6BB75729-1E0C-4936-A255-FA2B55CF22BD}.Debug|Any CPU.Build.0 = Debug|Any CPU
35+
{6BB75729-1E0C-4936-A255-FA2B55CF22BD}.Release|Any CPU.ActiveCfg = Release|Any CPU
36+
{6BB75729-1E0C-4936-A255-FA2B55CF22BD}.Release|Any CPU.Build.0 = Release|Any CPU
37+
EndGlobalSection
38+
GlobalSection(NestedProjects) = preSolution
39+
{5906904E-00A0-4ED3-8E7A-85B7A7A1A7C9} = {0DDD542C-01AF-4E41-96C8-C8294378CB09}
40+
{D9E5D9CF-D7A8-4DBF-87C0-49FDD3C62848} = {A56030AE-D35C-4EA6-A089-E7950A8DBDBF}
41+
{6BB75729-1E0C-4936-A255-FA2B55CF22BD} = {A56030AE-D35C-4EA6-A089-E7950A8DBDBF}
42+
EndGlobalSection
43+
EndGlobal

README.md

+27-34
Original file line numberDiff line numberDiff line change
@@ -5,55 +5,49 @@
55

66
```fsharp
77
open Falco
8-
open Falco.Routing
9-
open Falco.HostBuilder
10-
11-
webHost [||] {
12-
endpoints [
13-
get "/" (Response.ofPlainText "Hello World")
14-
]
15-
}
8+
open Microsoft.AspNetCore.Builder
9+
10+
let wapp = WebApplication.Create()
11+
12+
wapp.Run(Response.ofPlainText "Hello world")
1613
```
1714

18-
[Falco](https://github.com/pimbrouwers/Falco) is a toolkit for building fast and functional-first web applications using F#.
15+
[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*.
1916

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

2421
## Key Features
2522

26-
- Asynchronous [request handling](https://github.com/pimbrouwers/Falco/tree/master/documentation/response.md).
27-
- Simple and powerful [routing](https://github.com/pimbrouwers/Falco/tree/master/documentation/routing.md) API.
28-
- Fast, secure and configurable [web server](https://github.com/pimbrouwers/Falco/tree/master/documentation/host.md).
29-
- Native F# [view engine](https://github.com/pimbrouwers/Falco.Markup).
30-
- Uniform API for [accessing request data](https://github.com/pimbrouwers/Falco/tree/master/documentation/request.md).
31-
- [Authentication and security](https://github.com/pimbrouwers/Falco/tree/master/documentation/security.md) utilities.
32-
- 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).
23+
- Simple and powerful [routing](documentation/routing.md) API.
24+
- Uniform API for [accessing _any_ request data](documentation/request.md).
25+
- Native F# [view engine](documentation/markup.md).
26+
- Asynchronous [request handling](documentation/response.md).
27+
- [Authentication](documentation/authentication.md) and [security](documentation/cross-site-request-forgery.md) utilities.
28+
- Built-in support for [large uploads](documentation/request.md#multipartform-data-binding) and [binary responses](documentation/response.md#content-disposition).
29+
3330

3431
## Design Goals
3532

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

40-
## Learn
4137

42-
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.
43-
44-
If you want to stay in touch, feel free to reach out on [Twitter](https://twitter.com/falco_framework).
38+
## Learn
4539

46-
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).
40+
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.
4741

4842
### Related Libraries
4943

5044
- [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).
45+
- [Falco.Htmx](https://github.com/dpraimeyuu/Falco.Htmx) - a full featured integration with [htmx JS package](https://htmx.org/).
46+
- [Falco.OpenApi](https://github.com/pimbrouwers/Falco.OpenApi) - a library for generating OpenAPI documentation from Falco applications.
5147
- [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.
52-
- [Falco.Htmx](https://github.com/dpraimeyuu/Falco.Htmx) - An experimental Falco integration with [htmx JS package](https://htmx.org/).
5348

5449
### Community Projects
5550

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

6862
- 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)
6963

70-
## Contribute
7164

72-
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.
65+
## Contribute
7366

7467
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).
7568

69+
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.
7670

77-
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.
78-
79-
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).
80-
81-
Only pull requests which pass all build checks and comply with the general coding guidelines can be approved.
71+
Only pull requests which pass all build checks and comply with the general coding standard can be approved.
8272

8373
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).
8474

75+
8576
## Why "Falco"?
8677

8778
[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".
8879

80+
8981
## Find a bug?
9082

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

85+
9386
## License
9487

95-
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).
88+
Licensed under [Apache License 2.0](https://github.com/pimbrouwers/Falco/blob/master/LICENSE).

0 commit comments

Comments
 (0)