-
It seems like SSE blocks the further requests from coming in..
-
Get super methods from classes to allow for inheritance and better community support
- Add
create
command to the revali cli to create new- Constructs
- Routes
- Controllers
- Guards
- Exception Catchers
- Pipes
- Interceptors
- Middlewares
- Apps
- (etc)
- Figure out why we got an error when calling `body['data'] = value.toJson()
- Delete "old" files within .revali directory on hot reload
- Create a Set of paths, remove a path when the file is updated/created. Delete any remaining paths
- When a value is provided to 'arg', the
paramName
also gets that value, instead of the name of the parameter - Think of new names (?) for
arg
andparamName
- Change
transform
to aFutureOr
type to allow for async methods - Remove check to force only one app in
*.app.dart
- Create general package for revali server that exports all annotations and core functionality
- Ensure we can return streams from endpoints
- Handle streams in websocket responses
- revali build
- Compiles the server code and prepares the "out-going" directory with any Public files
- We may need to have a configuration file to handle what to ignore/include
- Compiles the server code and prepares the "out-going" directory with any Public files
- revali upload
- Uploads the "out-going" directory to a server
- Catch errors thrown by the generator
- Clear the console, then print the error
- We want to avoid exiting the process at all costs!
- Maybe we can handle this with the Isolate?
-
Find a way to support partial content requests- Maybe later
- CORs for apps (docs)
- Handle range file requests
- Handle if modified since file requests
- Send back last modified header for files
- Set headers based on body data type (within the send request method only!)
- Create headers getter on the body data type
- Update the content disposition header for files
- Update headers when status code changes
- Update headers when body changes
- Returning files
- Public files
- Routes will be automatically generated for these files
- The files will be served from the
public
directory
- Static files
- Routes will not be generated for these files
- The idea is that the user will be able to return a "ServerFile" class with the path pointing to the file
- Dependency injection for apps
[ ] Wildcard paths- Maybe later...
- Web sockets
[ ] Returning streams (not as web sockets)
- Attempt to create a variable for combine types as an annotation
- This could allow me to get the values of the fields of the annotation
- Create "App" annotation
- This will be used for configurations such as
- Server lambdas
- Server configurations
- Dependency injection
- Global exception catchers
- Global guards
- Global prefix
- CORS
- (Nice To Haves):
- Rate limiting
- This will be used for configurations such as
- Add flavor flag to the annotation & to the CLI to determine what environment the app is running in
- Add
Pipe
class for annotations- This will be used to convert the annotated item to another type
- Add
Guard
class for annotations- This will be used to stop or continue the execution of the method/endpoint
- We could create a field for types where we could annotation like
@Guard([AuthGuard, RoleGuard])
- This wouldn't allow for all edge cases, but could be useful
- We could also add a different field coupled with a different constructor to allow for instances of guards
- Create
Catch
class which will be used to catch errors thrown by the method/endpoint- The errors would need to implement the
ExceptionCatcher
interface - We could create a field for types where we could annotation like
@Catch([UnknownCatcher, ServerCatcher, BadRequestCatcher])
- The errors would need to implement the
- Create
HttpCode
class which will be used to set the status code of the response@HttpCode(200)
- Create
SetHeader
class which will be used to set the headers of the response@SetHeader('Content-Type', 'application/json')
- Create
Redirect
class which will be used to redirect the user to another endpoint@Redirect('/home')
- Create
Body
class which will be used to get the body of the request as a parameter@Body()
- Create
Header
class which will be used to get the headers of the request as a parameter@Header('Content-Type')
- Create
RateLimit
class which will be used to limit the number of requests to an endpoint@RateLimit(10, Duration(minutes: 1))
-
Combine revali and revali_server into a single packageThis is because shelf is really the only http server that we will be using, and we want consistencyWe also don't want constructs to run scripts, which is what we would have to do if the revali_server package was separate- This is fine actually, we will have a flag within the config file that will determine whether the dependency is a "router" generator or other
- Create
revali_construct
package to hold the core functionality of revali- This way developers don't need to depend on the entire revali package, just the necessary parts
So I just figured out how I can get the constructs that the dev is depending on implicitly
- Ge the dev dependencies
- Resolve their paths and look for a construct.yaml file
- Parse the construct.yaml file to get the configuration
No that I have the construct configs, I need a way to generate the code that the constructs will provide. Thankfully build_runner has already done the work for this and I can follow their footsteps.
I can do this by creating a file within .dart_tool/revali/entrypoint/revali.dart
The code within this file should look like
import 'dart:io' as io;
import 'dart:isolate';
import 'package:revali/revali.dart';
import 'package:revali_server/revali_server.dart';
final constructs = <Construct>[
revaliShelfConstruct(),
];
const path = '/Users/morgan/Documents/develop.nosync/revali/examples/demo/routes';
void main(
List<String> args, [
SendPort? sendPort,
]) async {
var result = await run(
args,
constructs: constructs,
path: path,
);
sendPort?.send(result);
io.exitCode = result;
}
Obviously this will need to be modified so that we don't have conflicts in the imports.
Once I have this file, I can execute it
await Isolate.spawnUri(Uri.file(p.absolute(scriptKernelLocation)), args,
messagePort.sendPort,
errorsAreFatal: true,
onExit: exitPort.sendPort,
onError: errorPort.sendPort);
In build_runner, they are compiling the code to a kernel file and then executing it. I will probably need to do the same thing.
Once the code is executed, it will run the code found within the revali
package and generate the code provided by the constructs, provided by the generated revali.dart
file.