diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md
new file mode 100644
index 00000000..8b5bda2a
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug.md
@@ -0,0 +1,24 @@
+---
+name: Bug
+about: Create a report to warn us about a bug
+title: "fix: "
+labels: bug
+---
+
+**What happened**
+
+A simple and clear description of what the bug is.
+
+**Code**
+
+```dart
+void main() {
+
+ /// your code goes here
+
+}
+```
+
+**What should have happened**
+
+A simple and clear description of what you expected to happen.
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 00000000..ec4bb386
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1 @@
+blank_issues_enabled: false
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/feature.md b/.github/ISSUE_TEMPLATE/feature.md
new file mode 100644
index 00000000..5e372f21
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature.md
@@ -0,0 +1,15 @@
+---
+name: Feature
+about: A new feature to be added to the project
+title: "feat: "
+labels: feature
+---
+
+**Description**
+
+Clearly describe what you are looking to add. The more context the better.
+
+**Requirements**
+
+- [ ] Checklist of requirements to be fulfilled
+- [ ] Another requirement
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 00000000..5c101cf1
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,26 @@
+# Description
+
+Please include a summary of the changes and the related issue. Please also include relevant motivation and context. List any dependencies that are required for this change.
+
+Fixes # (issue)
+
+## Type of change
+
+Please delete options that are not relevant.
+
+- [ ] Bug fix (non-breaking change which fixes an issue)
+- [ ] New feature (non-breaking change which adds functionality)
+- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
+- [ ] This change requires a documentation update
+
+# Checklist:
+
+- [ ] My code follows the style guidelines of this project
+- [ ] I have performed a self-review of my code
+- [ ] I have commented my code, particularly in hard-to-understand areas
+- [ ] I have made corresponding changes to the documentation
+- [ ] My changes generate no new warnings
+- [ ] I have added tests that prove my fix is effective or that my feature works
+- [ ] New and existing unit tests pass locally with my changes
+- [ ] Any dependent changes have been merged and published in downstream modules
+
diff --git a/.github/workflows/serinus_docs_deploy.yml b/.github/workflows/serinus_docs_deploy.yml
index f87b662e..bf92be3f 100644
--- a/.github/workflows/serinus_docs_deploy.yml
+++ b/.github/workflows/serinus_docs_deploy.yml
@@ -4,6 +4,7 @@ on:
push:
branches:
- main
+ - 'docs/**'
pull_request:
types: [opened, synchronize, reopened, closed]
branches:
diff --git a/.github/workflows/serinus_tests.yml b/.github/workflows/serinus_tests.yml
index f8b6d537..337219d8 100644
--- a/.github/workflows/serinus_tests.yml
+++ b/.github/workflows/serinus_tests.yml
@@ -29,14 +29,15 @@ jobs:
run: |
dart pub global activate coverage
export SERINUS_TEST=true
- dart test --coverage=coverage test/serinus.dart && dart pub global run coverage:format_coverage --lcov --in=coverage --out=coverage/lcov.info --packages=.dart_tool/package_config.json --report-on=${{inputs.report_on}}
+ dart test --coverage=coverage && dart pub global run coverage:format_coverage --lcov --in=coverage --out=coverage/lcov.info --packages=.dart_tool/package_config.json --report-on=${{inputs.report_on}}
- name: 📊 Check Code Coverage
uses: VeryGoodOpenSource/very_good_coverage@v2
with:
path: ./packages/serinus/coverage/lcov.info
- min_coverage: 70
+ min_coverage: 80
- name: Upload coverage reports to Codecov
- uses: codecov/codecov-action@v3
-
+ uses: codecov/codecov-action@v4
+ env:
+ CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
diff --git a/.website/.vitepress/config.mts b/.website/.vitepress/config.mts
index 3694caee..38103cac 100644
--- a/.website/.vitepress/config.mts
+++ b/.website/.vitepress/config.mts
@@ -11,18 +11,20 @@ export default defineConfig({
],
lastUpdated: true,
themeConfig: {
+ footer: {
+ copyright: 'Copyright © 2024 Francesco Vallone',
+ message: 'Built with 💙 and Dart 🎯 | One of the 🐤 of Serinus Nest'
+ },
// https://vitepress.dev/reference/default-theme-config
logo: '/serinus-logo.png',
nav: [
{
text: 'pub.dev',
link: 'https://pub.dev/packages/serinus'
- }
+ },
],
sidebar: [
{
- text: 'Serinus - Dart Backend Framework',
- link: '/',
items: [
{ text: 'Introduction', link: '/introduction' },
{
@@ -44,6 +46,15 @@ export default defineConfig({
{ text: 'Model View Controller', link: '/techniques/mvc' },
{ text: 'Versioning', link: '/techniques/versioning' },
]
+ },
+ {
+ text: 'Plugins',
+ items: [
+ { text: 'Configuration', link: '/plugins/configuration' },
+ { text: 'Serve Static Files [WIP]' },
+ { text: 'Swagger [WIP]' }
+ ],
+ link: '/plugins/'
}
]
},
@@ -54,7 +65,8 @@ export default defineConfig({
],
socialLinks: [
{ icon: 'github', link: 'https://github.com/francescovallone/serinus' },
- { icon: 'twitter', link: 'https://twitter.com/serinus_nest'}
+ { icon: 'twitter', link: 'https://twitter.com/serinus_nest'},
+ { icon: 'discord', link: 'https://discord.gg/zydgnJ3ksJ' }
]
}
})
\ No newline at end of file
diff --git a/.website/.vitepress/theme/style.css b/.website/.vitepress/theme/style.css
index e1ca0654..37741b9b 100644
--- a/.website/.vitepress/theme/style.css
+++ b/.website/.vitepress/theme/style.css
@@ -92,7 +92,7 @@
}
.image-bg {
- background-image: linear-gradient(-45deg, hsla(36, 100%, 75%, 0.5) 50%, hsla(36, 100%, 50%, 0.5) 50%) !important;
- background-image: -moz-linear-gradient(-45deg, hsla(36, 100%, 75%, 0.5) 50%, hsla(36, 100%, 50%, 0.5) 50%) !important;
- background-image: -webkit-linear-gradient(-45deg, hsla(36, 100%, 75%, 0.5) 50%, hsla(36, 100%, 50%, 0.5) 50%) !important;
+ background-image: linear-gradient(-45deg, rgba(255, 152, 0, 0.6) 50%, rgba(245, 124, 0, 0.6) 50%) !important;
+ background-image: -moz-linear-gradient(-45deg, rgba(255, 152, 0, 0.6) 50%, rgba(245, 124, 0, 0.6) 50%) !important;
+ background-image: -webkit-linear-gradient(-45deg, rgba(255, 152, 0, 0.6) 50%, rgba(245, 124, 0, 0.6) 50%) !important;
}
\ No newline at end of file
diff --git a/.website/overview/pipes.md b/.website/overview/pipes.md
index 73a527db..9d5686f8 100644
--- a/.website/overview/pipes.md
+++ b/.website/overview/pipes.md
@@ -26,7 +26,7 @@ import 'package:serinus/serinus.dart';
class MyController extends Controller {
MyController({super.path = '/'}) {
- on(GetRoute(path: '/'), (context, request) {
+ on(GetRoute(path: '/'), (context) {
return Response.text(
data: 'Hello World!',
);
diff --git a/.website/overview/providers.md b/.website/overview/providers.md
index 14fce08a..e7eb1588 100644
--- a/.website/overview/providers.md
+++ b/.website/overview/providers.md
@@ -56,15 +56,14 @@ If you want to use a provider from a submodule, you must add the `Type` of the p
import 'package:serinus/serinus.dart';
class MyController extends Controller {
- MyController({super.path = '/'});
-
- @override
- Future handle(Request request) async {
- final myProvider = context.get();
- return Response.text(
- data: 'Hello World!',
- );
+ MyController({super.path = '/'}){
+ on(GetRoute(path: '/'), (context) {
+ return Response.text(
+ data: context.use().myMethod(),
+ );
+ });
}
+
}
```
diff --git a/.website/overview/routes.md b/.website/overview/routes.md
index d7b76f95..01788e2e 100644
--- a/.website/overview/routes.md
+++ b/.website/overview/routes.md
@@ -8,6 +8,7 @@ They only exposes the endpoint and the method that the route will respond to so
To add routes you first need to create a class that extends the `Route` class and then add it to the controller using the `on` method.
::: code-group
+
```dart [my_controller.dart]
import 'package:serinus/serinus.dart';
import 'my_routes.dart';
@@ -22,6 +23,7 @@ class MyController extends Controller {
}
}
```
+
```dart [my_routes.dart]
import 'package:serinus/serinus.dart';
@@ -34,6 +36,7 @@ class GetRoute extends Route {
}
```
+
:::
## Query Parameters
@@ -61,6 +64,7 @@ class GetRoute extends Route {
To define a path parameter you need to add the parameter name between `<` and `>` in the path of the route.
::: code-group
+
```dart [my_controller.dart]
import 'package:serinus/serinus.dart';
@@ -76,6 +80,7 @@ class MyController extends Controller {
}
}
```
+
```dart [my_routes.dart]
import 'package:serinus/serinus.dart';
@@ -88,6 +93,7 @@ class GetRoute extends Route {
}
```
+
:::
## Adding Pipes
diff --git a/.website/plugins/configuration.md b/.website/plugins/configuration.md
new file mode 100644
index 00000000..ac624e70
--- /dev/null
+++ b/.website/plugins/configuration.md
@@ -0,0 +1,45 @@
+# Config
+
+Serinus Config is a plugin that allows to load .env files in your Serinus application.
+
+::: warning
+This plugin uses the [dotenv](https://pub.dev/packages/dotenv) package to load the .env files.
+:::
+
+## Installation
+
+The installation of the plugin is immediate and can be done using the following command:
+
+```bash
+dart pub add serinus_config
+```
+
+## Usage
+
+To use the plugin, you need to import it in your entrypoint module:
+
+```dart
+import 'package:serinus_config/serinus_config.dart';
+import 'package:serinus/serinus.dart';
+
+class AppModule extends Module {
+
+ AppModule() : super(imports: [ConfigModule()]);
+
+}
+```
+
+### Options
+
+The plugin allows you to specify the path of the .env file to load using the `dotEnvPath` parameter. The default value is `.env`.
+
+```dart
+import 'package:serinus_config/serinus_config.dart';
+import 'package:serinus/serinus.dart';
+
+class AppModule extends Module {
+
+ AppModule() : super(imports: [ConfigModule(dotEnvPath: '.env')]);
+
+}
+```
diff --git a/.website/plugins/index.md b/.website/plugins/index.md
new file mode 100644
index 00000000..76d71676
--- /dev/null
+++ b/.website/plugins/index.md
@@ -0,0 +1,7 @@
+# Plugins
+
+This is a list of plugins that are available for Serinus. If you would like to add your own plugin, please submit a pull request to the [Serinus GitHub repository](https://github.com/francescovallone/serinus).
+
+## Official Plugins
+
+- [Configuration](/plugins/configuration)
diff --git a/.website/techniques/mvc.md b/.website/techniques/mvc.md
index 0a03d4ae..ee212152 100644
--- a/.website/techniques/mvc.md
+++ b/.website/techniques/mvc.md
@@ -76,7 +76,7 @@ import 'package:serinus/serinus.dart';
class MyController extends Controller {
MyController({super.path = '/'}) {
- on(GetRoute(path: '/'), (context, request) {
+ on(GetRoute(path: '/'), (context) {
// This refers to the view file `views/index.mustache`
return Response.render(View(view: 'index', variables: {'name': 'Serinus'}));
});
@@ -89,7 +89,7 @@ import 'package:serinus/serinus.dart';
class MyController extends Controller {
MyController({super.path = '/'}) {
- on(GetRoute(path: '/'), (context, request) {
+ on(GetRoute(path: '/'), (context) {
return Response.renderString(ViewString(viewData: 'Hello {{name}}', variables: {'name': 'Serinus'}));
});
}
diff --git a/.website/techniques/versioning.md b/.website/techniques/versioning.md
index 2c78fbff..5dbd85dc 100644
--- a/.website/techniques/versioning.md
+++ b/.website/techniques/versioning.md
@@ -77,7 +77,7 @@ class MyController extends Controller {
int get version => 2;
MyController({super.path = '/'}) {
- on(GetRoute(path: '/'), (context, request) {
+ on(GetRoute(path: '/'), (context) {
return Response.text('Hello, World!');
});
}
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 00000000..67fe8cee
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,132 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+We as members, contributors, and leaders pledge to make participation in our
+community a harassment-free experience for everyone, regardless of age, body
+size, visible or invisible disability, ethnicity, sex characteristics, gender
+identity and expression, level of experience, education, socio-economic status,
+nationality, personal appearance, race, caste, color, religion, or sexual
+identity and orientation.
+
+We pledge to act and interact in ways that contribute to an open, welcoming,
+diverse, inclusive, and healthy community.
+
+## Our Standards
+
+Examples of behavior that contributes to a positive environment for our
+community include:
+
+* Demonstrating empathy and kindness toward other people
+* Being respectful of differing opinions, viewpoints, and experiences
+* Giving and gracefully accepting constructive feedback
+* Accepting responsibility and apologizing to those affected by our mistakes,
+ and learning from the experience
+* Focusing on what is best not just for us as individuals, but for the overall
+ community
+
+Examples of unacceptable behavior include:
+
+* The use of sexualized language or imagery, and sexual attention or advances of
+ any kind
+* Trolling, insulting or derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or email address,
+ without their explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+ professional setting
+
+## Enforcement Responsibilities
+
+Community leaders are responsible for clarifying and enforcing our standards of
+acceptable behavior and will take appropriate and fair corrective action in
+response to any behavior that they deem inappropriate, threatening, offensive,
+or harmful.
+
+Community leaders have the right and responsibility to remove, edit, or reject
+comments, commits, code, wiki edits, issues, and other contributions that are
+not aligned to this Code of Conduct, and will communicate reasons for moderation
+decisions when appropriate.
+
+## Scope
+
+This Code of Conduct applies within all community spaces, and also applies when
+an individual is officially representing the community in public spaces.
+Examples of representing our community include using an official email address,
+posting via an official social media account, or acting as an appointed
+representative at an online or offline event.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported to the community leaders responsible for enforcement at
+[INSERT CONTACT METHOD].
+All complaints will be reviewed and investigated promptly and fairly.
+
+All community leaders are obligated to respect the privacy and security of the
+reporter of any incident.
+
+## Enforcement Guidelines
+
+Community leaders will follow these Community Impact Guidelines in determining
+the consequences for any action they deem in violation of this Code of Conduct:
+
+### 1. Correction
+
+**Community Impact**: Use of inappropriate language or other behavior deemed
+unprofessional or unwelcome in the community.
+
+**Consequence**: A private, written warning from community leaders, providing
+clarity around the nature of the violation and an explanation of why the
+behavior was inappropriate. A public apology may be requested.
+
+### 2. Warning
+
+**Community Impact**: A violation through a single incident or series of
+actions.
+
+**Consequence**: A warning with consequences for continued behavior. No
+interaction with the people involved, including unsolicited interaction with
+those enforcing the Code of Conduct, for a specified period of time. This
+includes avoiding interactions in community spaces as well as external channels
+like social media. Violating these terms may lead to a temporary or permanent
+ban.
+
+### 3. Temporary Ban
+
+**Community Impact**: A serious violation of community standards, including
+sustained inappropriate behavior.
+
+**Consequence**: A temporary ban from any sort of interaction or public
+communication with the community for a specified period of time. No public or
+private interaction with the people involved, including unsolicited interaction
+with those enforcing the Code of Conduct, is allowed during this period.
+Violating these terms may lead to a permanent ban.
+
+### 4. Permanent Ban
+
+**Community Impact**: Demonstrating a pattern of violation of community
+standards, including sustained inappropriate behavior, harassment of an
+individual, or aggression toward or disparagement of classes of individuals.
+
+**Consequence**: A permanent ban from any sort of public interaction within the
+community.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage],
+version 2.1, available at
+[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
+
+Community Impact Guidelines were inspired by
+[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
+
+For answers to common questions about this code of conduct, see the FAQ at
+[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
+[https://www.contributor-covenant.org/translations][translations].
+
+[homepage]: https://www.contributor-covenant.org
+[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
+[Mozilla CoC]: https://github.com/mozilla/diversity
+[FAQ]: https://www.contributor-covenant.org/faq
+[translations]: https://www.contributor-covenant.org/translations
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 00000000..5475d264
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,21 @@
+# Contributing to Serinus
+
+First off, thank you for considering contributing to Serinus. I'm glad that you want to help us grow this project. 🎉
+
+## Code of Conduct
+
+This project and everyone participating in it is governed by our [Code of Conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to [Francesco Vallone](mailto:vallonefrancesco587@gmail.com).
+
+## How Can I Contribute?
+
+### Reporting Bugs
+
+This section guides you through submitting a bug report for Serinus. Following these guidelines helps maintainers and the community understand your report, reproduce the behavior, and find related reports.
+
+Before creating bug reports, please check the [issues list](https://github.com/francescovallone/serinus/issues) as you might find out that you don't need to create one. When you are creating a bug report, please include as many details as possible. Fill out the required template since the information it asks for helps us resolve issues faster. Please be aware that I'm a one-man team and I might not be able to address your issue immediately but I'll do my best to help you.
+
+### Suggesting Enhancements
+
+This section guides you through submitting an enhancement suggestion for Serinus, including completely new features and minor improvements to existing functionality. Following these guidelines helps maintainers and the community understand your suggestion and find related suggestions.
+
+Before creating enhancement suggestions, please check the [issues list](https://github.com/francescovallone/serinus/issues) as you might find out that you don't need to create one. When you are creating an enhancement suggestion, please include as many details as possible. Fill in the template, including the steps that you imagine you would take if the feature you're requesting existed. Please be aware that not all suggestions will be accepted because there are a lot of factors to consider but regardless I'll look into it and will try to find a solution.
diff --git a/benchmarks/all_results.md b/benchmarks/all_results.md
index 503f3abb..5f7a7ca5 100644
--- a/benchmarks/all_results.md
+++ b/benchmarks/all_results.md
@@ -1,6 +1,6 @@
| | Req/sec | Trans/sec | Req/sec DIFF | Avg Latency |
|----------------|---------|-----------|-------------|-----------|
- | dart_frog (no_cli) | 28649.98 | 7.08MB | +0.00% | 44.57 |
- | shelf | 28770.78 | 7.00MB | +0.42% | 39.46 |
- | serinus | 30169.86 | 6.24MB | +5.30% | 37.69 |
- | pharaoh | 31479.41 | 4.32MB | +9.88% | 38.33 |
\ No newline at end of file
+ | shelf | 29758.27 | 7.24MB | +0.00% | 39.4 |
+ | dart_frog (no_cli) | 29766.17 | 7.35MB | +0.03% | 42.08 |
+ | serinus | 31844.3 | 6.01MB | +7.01% | 36.07 |
+ | pharaoh | 32743.85 | 4.50MB | +10.03% | 37.62 |
\ No newline at end of file
diff --git a/benchmarks/angel3_result.md b/benchmarks/angel3_result.md
new file mode 100644
index 00000000..7905de60
--- /dev/null
+++ b/benchmarks/angel3_result.md
@@ -0,0 +1,15 @@
+## angel3
+### Requests per second
+Requests/sec: 21782.05
+Transfer/sec: 5.07MB
+Requests/sec DIFF: +0.00%
+### Latency
+Avg Latency: 58.24
+Stdev Latency: 107.41
+Max Latency: 1.43
+Stdev Perc: 97.31
+### Req/Sec
+Rps Avg: 2.74
+Rps Max: 3.23
+Rps Stdev: 405.3
+Rps Perc: 92.25
\ No newline at end of file
diff --git a/benchmarks/bin/benchmarks.dart b/benchmarks/bin/benchmarks.dart
index 3ed0be60..30a718b6 100644
--- a/benchmarks/bin/benchmarks.dart
+++ b/benchmarks/bin/benchmarks.dart
@@ -10,7 +10,7 @@ Future main(List arguments) async {
results['serinus'] = await benchmarks.SerinusAppBenchmark().report();
// results['vania (no_cli)'] = await benchmarks.VaniaAppBenchmark().report();
results['pharaoh'] = await benchmarks.PharaohAppBenchmark().report();
- results['angel3'] = await benchmarks.Angel3AppBenchmark().report();
+ // results['angel3'] = await benchmarks.Angel3AppBenchmark().report();
results['dart_frog (no_cli)'] =
await benchmarks.DartFrogAppBenchmark().report();
await saveToFile();
diff --git a/benchmarks/dart_frog_result.md b/benchmarks/dart_frog_result.md
index 15cc412d..05d77f76 100644
--- a/benchmarks/dart_frog_result.md
+++ b/benchmarks/dart_frog_result.md
@@ -1,15 +1,15 @@
## dart_frog (no_cli)
### Requests per second
-Requests/sec: 28649.98
-Transfer/sec: 7.08MB
-Requests/sec DIFF: +0.00%
+Requests/sec: 29766.17
+Transfer/sec: 7.35MB
+Requests/sec DIFF: +0.03%
### Latency
-Avg Latency: 44.57
-Stdev Latency: 81.17
-Max Latency: 1.12
-Stdev Perc: 97.66
+Avg Latency: 42.08
+Stdev Latency: 73.87
+Max Latency: 993.67
+Stdev Perc: 97.76
### Req/Sec
-Rps Avg: 3.6
-Rps Max: 4.77
-Rps Stdev: 477.96
-Rps Perc: 92.38
\ No newline at end of file
+Rps Avg: 3.74
+Rps Max: 4.87
+Rps Stdev: 481.07
+Rps Perc: 95.0
\ No newline at end of file
diff --git a/benchmarks/pharaoh_result.md b/benchmarks/pharaoh_result.md
index 92f3741f..3c5df3df 100644
--- a/benchmarks/pharaoh_result.md
+++ b/benchmarks/pharaoh_result.md
@@ -1,15 +1,15 @@
## pharaoh
### Requests per second
-Requests/sec: 31479.41
-Transfer/sec: 4.32MB
-Requests/sec DIFF: +9.88%
+Requests/sec: 32743.85
+Transfer/sec: 4.50MB
+Requests/sec DIFF: +10.03%
### Latency
-Avg Latency: 38.33
-Stdev Latency: 62.71
-Max Latency: 964.26
-Stdev Perc: 98.04
+Avg Latency: 37.62
+Stdev Latency: 64.91
+Max Latency: 918.12
+Stdev Perc: 98.06
### Req/Sec
-Rps Avg: 3.96
-Rps Max: 4.45
-Rps Stdev: 528.26
-Rps Perc: 95.75
\ No newline at end of file
+Rps Avg: 4.12
+Rps Max: 4.85
+Rps Stdev: 546.83
+Rps Perc: 95.38
\ No newline at end of file
diff --git a/benchmarks/serinus_result.md b/benchmarks/serinus_result.md
index 1386e5e9..ffc836a5 100644
--- a/benchmarks/serinus_result.md
+++ b/benchmarks/serinus_result.md
@@ -1,15 +1,15 @@
## serinus
### Requests per second
-Requests/sec: 30169.86
-Transfer/sec: 6.24MB
-Requests/sec DIFF: +5.30%
+Requests/sec: 31844.3
+Transfer/sec: 6.01MB
+Requests/sec DIFF: +7.01%
### Latency
-Avg Latency: 37.69
-Stdev Latency: 53.96
-Max Latency: 973.26
-Stdev Perc: 98.36
+Avg Latency: 36.07
+Stdev Latency: 52.8
+Max Latency: 941.4
+Stdev Perc: 98.01
### Req/Sec
-Rps Avg: 3.8
-Rps Max: 4.27
-Rps Stdev: 541.0
-Rps Perc: 94.12
\ No newline at end of file
+Rps Avg: 4.01
+Rps Max: 4.46
+Rps Stdev: 556.36
+Rps Perc: 95.38
\ No newline at end of file
diff --git a/benchmarks/shelf_result.md b/benchmarks/shelf_result.md
index ad1f0c68..46542d68 100644
--- a/benchmarks/shelf_result.md
+++ b/benchmarks/shelf_result.md
@@ -1,15 +1,15 @@
## shelf
### Requests per second
-Requests/sec: 28770.78
-Transfer/sec: 7.00MB
-Requests/sec DIFF: +0.42%
+Requests/sec: 29758.27
+Transfer/sec: 7.24MB
+Requests/sec DIFF: +0.00%
### Latency
-Avg Latency: 39.46
-Stdev Latency: 60.49
-Max Latency: 1.03
-Stdev Perc: 97.98
+Avg Latency: 39.4
+Stdev Latency: 63.89
+Max Latency: 989.15
+Stdev Perc: 97.9
### Req/Sec
-Rps Avg: 3.62
-Rps Max: 4.22
-Rps Stdev: 618.21
-Rps Perc: 91.5
\ No newline at end of file
+Rps Avg: 3.74
+Rps Max: 4.3
+Rps Stdev: 644.75
+Rps Perc: 92.75
\ No newline at end of file
diff --git a/examples/ping_pong/pubspec.yaml b/examples/ping_pong/pubspec.yaml
index 426baa01..e2f864f5 100644
--- a/examples/ping_pong/pubspec.yaml
+++ b/examples/ping_pong/pubspec.yaml
@@ -6,5 +6,5 @@ environment:
sdk: '>=3.0.0 <4.0.0'
dependencies:
- serinus: 0.2.0
+ serinus: 0.2.2
\ No newline at end of file
diff --git a/packages/serinus/CHANGELOG.md b/packages/serinus/CHANGELOG.md
index 173be645..08279560 100644
--- a/packages/serinus/CHANGELOG.md
+++ b/packages/serinus/CHANGELOG.md
@@ -1,5 +1,11 @@
# Changelog
+## 0.2.2
+
+- Add enableCompression flag in the SerinusApplication
+- Clean up code and add more tests
+- Start documenting the code
+
## 0.2.1
- Fix support for Serinus CLI run command environment variables
diff --git a/packages/serinus/analysis_options.yaml b/packages/serinus/analysis_options.yaml
index 9b348441..b2addb49 100644
--- a/packages/serinus/analysis_options.yaml
+++ b/packages/serinus/analysis_options.yaml
@@ -34,4 +34,6 @@ linter:
- always_declare_return_types
- always_put_control_body_on_new_line
- always_put_required_named_parameters_first
- - directives_ordering
\ No newline at end of file
+ - directives_ordering
+ - prefer_relative_imports
+ - prefer_single_quotes
\ No newline at end of file
diff --git a/packages/serinus/bin/serinus.dart b/packages/serinus/bin/serinus.dart
index 29c3e0f8..ae520d37 100644
--- a/packages/serinus/bin/serinus.dart
+++ b/packages/serinus/bin/serinus.dart
@@ -64,7 +64,7 @@ class GetRoute extends Route {
int? get version => 2;
@override
- List get guards => [TestGuard()];
+ List get guards => [];
}
class PostRoute extends Route {
@@ -119,6 +119,9 @@ class AppModule extends Module {
List get pipes => [
TestPipe(),
];
+
+ @override
+ List get guards => [TestGuard()];
}
class TestPipe extends Pipe {
diff --git a/packages/serinus/bin/serve_static/serve_static_controller.dart b/packages/serinus/bin/serve_static/serve_static_controller.dart
index 43e3c79e..e340c140 100644
--- a/packages/serinus/bin/serve_static/serve_static_controller.dart
+++ b/packages/serinus/bin/serve_static/serve_static_controller.dart
@@ -28,7 +28,7 @@ class ServeStaticController extends Controller {
// }
// }
if (!file.existsSync()) {
- throw NotFoundException(message: "The file $path does not exist");
+ throw NotFoundException(message: 'The file $path does not exist');
}
// final byteSink = ByteAccumulatorSink();
// await file.openRead().listen(byteSink.add).asFuture();
diff --git a/packages/serinus/example/bin/echo.dart b/packages/serinus/example/bin/echo.dart
index ef8c2a71..ebd9cf4c 100644
--- a/packages/serinus/example/bin/echo.dart
+++ b/packages/serinus/example/bin/echo.dart
@@ -1,4 +1,4 @@
-import 'package:echo/echo.dart';
+import 'package:echo/serinus.dart';
Future main(List arguments) async {
await bootstrap();
diff --git a/packages/serinus/example/lib/echo.dart b/packages/serinus/example/lib/serinus.dart
similarity index 100%
rename from packages/serinus/example/lib/echo.dart
rename to packages/serinus/example/lib/serinus.dart
diff --git a/packages/serinus/example/pubspec.lock b/packages/serinus/example/pubspec.lock
index b6e992a4..5abf08b1 100644
--- a/packages/serinus/example/pubspec.lock
+++ b/packages/serinus/example/pubspec.lock
@@ -77,10 +77,10 @@ packages:
dependency: transitive
description:
name: meta
- sha256: "25dfcaf170a0190f47ca6355bdd4552cb8924b430512ff0cafb8db9bd41fe33b"
+ sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
url: "https://pub.dev"
source: hosted
- version: "1.14.0"
+ version: "1.15.0"
mime:
dependency: transitive
description:
diff --git a/packages/serinus/example/pubspec.yaml b/packages/serinus/example/pubspec.yaml
index 9be4bd44..3df77164 100644
--- a/packages/serinus/example/pubspec.yaml
+++ b/packages/serinus/example/pubspec.yaml
@@ -1,10 +1,10 @@
name: echo
description: ''
-
+publish_to: none
environment:
sdk: '>=3.0.0 <4.0.0'
dependencies:
- serinus:
+ serinus: 0.2.2
\ No newline at end of file
diff --git a/packages/serinus/lib/serinus.dart b/packages/serinus/lib/serinus.dart
index d2de55e4..c85c2353 100644
--- a/packages/serinus/lib/serinus.dart
+++ b/packages/serinus/lib/serinus.dart
@@ -1,4 +1,14 @@
library serinus;
-export 'src/commons/commons.dart';
+export 'src/adapters/serinus_http_server.dart';
+export 'src/adapters/server_adapter.dart';
+export 'src/containers/module_container.dart';
+export 'src/contexts/contexts.dart';
export 'src/core/core.dart';
+export 'src/enums/enums.dart';
+export 'src/errors/initialization_error.dart';
+export 'src/exceptions/exceptions.dart';
+export 'src/global_prefix.dart';
+export 'src/http/http.dart';
+export 'src/mixins/mixins.dart';
+export 'src/versioning.dart';
diff --git a/packages/serinus/lib/src/commons/adapters/serinus_http_server.dart b/packages/serinus/lib/src/adapters/serinus_http_server.dart
similarity index 59%
rename from packages/serinus/lib/src/commons/adapters/serinus_http_server.dart
rename to packages/serinus/lib/src/adapters/serinus_http_server.dart
index 577f2342..8699c14e 100644
--- a/packages/serinus/lib/src/commons/adapters/serinus_http_server.dart
+++ b/packages/serinus/lib/src/adapters/serinus_http_server.dart
@@ -1,9 +1,16 @@
import 'dart:io' as io;
-import '../internal_request.dart';
+import '../http/internal_request.dart';
import 'server_adapter.dart';
class SerinusHttpServer extends HttpServerAdapter {
+ late final String host;
+ late final int port;
+ late final String poweredByHeader;
+ late final io.SecurityContext? securityContext;
+ bool get isSecure => securityContext != null;
+ bool _enableCompression = true;
+
factory SerinusHttpServer() {
return _singleton;
}
@@ -17,12 +24,19 @@ class SerinusHttpServer extends HttpServerAdapter {
{String host = 'localhost',
int port = 3000,
String poweredByHeader = 'Powered by Serinus',
- io.SecurityContext? securityContext}) async {
+ io.SecurityContext? securityContext,
+ bool enableCompression = true}) async {
if (securityContext == null) {
- server = await io.HttpServer.bind(host, port);
+ server = await io.HttpServer.bind(host, port, shared: true);
} else {
- server = await io.HttpServer.bindSecure(host, port, securityContext);
+ server = await io.HttpServer.bindSecure(host, port, securityContext,
+ shared: true);
}
+ this.host = host;
+ this.port = port;
+ this.poweredByHeader = poweredByHeader;
+ this.securityContext = securityContext;
+ _enableCompression = enableCompression;
server?.defaultResponseHeaders.add('X-Powered-By', poweredByHeader);
}
@@ -35,10 +49,11 @@ class SerinusHttpServer extends HttpServerAdapter {
Future listen(RequestCallback requestCallback,
{ErrorHandler? errorHandler}) async {
try {
- server?.listen((req) async {
+ server?.autoCompress = _enableCompression;
+ server?.listen((req) {
final request = InternalRequest.from(req, baseUrl: '');
final response = request.response;
- await requestCallback.call(request, response);
+ requestCallback.call(request, response);
}, onError: errorHandler);
} catch (e) {
if (errorHandler == null) {
diff --git a/packages/serinus/lib/src/commons/adapters/server_adapter.dart b/packages/serinus/lib/src/adapters/server_adapter.dart
similarity index 90%
rename from packages/serinus/lib/src/commons/adapters/server_adapter.dart
rename to packages/serinus/lib/src/adapters/server_adapter.dart
index 79a21a7f..faf6ad67 100644
--- a/packages/serinus/lib/src/commons/adapters/server_adapter.dart
+++ b/packages/serinus/lib/src/adapters/server_adapter.dart
@@ -1,7 +1,7 @@
import 'dart:async';
-import '../internal_request.dart';
-import '../internal_response.dart';
+import '../http/internal_request.dart';
+import '../http/internal_response.dart';
typedef RequestCallback = Future Function(
InternalRequest request, InternalResponse response);
diff --git a/packages/serinus/lib/src/commons/body.dart b/packages/serinus/lib/src/commons/body.dart
deleted file mode 100644
index 1f6ddb5f..00000000
--- a/packages/serinus/lib/src/commons/body.dart
+++ /dev/null
@@ -1,13 +0,0 @@
-import 'dart:io';
-
-import '../commons/form_data.dart';
-
-class Body {
- final FormData? formData;
- final ContentType contentType;
- final String? text;
- final List? bytes;
- final Map? json;
-
- Body(this.contentType, {this.formData, this.text, this.bytes, this.json});
-}
diff --git a/packages/serinus/lib/src/commons/commons.dart b/packages/serinus/lib/src/commons/commons.dart
deleted file mode 100644
index eb6a3ba7..00000000
--- a/packages/serinus/lib/src/commons/commons.dart
+++ /dev/null
@@ -1,18 +0,0 @@
-export 'adapters/serinus_http_server.dart';
-export 'adapters/server_adapter.dart';
-export 'body.dart';
-export 'cors.dart';
-export 'engines/view_engine.dart';
-export 'enums/http_method.dart';
-export 'enums/log_level.dart';
-export 'exceptions/exceptions.dart';
-export 'form_data.dart';
-export 'global_prefix.dart';
-export 'internal_response.dart';
-export 'mixins/application_mixins.dart';
-export 'mixins/object_mixins.dart';
-export 'request.dart';
-export 'response.dart';
-export 'services/logger_service.dart';
-export 'session.dart';
-export 'versioning.dart';
diff --git a/packages/serinus/lib/src/commons/extensions/content_type_extensions.dart b/packages/serinus/lib/src/commons/extensions/content_type_extensions.dart
deleted file mode 100644
index 092769ac..00000000
--- a/packages/serinus/lib/src/commons/extensions/content_type_extensions.dart
+++ /dev/null
@@ -1,6 +0,0 @@
-import 'dart:io';
-
-extension ContentTypeExtensions on ContentType {
- bool isUrlEncoded() => subType == "x-www-form-urlencoded";
- bool isMultipart() => mimeType == "multipart/form-data";
-}
diff --git a/packages/serinus/lib/src/commons/extensions/dynamic_extensions.dart b/packages/serinus/lib/src/commons/extensions/dynamic_extensions.dart
deleted file mode 100644
index ada28608..00000000
--- a/packages/serinus/lib/src/commons/extensions/dynamic_extensions.dart
+++ /dev/null
@@ -1,31 +0,0 @@
-import '../extensions/string_extensions.dart';
-
-extension JsonParsing on dynamic {
- String toJsonString() {
- final stringifiedObject = toString();
- if (stringifiedObject.isJson()) {
- return stringifiedObject;
- }
- try {
- return jsonEncode(this);
- } catch (e) {
- throw StateError("Error while parsing json");
- }
- }
-
- Map convertMap() {
- Map convertedMap = {};
- for (var key in this.keys) {
- if (this[key] is Map) {
- convertedMap[key.toString()] = this[key].convertMap();
- // }else if(this[key] is UploadedFile){
- // convertedMap[key.toString()] = this[key].toString();
- // }else if(this[key] is FormData){
- // convertedMap[key.toString()] = this[key].convertMap();
- } else {
- convertedMap[key.toString()] = this[key];
- }
- }
- return Map.from(convertedMap);
- }
-}
diff --git a/packages/serinus/lib/src/commons/extensions/uri_extensions.dart b/packages/serinus/lib/src/commons/extensions/uri_extensions.dart
deleted file mode 100644
index d27bca9f..00000000
--- a/packages/serinus/lib/src/commons/extensions/uri_extensions.dart
+++ /dev/null
@@ -1,21 +0,0 @@
-extension CombineUriPath on Uri {
- List combinePath() {
- List pathSegments = this.pathSegments;
-
- if (pathSegments.isEmpty) {
- return [];
- }
-
- List combinedPath = [];
-
- for (int i = 0; i < pathSegments.length; i++) {
- if (i == 0) {
- combinedPath.add(pathSegments[i]);
- } else {
- combinedPath.add('${combinedPath[i - 1]}/${pathSegments[i]}');
- }
- }
-
- return combinedPath;
- }
-}
diff --git a/packages/serinus/lib/src/commons/global_prefix.dart b/packages/serinus/lib/src/commons/global_prefix.dart
deleted file mode 100644
index 94067f9e..00000000
--- a/packages/serinus/lib/src/commons/global_prefix.dart
+++ /dev/null
@@ -1,5 +0,0 @@
-final class GlobalPrefix {
- final String prefix;
-
- const GlobalPrefix({required this.prefix});
-}
diff --git a/packages/serinus/lib/src/commons/mixins/application_mixins.dart b/packages/serinus/lib/src/commons/mixins/application_mixins.dart
deleted file mode 100644
index 3c9202f8..00000000
--- a/packages/serinus/lib/src/commons/mixins/application_mixins.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-import 'package:serinus/serinus.dart';
-
-mixin OnApplicationInit on Provider {
- Future onApplicationInit();
-}
-
-mixin OnApplicationShutdown on Provider {
- Future onApplicationShutdown();
-}
diff --git a/packages/serinus/lib/src/commons/mixins/object_mixins.dart b/packages/serinus/lib/src/commons/mixins/object_mixins.dart
deleted file mode 100644
index 168ff2a3..00000000
--- a/packages/serinus/lib/src/commons/mixins/object_mixins.dart
+++ /dev/null
@@ -1,3 +0,0 @@
-mixin JsonObject {
- Map toJson();
-}
diff --git a/packages/serinus/lib/src/commons/response.dart b/packages/serinus/lib/src/commons/response.dart
deleted file mode 100644
index e84cda59..00000000
--- a/packages/serinus/lib/src/commons/response.dart
+++ /dev/null
@@ -1,86 +0,0 @@
-import 'dart:convert';
-import 'dart:io';
-import 'dart:typed_data';
-
-import 'package:serinus/src/commons/engines/view_engine.dart';
-import 'package:serinus/src/commons/mixins/object_mixins.dart';
-
-class Response {
- final dynamic _value;
- int statusCode;
- final ContentType _contentType;
- final bool _shouldRedirect;
-
- Response._(this._value, this.statusCode, this._contentType,
- {bool shouldRedirect = false})
- : _shouldRedirect = shouldRedirect;
-
- dynamic get data => _value;
-
- ContentType get contentType => _contentType;
-
- bool get shouldRedirect => _shouldRedirect;
-
- final Map _headers = {};
-
- Map get headers => _headers;
-
- factory Response.json(dynamic data,
- {int statusCode = 200, ContentType? contentType}) {
- dynamic responseData;
- if (data is Map || data is List