VeryGoodOpenSource / dart_frog

A fast, minimalistic backend framework for Dart 🎯
https://dartfrog.vgv.dev
MIT License
1.87k stars 150 forks source link

feat: custom lints #548

Open felangel opened 1 year ago

felangel commented 1 year ago

Description

As a developer, I want to be able to have custom lint rules specifically for Dart Frog so that I can see warnings and apply quick fixes directly from my IDE rather than waiting for runtime errors.

Huge thanks to @Ehesp @Salakar @rrousselGit for initiating the convo and proposing the first batch of lints!

Requirements

Proposed Lint Rules

A route file must have an onRequest handler:

Currently you can just make an empty file, and the dev server will error since onRequest does not exist

Response onRequest(RequestContext context) {...}

onRequest must return FutureOr<Response>

You can just return anything at the moment, nothing will complain but the dev server will error out again,

String onRequest(RequestContext context) {
^^ bad

onRequest must contain a RequestContext

You can add anything in right now, nothing will complain but the dev server will error out again,

String onRequest(bool context) {
                 ^^ bad

A dynamic route path must contain the path params

The path: routes/posts/[userId]/[postId].dart must contain an onRequest handler with dynamic args:

Response onRequest(RequestContext context, String userId, String postId) {

Route conflicts: https://dartfrog.vgv.dev/docs/basics/routes#route-conflicts- Rouge routes: https://dartfrog.vgv.dev/docs/basics/routes#rogue-routes-

Middleware files should contain a valid middleware handler:

All of the same arguments as above apply here; return a Handler, contains a handler, must have a function called middleware etc

Handler middleware(Handler handler) {

Validation on a custom server handler

Same ideas as above, but in regards to the run method within a main.dart file: https://dartfrog.vgv.dev/docs/advanced/custom_entrypoint

Validation on middleware chaining

It’s fairly common for developers to apply the cascade operator on middleware when calling handler.use but this leads to incorrect behavior since use returns a new handler

return handler..use(middlewareA())..use(middlewareB());
              ^^ bad              ^^ bad   
return handler.use(middlewareA()).use(middlewareB());
              ^^ good
rrousselGit commented 1 year ago

I've implemented the lints (without fixes yet). I'll open a draft PR later this week