masoniteframework / masonite4 Goto Github PK
View Code? Open in Web Editor NEWTemporary Repository for a Masonite Rewrite for Masonite 4
Temporary Repository for a Masonite Rewrite for Masonite 4
These 2 helpers need to be reworked and added
Currently the exception handler doesn't really operate like the other features. It's really its own thing. It should follow the same process as the white paper I think
Need to create commands to scaffold:
ipython
option to have an easy to use shell with preloaded helpers and modelsUsage would be python craft tinker --ipython
.
It would require pip install ipython
first.
Database support should be separate. Possibly even connected to the Masonite ORM. You should be inheriting a class on your test case like:
class TestUsers(TestCase, DatabaseTransactions):
# ...
We need to display exception messages as we do with M3
When uploading a file using LocalDriver
class, the store
method returns the abs path to the file, but often in database
we want to store the path relative to the project. Then it's the role of e.g. the static
template helper to build the path to the file depending on the driver. It's also important for static file serving to work.
For now in my project when I do:
path = self.application.make("storage").disk("local").store(my_file)
path
is an absolute path. It was not the behaviour in M3
here is the path:
'/Users/sam/masonite-admin/tests/integrations/storage/uploads/70fc8f283543e77bd4434d00d6694a1dedf89454.png
maybe it should be only tests/integrations/storage/uploads/70fc8f283543e77bd4434d00d6694a1dedf89454.png
then static
helper
static("local", "tests/integrations/storage/uploads/70fc8f283543e77bd4434d00d6694a1dedf89454.png") # == "/static/70fc8f283543e77bd4434d00d6694a1dedf89454.png"
and then it can be served by whitenoise if we have this config in Kernel
storage.add_storage_assets(
{
# folder # template alias
"tests/integrations/storage/static": "static/",
"tests/integrations/storage/compiled": "static/",
"tests/integrations/storage/uploads": "static/",
"tests/integrations/storage/public": "/",
}
)
I open an issue here to keep in mind some features that Masonite 4 should be able to do.
Just to think about it during the rewrite (and maybe all of this is already possible in M3 ...)
Note: I am not talking about publishing files which can be done right now (and that's useful too).
That's the the two things I have been struggling with when trying to build a cool way to register packages to Masonite
Closes #51
As discussed I guess I will migrate this PR https://github.com/MasoniteFramework/notifications/pulls to a PR in this repo
This issue is easy. This is really just porting over the Helpers Provider from Masonite
These recently broke because of a change in how cookies are encrypted and decrypted. the failing tests are just commented out in the tests/tests/test_testcase.py
file
Need to add support again for the dotenv for .env files
In html we can do something like:
<input type="text" name="comments[]" value="1">
<input type="text" name="comments[]" value="2">
When it submits it is currently submitting as 1 value:
{
"comments": 2
}
It should be submitting like:
{
"comments": [1,2]
}
When you submit an input like this:
<input type="text" name="comments[description]" value="1">
<input type="text" name="comments[name]" value="2">
It should look like this:
{
"comments": {
"description": 1,
"name": 2
}
}
and lastly it could get more advanced:
<input type="text" name="comments[options][description]" value="1">
<input type="text" name="comments[options][name]" value="2">
should compile down to:
{
"comments": {
"options": {
"description": 1,
"name": 2
}
}
}
Currently this advanced input doesn't work
In Masonite M3 we can upload files to various places. Supported are local storage and Amazon S3..
The feature is extremely simple though and doesn't really support anything else.
We also have a Storage
class which is a half-baked feature that tried to bridge the gap between storage and uploading.
I think we can take this and run with it and make it more similar to this Laravel https://laravel.com/docs/8.x/filesystem
This class will contain all of the request related information like the URL and path
I would like to be able to update configuration during unit tests.
(It could be handy to be able to do it outside of tests too ? (or maybe not))
What do we currently have to do now?
Now we can get config with config() helper but not set it.
Solutions I have in mind:
Solution 1/
from masonite.helpers import set_config
set_config("application.name", "Brand new name !")
Solution 2/
We can change environment loaded during tests, but changing env vars during a unit test does not change the config and the config() function still returns the same value.
Solution 3/
Create a Configuration provider, load it early in the app lifecycle and load in it configuration settings defined in config/
,
the config helper would fetch settings from the configuration provider instead. settings would be maybe cached inside it to avoid accessing params from config files again.
Then it would be possible to set a config value because values would be hold inside this provider.
make("Configuration").update("app.name", "Masonite 4")
make("Configuration").get("app.name") #== config("app.name")
Solution 4/
As this would be mostly used during unit tests, maybe we can call "something" in setUp()
to load a different configuration ?
Temporary workaround
from unittest.mock import patch
@patch("config.application.APP_NAME", "Masonite 4.0") # patch one config value
@patch.dict("config.broadcast.DRIVERS", {"pusher": {"app_id": None, "client": None} }) # patch a whole config dict
def my_unit_test(self):
pass
Totally open about this !
The idea is to be able to as in Laravel
https://laravel.com/docs/master/configuration#accessing-configuration-values
and Django
https://docs.djangoproject.com/en/3.1/topics/testing/tools/#overriding-settings
This is one of the features we will need to rethink. We need to structure the classes differently I think and add better support for things like Mailables and other type classes
One of the issues with routing is that there is really no good encapsulation with the current structure.
Meaning that there are a lot of side effects, setting routing in 1 file could change routing in another file
I started this for M3 and I would like to migrate it to M4. Two possibilities: either in M4 core or as an external package. For me it makes sense to have this into the core.
Different approachs can be used here to provide utilities to developers wanting to create a package. In this issue I am going down the road of the provider approach. This is a first draft proposal to explain how this could work with M4.
It's inspired from https://github.com/spatie/laravel-package-tools
Of course this might not be the best approach but that's a try ๐
M4 could provide a PackageProvider
that you can use in your packages, to easily:
All files could be published by default under a configurable "vendor/package-name" namespace in locations defined in Kernel.py of project. So we would use what is defined in the container to build correct locations.
This is how it could look like:
from masonite.providers import PackageProvider
package_root_path = "path/to/package/root"
class MyPackageProvider(PackageProvider):
def configure(self):
self.name("my-package")
self.add_config("test")
self.add_command(MyCommand())
self.add_routes("admin", "public", tag="my-routes")
self.add_migrations("create_my_table", "create_my_other_package_table", tag="db")
self.add_assets(
{
"package.js": "app.js",
"package.css": None,
"sub/admin.js": "admin.js",
}
)
seld.add_tests_assertions(CustomTestResponse)
self.add_command(OtherCommand(), "DemoCommand")
M3 PackageProvider
code for reference https://github.com/MasoniteFramework/masonite/pull/411/files#diff-26aa7ccb08af6962c9fcb17624445040dc5fefb313ff32a4ab939e8e2c7c0ed9 that could be used to rewrite that from scratch for M4. Here the PackageProvider, call configure method behind the scenes in the register() method. And add stuff in the boot method also.
I guess this major release might be the time to upgrade hupper
and rewrite dev server if needed ? I did not really looked into how it was handled for M4. Is it a copy fof what's done in M3 ?
MasoniteFramework/masonite#369
still have the warning
======================================= warnings summary =======================================
../../../.pyenv/versions/3.9.1/lib/python3.9/site-packages/hupper/compat.py:2
/Users/craggeek/.pyenv/versions/3.9.1/lib/python3.9/site-packages/hupper/compat.py:2: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses
import imp
-- Docs: https://docs.pytest.org/en/stable/warnings.html
================================= 2 passed, 1 warning in 0.73s =================================
Need to relook at all the authentication scaffolding. Early days had a lot of rewrites in this.
We need to support controllers and routes for:
password_resets
)The Masonite essentials package is just a small package that has basically 1 middleware so can just bring that into M4 and archive that package
Before we dive too far into the framework I think it would be important to make sure that some of this stuff is testable. Some things with the request and response I was building out by testing it in the browser but it really should be testable first.
Also its important to test it in a way where a user can test it too. It's not just important to test core aspects of the framework but also important that a user can test their application too.
So because of that we need to be able to have as many assertions as possible. How the request works is we have a response_handler. this is largely the same handler as M3. Nothing really to discuss there. This response handler is bound to the container in the Kernel. This response handler is a WSGI standard and it runs through the framework and returns an iterable byte string and returns that to the browser.
BUT for testing purposes I added a testcase_handler
which does the exact same thing as the normal handler but instead it returns the request and response as a tuple and accepts more parameters like the application.
Because of this we should now be able to assert things on the response, request and route. We just need those things built out which is what this ticket is for.
At a minimum we should be able to do all the assertions that Masonite had and we can explore other frameworks for anymore assertions they have.
Methods like request.validate()
should be added back. Should also add the validation to the controller classes for the auth scaffolding
Can either do something like this or this when building mails:
.subject("Password Reset").priority(1)
.subject("Password Reset").high_priority()
or both and high_priority
is just an alias for priority(1)
https://github.com/girardinsamuel/masonite4-template needs to be deployed as a 4.X branch in the cookie-cutter repo
so that we can craft new project with M4.
The title is a bit wrong as we should not enforce a project layout, but what I meant was that we need at least a configuration file like the Kernel.py
file.
craft new
will use. (Are we still going to need this ?)Right now the request class needs the sign dependency. But I think we can remove the dependency if we just don't encrypt cookies on the request class but we have a middleware between requests that encrypts and decrypts them between request and response ..
This is a feature of Masonite where we can listen to multiple exceptions. But maybe this should tie into the Masonite events system ..
I played with file uploads for masonite-admin
๐ . It's working great. But then I tried to display a user avatar (e.g to serve an image from masonite) it did not work => I did not found static files handling feature. It was there in M3.
I guess it have to be implemented, the same way ?
I worked quite a lot with Masonite when it was at version 2.3.20 or so, since I really liked the framework. The only bad thing was that I found it quite troublesome to get it fully working for pure REST APIs, and attempts to remove folders such as resources
and storage
which contained templates and javascript/css etc.
The reason I wanted to remove these folders and everything related to Views was because a pure REST API will never use Views to return any HTML-formatted code (like Laravel blades). It will only return raw JSON blobs/data.
When reading the White Paper for Masonite 4, I noticed the following statements under Kernel Classes:
"Kernel classes is really just a service provider that only registers things to the application class that is crucial to making the framework work. For example, we need to know where the config directories are, the view directories, controller directories, bind middleware, etc."
The view directory (similar to Laravel blades) seems to be considered a core part of the framework (which it obviously is for MVC), which makes me worried that it again will be troublesome to use Masonite for APIs (since an API should return data, NOT a View.)
Considering we are in 2021 and web development is going further and further in the direction of only using REST/CRUD/Graph APIs, my suggestion is to keep this in mind when developing Masonite once again from scratch. I truly believe that a clean and simple way to create APIs with Masonite will attract a lot of new users.
Lastly, the paragraph above is not meant to be critical or negative. It is more that I really would like this project to be as good as possible, because I really believe it has the potential.
It would be nice to see this out of the box in M4, allowing new users to create APIs with just a few commands and defining their routes exactly like its done today.
I played with this for M3 here
MasoniteFramework/masonite#406
In short, the idea is to swap the provider with a testing one which is mocking the "external" part (sending an email for Mail class, pushing on a real queue for Queue class ...). On this mocked provider, some handy assertions are available.
If you think it's in the spirit of M4/the way to go to add some good testing capabilities, I would be glad to integrate this into M4
But maybe it should be done manually and it's a not bug.
user = User.create({..."password": "secret"})
user.password #== secret
I guess we should be able to hash it before storing it in database, and it should be taken care of automatically for Users ?
One requirement I missed on the queue jobs was the ability to delay a job for later. For example if we want to send a welcome email 1 hour after a user signed up:
self.app.make('queue').push(SendWelcomeJob(), delay="1 hour")
Something like this. For the async driver I think we can ignore it but for the database driver we have an available_at field we need to populate
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.