fastlifeweb 0.20.1__py3-none-any.whl → 0.22.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- CHANGELOG.md +18 -1
- fastlife/__init__.py +45 -13
- fastlife/adapters/__init__.py +1 -1
- fastlife/adapters/fastapi/__init__.py +9 -0
- fastlife/adapters/fastapi/form.py +26 -0
- fastlife/{request → adapters/fastapi}/form_data.py +1 -1
- fastlife/{request → adapters/fastapi}/localizer.py +4 -2
- fastlife/adapters/fastapi/request.py +33 -0
- fastlife/{routing → adapters/fastapi/routing}/route.py +3 -3
- fastlife/{routing → adapters/fastapi/routing}/router.py +1 -1
- fastlife/adapters/itsdangerous/__init__.py +3 -0
- fastlife/adapters/itsdangerous/session.py +50 -0
- fastlife/adapters/jinjax/jinjax_ext/inspectable_component.py +7 -7
- fastlife/adapters/jinjax/jinjax_ext/jinjax_doc.py +1 -1
- fastlife/adapters/jinjax/renderer.py +9 -57
- fastlife/adapters/jinjax/widget_factory/bool_builder.py +2 -2
- fastlife/adapters/jinjax/widget_factory/emailstr_builder.py +5 -4
- fastlife/adapters/jinjax/widget_factory/enum_builder.py +2 -2
- fastlife/adapters/jinjax/widget_factory/factory.py +32 -23
- fastlife/adapters/jinjax/widget_factory/literal_builder.py +7 -6
- fastlife/adapters/jinjax/widget_factory/model_builder.py +3 -3
- fastlife/adapters/jinjax/widget_factory/secretstr_builder.py +2 -2
- fastlife/adapters/jinjax/widget_factory/sequence_builder.py +3 -3
- fastlife/adapters/jinjax/widget_factory/set_builder.py +2 -2
- fastlife/adapters/jinjax/widget_factory/simpletype_builder.py +7 -8
- fastlife/adapters/jinjax/widget_factory/union_builder.py +3 -3
- fastlife/adapters/jinjax/widgets/base.py +36 -36
- fastlife/adapters/jinjax/widgets/boolean.py +13 -34
- fastlife/adapters/jinjax/widgets/checklist.py +36 -42
- fastlife/adapters/jinjax/widgets/dropdown.py +32 -38
- fastlife/adapters/jinjax/widgets/hidden.py +7 -15
- fastlife/adapters/jinjax/widgets/model.py +36 -43
- fastlife/adapters/jinjax/widgets/sequence.py +63 -42
- fastlife/adapters/jinjax/widgets/text.py +39 -78
- fastlife/adapters/jinjax/widgets/union.py +51 -58
- fastlife/components/CsrfToken.jinja +1 -1
- fastlife/components/Form.jinja +1 -1
- fastlife/components/pydantic_form/FatalError.jinja +8 -0
- fastlife/components/pydantic_form/Widget.jinja +4 -3
- fastlife/config/__init__.py +3 -6
- fastlife/config/configurator.py +80 -32
- fastlife/config/exceptions.py +0 -2
- fastlife/config/resources.py +1 -2
- fastlife/config/views.py +2 -4
- fastlife/domain/__init__.py +1 -0
- fastlife/domain/model/__init__.py +1 -0
- fastlife/domain/model/asgi.py +3 -0
- fastlife/domain/model/csrf.py +19 -0
- fastlife/{request → domain/model}/form.py +13 -22
- fastlife/{request → domain/model}/request.py +26 -30
- fastlife/domain/model/security_policy.py +105 -0
- fastlife/{templates/inline.py → domain/model/template.py} +8 -0
- fastlife/domain/model/types.py +17 -0
- fastlife/middlewares/base.py +1 -1
- fastlife/middlewares/reverse_proxy/x_forwarded.py +1 -2
- fastlife/middlewares/session/__init__.py +2 -2
- fastlife/middlewares/session/middleware.py +4 -3
- fastlife/middlewares/session/serializer.py +0 -44
- fastlife/{services/policy.py → service/check_permission.py} +1 -1
- fastlife/{security → service}/csrf.py +5 -15
- fastlife/{services → service}/locale_negociator.py +5 -8
- fastlife/{config → service}/registry.py +13 -7
- fastlife/service/security_policy.py +100 -0
- fastlife/{services → service}/templates.py +10 -48
- fastlife/{services → service}/translations.py +15 -0
- fastlife/{config/settings.py → settings.py} +6 -12
- fastlife/shared_utils/infer.py +24 -1
- fastlife/{templates/constants.py → template_globals.py} +2 -2
- fastlife/testing/testclient.py +2 -2
- fastlife/views/__init__.py +1 -0
- fastlife/views/pydantic_form.py +6 -0
- {fastlifeweb-0.20.1.dist-info → fastlifeweb-0.22.0.dist-info}/METADATA +1 -1
- {fastlifeweb-0.20.1.dist-info → fastlifeweb-0.22.0.dist-info}/RECORD +79 -80
- tailwind.config.js +1 -1
- fastlife/components/pydantic_form/Boolean.jinja +0 -13
- fastlife/components/pydantic_form/Checklist.jinja +0 -21
- fastlife/components/pydantic_form/Dropdown.jinja +0 -18
- fastlife/components/pydantic_form/Hidden.jinja +0 -3
- fastlife/components/pydantic_form/Model.jinja +0 -30
- fastlife/components/pydantic_form/Sequence.jinja +0 -47
- fastlife/components/pydantic_form/Text.jinja +0 -11
- fastlife/components/pydantic_form/Textarea.jinja +0 -38
- fastlife/components/pydantic_form/Union.jinja +0 -34
- fastlife/request/__init__.py +0 -5
- fastlife/security/__init__.py +0 -1
- fastlife/security/policy.py +0 -188
- fastlife/templates/__init__.py +0 -12
- fastlife/templates/binding.py +0 -52
- /fastlife/{routing → adapters/fastapi/routing}/__init__.py +0 -0
- /fastlife/{services → service}/__init__.py +0 -0
- {fastlifeweb-0.20.1.dist-info → fastlifeweb-0.22.0.dist-info}/WHEEL +0 -0
- {fastlifeweb-0.20.1.dist-info → fastlifeweb-0.22.0.dist-info}/entry_points.txt +0 -0
- {fastlifeweb-0.20.1.dist-info → fastlifeweb-0.22.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,100 @@
|
|
1
|
+
"""Security policy."""
|
2
|
+
|
3
|
+
import abc
|
4
|
+
from typing import Annotated, Any, Generic
|
5
|
+
from uuid import UUID
|
6
|
+
|
7
|
+
from fastapi import Depends
|
8
|
+
|
9
|
+
from fastlife import GenericRequest, get_request
|
10
|
+
from fastlife.domain.model.security_policy import (
|
11
|
+
Allowed,
|
12
|
+
Forbidden,
|
13
|
+
HasPermission,
|
14
|
+
TUser,
|
15
|
+
Unauthorized,
|
16
|
+
)
|
17
|
+
from fastlife.service.registry import TRegistry
|
18
|
+
|
19
|
+
|
20
|
+
class AbstractSecurityPolicy(abc.ABC, Generic[TUser, TRegistry]):
|
21
|
+
"""Security policy base class."""
|
22
|
+
|
23
|
+
Forbidden = Forbidden
|
24
|
+
"""The exception raised if the user identified is not granted."""
|
25
|
+
Unauthorized = Unauthorized
|
26
|
+
"""The exception raised if no user has been identified."""
|
27
|
+
|
28
|
+
request: GenericRequest[TRegistry]
|
29
|
+
"""Request where the security policy is applied."""
|
30
|
+
|
31
|
+
def __init__(
|
32
|
+
self, request: Annotated[GenericRequest[TRegistry], Depends(get_request)]
|
33
|
+
):
|
34
|
+
"""
|
35
|
+
Build the security policy.
|
36
|
+
|
37
|
+
When implementing a security policy, multiple parameters can be added
|
38
|
+
to the constructor as FastAPI dependencies, using the `Depends` FastAPI
|
39
|
+
annotation.
|
40
|
+
The security policy is installed has a depenency of the router that hold
|
41
|
+
a route prefix of the application.
|
42
|
+
"""
|
43
|
+
self.request = request
|
44
|
+
self.request.security_policy = self # we do backref to implement has_permission
|
45
|
+
|
46
|
+
@abc.abstractmethod
|
47
|
+
async def identity(self) -> TUser | None:
|
48
|
+
"""
|
49
|
+
Return app-specific user object or raise an HTTPException.
|
50
|
+
"""
|
51
|
+
|
52
|
+
@abc.abstractmethod
|
53
|
+
async def authenticated_userid(self) -> str | UUID | None:
|
54
|
+
"""
|
55
|
+
Return app-specific user object or raise an HTTPException.
|
56
|
+
"""
|
57
|
+
|
58
|
+
@abc.abstractmethod
|
59
|
+
async def has_permission(
|
60
|
+
self, permission: str
|
61
|
+
) -> HasPermission | type[HasPermission]:
|
62
|
+
"""Allow access to everything if signed in."""
|
63
|
+
|
64
|
+
@abc.abstractmethod
|
65
|
+
async def remember(self, user: TUser) -> None:
|
66
|
+
"""Save the user identity in the request session."""
|
67
|
+
|
68
|
+
@abc.abstractmethod
|
69
|
+
async def forget(self) -> None:
|
70
|
+
"""Destroy the request session."""
|
71
|
+
|
72
|
+
|
73
|
+
class InsecurePolicy(AbstractSecurityPolicy[None, Any]):
|
74
|
+
"""
|
75
|
+
An implementation of the security policy made for explicit unsecured access.
|
76
|
+
|
77
|
+
Setting a permission on a view require a security policy, if not set, accessing
|
78
|
+
to a view will raise a RuntimeError. To bypass this error for testing purpose
|
79
|
+
or your own reason, the InsecurePolicy has to be set to the configurator.
|
80
|
+
"""
|
81
|
+
|
82
|
+
async def identity(self) -> None:
|
83
|
+
"""Nobodies is identified."""
|
84
|
+
return None
|
85
|
+
|
86
|
+
async def authenticated_userid(self) -> str | UUID:
|
87
|
+
"""An uuid mades of 0."""
|
88
|
+
return UUID(int=0)
|
89
|
+
|
90
|
+
async def has_permission(
|
91
|
+
self, permission: str
|
92
|
+
) -> HasPermission | type[HasPermission]:
|
93
|
+
"""Access is allways granted."""
|
94
|
+
return Allowed
|
95
|
+
|
96
|
+
async def remember(self, user: None) -> None:
|
97
|
+
"""Do nothing."""
|
98
|
+
|
99
|
+
async def forget(self) -> None:
|
100
|
+
"""Do nothing."""
|
@@ -9,14 +9,11 @@ More template engine can be registered using the configurator method
|
|
9
9
|
"""
|
10
10
|
|
11
11
|
import abc
|
12
|
-
from collections.abc import
|
12
|
+
from collections.abc import Mapping
|
13
13
|
from typing import Any
|
14
14
|
|
15
15
|
from fastlife import Request, Response
|
16
|
-
from fastlife.
|
17
|
-
from fastlife.templates.inline import InlineTemplate
|
18
|
-
|
19
|
-
TemplateParams = Mapping[str, Any]
|
16
|
+
from fastlife.domain.model.template import InlineTemplate
|
20
17
|
|
21
18
|
|
22
19
|
class AbstractTemplateRenderer(abc.ABC):
|
@@ -30,6 +27,7 @@ class AbstractTemplateRenderer(abc.ABC):
|
|
30
27
|
|
31
28
|
def __init__(self, request: Request) -> None:
|
32
29
|
self.request = request
|
30
|
+
self.globals: dict[str, Any] = {}
|
33
31
|
|
34
32
|
@property
|
35
33
|
def route_prefix(self) -> str:
|
@@ -43,27 +41,21 @@ class AbstractTemplateRenderer(abc.ABC):
|
|
43
41
|
status_code: int = 200,
|
44
42
|
content_type: str = "text/html",
|
45
43
|
globals: Mapping[str, Any] | None = None,
|
46
|
-
params:
|
47
|
-
_create_csrf_token: Callable[..., str] = create_csrf_token,
|
44
|
+
params: InlineTemplate,
|
48
45
|
) -> Response:
|
49
46
|
"""
|
50
47
|
Render the template and build the HTTP Response.
|
51
48
|
"""
|
52
49
|
request = self.request
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
)
|
57
|
-
if isinstance(params, InlineTemplate):
|
58
|
-
data = self.render_inline(params)
|
59
|
-
else:
|
60
|
-
data = self.render_template(template, **params)
|
50
|
+
if globals:
|
51
|
+
self.globals.update(globals)
|
52
|
+
data = self.render_template(params)
|
61
53
|
resp = Response(
|
62
54
|
data, status_code=status_code, headers={"Content-Type": content_type}
|
63
55
|
)
|
64
56
|
resp.set_cookie(
|
65
|
-
|
66
|
-
request.
|
57
|
+
request.csrf_token.name,
|
58
|
+
request.csrf_token.value,
|
67
59
|
secure=request.url.scheme == "https",
|
68
60
|
samesite="strict",
|
69
61
|
max_age=60 * 15,
|
@@ -71,34 +63,7 @@ class AbstractTemplateRenderer(abc.ABC):
|
|
71
63
|
return resp
|
72
64
|
|
73
65
|
@abc.abstractmethod
|
74
|
-
def render_template(
|
75
|
-
self,
|
76
|
-
template: str,
|
77
|
-
*,
|
78
|
-
globals: Mapping[str, Any] | None = None,
|
79
|
-
**params: Any,
|
80
|
-
) -> str:
|
81
|
-
"""
|
82
|
-
Render the given template with the given params.
|
83
|
-
|
84
|
-
While rendering templates, the globals parameter is keps by the instantiated
|
85
|
-
renderer and sent to every rendering made by the request.
|
86
|
-
This is used by the pydantic form method that will render other templates
|
87
|
-
for the request.
|
88
|
-
In traditional frameworks, only one template is rendered containing the whole
|
89
|
-
pages. But, while rendering a pydantic form, every field is rendered in its
|
90
|
-
distinct template. The template renderer keep the globals and git it back
|
91
|
-
to every templates. This can be used to fillout options in a select without
|
92
|
-
performing an ajax request for example.
|
93
|
-
|
94
|
-
:param template: name of the template to render.
|
95
|
-
:param globals: some variable that will be passed to all rendered templates.
|
96
|
-
:param params: paramaters that are limited to the main rendered templates.
|
97
|
-
:return: The template rendering result.
|
98
|
-
"""
|
99
|
-
|
100
|
-
@abc.abstractmethod
|
101
|
-
def render_inline(self, template: InlineTemplate) -> str:
|
66
|
+
def render_template(self, template: InlineTemplate) -> str:
|
102
67
|
"""
|
103
68
|
Render an inline template.
|
104
69
|
|
@@ -110,9 +75,6 @@ class AbstractTemplateRenderer(abc.ABC):
|
|
110
75
|
class AbstractTemplateRendererFactory(abc.ABC):
|
111
76
|
"""
|
112
77
|
The template render factory.
|
113
|
-
|
114
|
-
The implementation of this class is found using the settings
|
115
|
-
:attr:`fastlife.config.settings.Settings.template_renderer_class`.
|
116
78
|
"""
|
117
79
|
|
118
80
|
@abc.abstractmethod
|
@@ -64,6 +64,9 @@ class Localizer:
|
|
64
64
|
self.translations[domain].merge(trans)
|
65
65
|
self.global_translations.merge(trans)
|
66
66
|
|
67
|
+
def __call__(self, message: str, mapping: dict[str, str] | None = None) -> str:
|
68
|
+
return self.gettext(message, mapping)
|
69
|
+
|
67
70
|
def gettext(self, message: str, mapping: dict[str, str] | None = None) -> str:
|
68
71
|
ret = self.global_translations.gettext(message)
|
69
72
|
if mapping:
|
@@ -117,6 +120,18 @@ class Localizer:
|
|
117
120
|
ret = ret.format(**mapping)
|
118
121
|
return ret
|
119
122
|
|
123
|
+
def npgettext(
|
124
|
+
self,
|
125
|
+
context: str,
|
126
|
+
singular: str,
|
127
|
+
plural: str,
|
128
|
+
n: int,
|
129
|
+
mapping: dict[str, str] | None = None,
|
130
|
+
) -> str:
|
131
|
+
ret = self.global_translations.npgettext(context, singular, plural, n)
|
132
|
+
mapping_num = {"num": n, **(mapping or {})}
|
133
|
+
return ret.format(**mapping_num)
|
134
|
+
|
120
135
|
def dnpgettext(
|
121
136
|
self,
|
122
137
|
domain: str,
|
@@ -29,15 +29,9 @@ class Settings(BaseSettings):
|
|
29
29
|
a python module name. for instance `fastlife:components` is the directory components
|
30
30
|
found in the fastlife package.
|
31
31
|
"""
|
32
|
-
registry_class: str = Field(default="fastlife.
|
32
|
+
registry_class: str = Field(default="fastlife.service.registry:DefaultRegistry")
|
33
33
|
"""Implementation class for the application regitry."""
|
34
|
-
|
35
|
-
default="fastlife.templates.renderer:JinjaxEngine"
|
36
|
-
)
|
37
|
-
"""
|
38
|
-
Implementation class for the
|
39
|
-
{class}`fastlife.templates.renderer.AbstractTemplateRenderer`.
|
40
|
-
"""
|
34
|
+
|
41
35
|
form_data_model_prefix: str = Field(default="payload")
|
42
36
|
"""
|
43
37
|
Pydantic form default model prefix for serialized field in www-urlencoded-form.
|
@@ -70,12 +64,12 @@ class Settings(BaseSettings):
|
|
70
64
|
Set to true while developing, set false for production.
|
71
65
|
"""
|
72
66
|
jinjax_global_catalog_class: str = Field(
|
73
|
-
default="fastlife.
|
67
|
+
default="fastlife.template_globals:Globals"
|
74
68
|
)
|
75
69
|
"""
|
76
70
|
Set global constants accessible in every templates.
|
77
|
-
Defaults to `fastlife.
|
78
|
-
See {class}`fastlife.
|
71
|
+
Defaults to `fastlife.template_globals:Globals`
|
72
|
+
See {class}`fastlife.template_globals.Globals`
|
79
73
|
"""
|
80
74
|
|
81
75
|
session_secret_key: str = Field(default="")
|
@@ -101,7 +95,7 @@ class Settings(BaseSettings):
|
|
101
95
|
should be true while using https on production.
|
102
96
|
"""
|
103
97
|
session_serializer: str = Field(
|
104
|
-
default="fastlife.
|
98
|
+
default="fastlife.adapters.itsdangerous:SignedSessionSerializer"
|
105
99
|
)
|
106
100
|
"""Cookie serializer for the session cookie."""
|
107
101
|
|
fastlife/shared_utils/infer.py
CHANGED
@@ -1,10 +1,14 @@
|
|
1
1
|
"""Type inference."""
|
2
2
|
|
3
|
+
import inspect
|
4
|
+
from collections.abc import Callable
|
3
5
|
from types import UnionType
|
4
|
-
from typing import Any, Union, get_origin
|
6
|
+
from typing import Any, Union, get_args, get_origin
|
5
7
|
|
6
8
|
from pydantic import BaseModel
|
7
9
|
|
10
|
+
from fastlife.domain.model.template import InlineTemplate
|
11
|
+
|
8
12
|
|
9
13
|
def is_complex_type(typ: type[Any]) -> bool:
|
10
14
|
"""
|
@@ -25,3 +29,22 @@ def is_union(typ: type[Any]) -> bool:
|
|
25
29
|
if type_origin is UnionType: # T | U
|
26
30
|
return True
|
27
31
|
return False
|
32
|
+
|
33
|
+
|
34
|
+
def is_inline_template_returned(endpoint: Callable[..., Any]) -> bool:
|
35
|
+
"""Test if a view, the endpoint return a template."""
|
36
|
+
signature = inspect.signature(endpoint)
|
37
|
+
return_annotation = signature.return_annotation
|
38
|
+
|
39
|
+
if isinstance(return_annotation, type) and issubclass(
|
40
|
+
return_annotation, InlineTemplate
|
41
|
+
):
|
42
|
+
return True
|
43
|
+
|
44
|
+
if is_union(return_annotation):
|
45
|
+
return any(
|
46
|
+
isinstance(arg, type) and issubclass(arg, InlineTemplate)
|
47
|
+
for arg in get_args(return_annotation)
|
48
|
+
)
|
49
|
+
|
50
|
+
return False
|
@@ -16,7 +16,7 @@ def space_join(*segments: str) -> str:
|
|
16
16
|
return " ".join(segments)
|
17
17
|
|
18
18
|
|
19
|
-
class
|
19
|
+
class Globals(BaseModel):
|
20
20
|
"""Templates constants."""
|
21
21
|
|
22
22
|
A_CLASS: str = space_join(
|
@@ -315,7 +315,7 @@ class Constants(BaseModel):
|
|
315
315
|
SUMMARY_CLASS: str = "flex items-center items-center font-medium cursor-pointer"
|
316
316
|
"""Default css class for {jinjax:component}`Summary`."""
|
317
317
|
|
318
|
-
TABLE_CLASS: str = "table-auto w-full text-left border-
|
318
|
+
TABLE_CLASS: str = "table-auto w-full text-left border-collapse"
|
319
319
|
"""Default css class for {jinjax:component}`Table`."""
|
320
320
|
|
321
321
|
TD_CLASS: str = "px-4 py-2 font-normal border-b dark:border-neutral-500"
|
fastlife/testing/testclient.py
CHANGED
@@ -8,10 +8,10 @@ import bs4
|
|
8
8
|
import httpx
|
9
9
|
from fastapi.testclient import TestClient
|
10
10
|
from multidict import MultiDict
|
11
|
-
from starlette.types import ASGIApp
|
12
11
|
|
13
|
-
from fastlife.
|
12
|
+
from fastlife.domain.model.asgi import ASGIApp
|
14
13
|
from fastlife.middlewares.session.serializer import AbsractSessionSerializer
|
14
|
+
from fastlife.settings import Settings
|
15
15
|
from fastlife.shared_utils.resolver import resolve
|
16
16
|
from fastlife.testing.dom import Element
|
17
17
|
from fastlife.testing.form import WebForm
|
fastlife/views/__init__.py
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
"""Fastlife views."""
|
fastlife/views/pydantic_form.py
CHANGED
@@ -1,42 +1,52 @@
|
|
1
|
-
CHANGELOG.md,sha256=
|
2
|
-
fastlife/__init__.py,sha256=
|
3
|
-
fastlife/adapters/__init__.py,sha256=
|
1
|
+
CHANGELOG.md,sha256=gtRawAWGc5B7HSVjRWA2eng5K_1jDm-AZrioc2niKWw,6987
|
2
|
+
fastlife/__init__.py,sha256=vccDwPrkKjB4N-yBdqWN5fCaUJzUnFyNAE35pcIz9kU,1664
|
3
|
+
fastlife/adapters/__init__.py,sha256=imPD1hImpgrYkvUJRhHA5kVyGAua7VbP2WGkhSWKJT8,93
|
4
|
+
fastlife/adapters/fastapi/__init__.py,sha256=1goV1FGFP04TGyskJBLKZam4Gvt1yoAvLMNs4ekWSSQ,243
|
5
|
+
fastlife/adapters/fastapi/form.py,sha256=csxsDI6RK-g41pMwFhaVQCLDhF7dAZzgUp-VcrC3NFY,823
|
6
|
+
fastlife/adapters/fastapi/form_data.py,sha256=2DQ0o-RvY6iROUKQjS-UJdNYEVSsNPd-AjpergI3w54,4473
|
7
|
+
fastlife/adapters/fastapi/localizer.py,sha256=XD1kCJuAlkGevivmvAJEcGMCBWMef9rAfTOGmt3PVWU,436
|
8
|
+
fastlife/adapters/fastapi/request.py,sha256=oyAZ1QKW2mh-9CadQdOdn_BqnVVjaZ6aG4eTNK2R2j0,1095
|
9
|
+
fastlife/adapters/fastapi/routing/__init__.py,sha256=8EMnQE5n8oA4J9_c3nxzwKDVt3tefZ6fGH0d2owE8mo,195
|
10
|
+
fastlife/adapters/fastapi/routing/route.py,sha256=g-MlXFvyRzVsNO_bBYDQQHD03fmRXEOm9KHxIHFZmug,1461
|
11
|
+
fastlife/adapters/fastapi/routing/router.py,sha256=jzrnU_Lyywu21e3spPaWQw8ujZh_Yy_EJOojcCi6ew4,499
|
12
|
+
fastlife/adapters/itsdangerous/__init__.py,sha256=7ocGY7v0cxooZBKQYjA2JkmzRqiBvcU1uzA84UsTVAI,84
|
13
|
+
fastlife/adapters/itsdangerous/session.py,sha256=9h_WRsXqZbytHZOv5B_K3OWD5mbfYzxHulXoOf6D2MI,1685
|
4
14
|
fastlife/adapters/jinjax/__init__.py,sha256=4JRAUwFGpTxYtRlg5sU79AahxyAiRMhllRFHoI-dnug,117
|
5
15
|
fastlife/adapters/jinjax/jinjax_ext/__init__.py,sha256=z6NWvHzTNEq6bVO4iJoTR6-y4A6UtS_VuSMV_tff1jY,49
|
6
16
|
fastlife/adapters/jinjax/jinjax_ext/docstring.py,sha256=Zlx0oSxsRU9vQvGoyScXf9uB1W8JaoreGoJK3Xi26RE,2791
|
7
17
|
fastlife/adapters/jinjax/jinjax_ext/inspectable_catalog.py,sha256=KHOYTT6UNA41QwyLNQVoG4trOVXYdChlRmqq_G1pv1s,2987
|
8
|
-
fastlife/adapters/jinjax/jinjax_ext/inspectable_component.py,sha256=
|
9
|
-
fastlife/adapters/jinjax/jinjax_ext/jinjax_doc.py,sha256=
|
10
|
-
fastlife/adapters/jinjax/renderer.py,sha256=
|
18
|
+
fastlife/adapters/jinjax/jinjax_ext/inspectable_component.py,sha256=Ye_0XIKPC2H2XAvqEc1Er3YWyvNyYS4chuVkTSY5bAk,2909
|
19
|
+
fastlife/adapters/jinjax/jinjax_ext/jinjax_doc.py,sha256=S4-JNQ2NehUdKkc6mzAWRE_oyuw3XYPkR53RArgpDFk,10218
|
20
|
+
fastlife/adapters/jinjax/renderer.py,sha256=8Pv2Ivg8iObPa-LeIfj764p2MEq78wzHqxZeLDIdLc8,5255
|
11
21
|
fastlife/adapters/jinjax/widget_factory/__init__.py,sha256=Dy_2xr_YDAyEF9WtNpjV-aYaehRO1iKEIHVFdfFeszw,59
|
12
22
|
fastlife/adapters/jinjax/widget_factory/base.py,sha256=TLEpYdekR4AeHhIie_DICc_oSvQaUaL8GlatqNiRewg,1046
|
13
|
-
fastlife/adapters/jinjax/widget_factory/bool_builder.py,sha256=
|
14
|
-
fastlife/adapters/jinjax/widget_factory/emailstr_builder.py,sha256=
|
15
|
-
fastlife/adapters/jinjax/widget_factory/enum_builder.py,sha256=
|
16
|
-
fastlife/adapters/jinjax/widget_factory/factory.py,sha256=
|
17
|
-
fastlife/adapters/jinjax/widget_factory/literal_builder.py,sha256=
|
18
|
-
fastlife/adapters/jinjax/widget_factory/model_builder.py,sha256=
|
19
|
-
fastlife/adapters/jinjax/widget_factory/secretstr_builder.py,sha256=
|
20
|
-
fastlife/adapters/jinjax/widget_factory/sequence_builder.py,sha256=
|
21
|
-
fastlife/adapters/jinjax/widget_factory/set_builder.py,sha256=
|
22
|
-
fastlife/adapters/jinjax/widget_factory/simpletype_builder.py,sha256=
|
23
|
-
fastlife/adapters/jinjax/widget_factory/union_builder.py,sha256
|
23
|
+
fastlife/adapters/jinjax/widget_factory/bool_builder.py,sha256=ElIDb6rlUiwuDAetC22TreoMa9HDgoZ2euVV1VurFFY,1291
|
24
|
+
fastlife/adapters/jinjax/widget_factory/emailstr_builder.py,sha256=hO0_4yd0lZ8mLqAzM_FMecdtkSa03AIG13cvs6K9JPA,1532
|
25
|
+
fastlife/adapters/jinjax/widget_factory/enum_builder.py,sha256=agx67oUeVy5_BKzY4WV0DxT67R43Vy74CoeHl9PBvK4,1527
|
26
|
+
fastlife/adapters/jinjax/widget_factory/factory.py,sha256=zTa6zbpW5lAh_eHlhO6XBP2GbeDTHatymhMAJQ-alTI,5915
|
27
|
+
fastlife/adapters/jinjax/widget_factory/literal_builder.py,sha256=mrtWbDMKNFtw5ufJK3DnkkttGGk16EnDQhejyOd57Ys,1758
|
28
|
+
fastlife/adapters/jinjax/widget_factory/model_builder.py,sha256=WgIEUExtGO_s9AlNQlaTG_136ipe64MIJsNP0nlnsOc,2236
|
29
|
+
fastlife/adapters/jinjax/widget_factory/secretstr_builder.py,sha256=JJLqN74tUSTDDBYcRLDuqOLSL0P16S1Fp-SqTCdjjgg,1573
|
30
|
+
fastlife/adapters/jinjax/widget_factory/sequence_builder.py,sha256=j5KRfK5R8q_QdzGqjG86mjoKTWH7gvhjXesFAoItPaU,1944
|
31
|
+
fastlife/adapters/jinjax/widget_factory/set_builder.py,sha256=kwtVLATkoOFTcKBKHk7xZwQxRomPCic0sp4Bsd8YQfM,2742
|
32
|
+
fastlife/adapters/jinjax/widget_factory/simpletype_builder.py,sha256=olP66B9AMY1X8fgEAxhMdozWN_w1TtcIAIW6uPJRSng,1570
|
33
|
+
fastlife/adapters/jinjax/widget_factory/union_builder.py,sha256=qQOK3Y4I0Tg0XOzU_DwseaaKRmqQ7ORMfFyIHd6oysU,2841
|
24
34
|
fastlife/adapters/jinjax/widgets/__init__.py,sha256=HERnX9xiXUbTDz3XtlnHWABTBjhIq_kkBgWs5E6ZIMY,42
|
25
|
-
fastlife/adapters/jinjax/widgets/base.py,sha256=
|
26
|
-
fastlife/adapters/jinjax/widgets/boolean.py,sha256=
|
27
|
-
fastlife/adapters/jinjax/widgets/checklist.py,sha256=
|
28
|
-
fastlife/adapters/jinjax/widgets/dropdown.py,sha256=
|
29
|
-
fastlife/adapters/jinjax/widgets/hidden.py,sha256=
|
30
|
-
fastlife/adapters/jinjax/widgets/model.py,sha256=
|
31
|
-
fastlife/adapters/jinjax/widgets/sequence.py,sha256=
|
32
|
-
fastlife/adapters/jinjax/widgets/text.py,sha256=
|
33
|
-
fastlife/adapters/jinjax/widgets/union.py,sha256=
|
35
|
+
fastlife/adapters/jinjax/widgets/base.py,sha256=jU-oklWuM6MPlNzBvYO0HtxUrUteb-Dh96OudPLFJx4,4120
|
36
|
+
fastlife/adapters/jinjax/widgets/boolean.py,sha256=GFvyO2Lz-vTJ8lpX2UrkJk7ymu0vU-xnBBEmyBKamJg,613
|
37
|
+
fastlife/adapters/jinjax/widgets/checklist.py,sha256=xsr_edMu1nTcNnMEs1AAS3U-ugK95pEqn5NV5hjTeI0,1747
|
38
|
+
fastlife/adapters/jinjax/widgets/dropdown.py,sha256=ou8U48txShr8IXdwF4_pBvTn1VcR9SazZKzbLcsN3_0,1458
|
39
|
+
fastlife/adapters/jinjax/widgets/hidden.py,sha256=IKcVYs6NjN8YjW-UTr3DRBong6Wrc0QLgcp8U9JoQmE,638
|
40
|
+
fastlife/adapters/jinjax/widgets/model.py,sha256=YBIEWa_6mnmrBnesXjLTrpJ4drUS2CIorNmhK24cz7Q,1298
|
41
|
+
fastlife/adapters/jinjax/widgets/sequence.py,sha256=XhIPRJyE9UXFetlDQA83N64kKlTqkj6WPcgPm6XF7mo,2559
|
42
|
+
fastlife/adapters/jinjax/widgets/text.py,sha256=uYdJ1bjA3-2vEumh2nnd264wAaHU758ZxEiN2BaqtcE,2143
|
43
|
+
fastlife/adapters/jinjax/widgets/union.py,sha256=roCoFA82dLjF1XFW6UYaV7SCQWdFsSAT8Ux7KEB6_Us,2602
|
34
44
|
fastlife/components/A.jinja,sha256=rjnOFNpM2SUeJ0P8FDe3jzc_1WlsL65Kv-tb6KMCEpw,1389
|
35
45
|
fastlife/components/Button.jinja,sha256=COtCjDpzGLNqtBUYsHw7gdUay4kff3KdLJFAzrEnMmo,2310
|
36
46
|
fastlife/components/Checkbox.jinja,sha256=47_E9uPdr3QKUvRVhNQA7VE0uh5FVslQM26cdF0WCtY,753
|
37
|
-
fastlife/components/CsrfToken.jinja,sha256=
|
47
|
+
fastlife/components/CsrfToken.jinja,sha256=mS0q-3_hAevl_waWEPaN0QAYOBzMyzl-W1PSpEHUBA0,215
|
38
48
|
fastlife/components/Details.jinja,sha256=BKyhSU7bZdbd_deTjmAGcMbgUoQW3h8JSR3thH-2oJA,741
|
39
|
-
fastlife/components/Form.jinja,sha256=
|
49
|
+
fastlife/components/Form.jinja,sha256=Aukx9cVR8Af1nIsdHst3Qk7Bz34g1RpDhl7WOIcy0Tg,2094
|
40
50
|
fastlife/components/H1.jinja,sha256=ODwQMgwtuy2E2ShgamjFDlnCwOQQuuLIhvEzUF66nYM,375
|
41
51
|
fastlife/components/H2.jinja,sha256=LcBE2R_N50gio01nxH9qhp8_G1HxOT91xG_u8J8ae_Q,375
|
42
52
|
fastlife/components/H3.jinja,sha256=3PzxfQh07A35Og6dE5ow9BZdNp2Qnu7OuVeWREvD7Uo,375
|
@@ -1671,67 +1681,56 @@ fastlife/components/icons/solid/Wrench.jinja,sha256=ZdpxRZTC5p54FGWw3bgeaQyaPooJ
|
|
1671
1681
|
fastlife/components/icons/solid/WrenchScrewdriver.jinja,sha256=bqF-g6PTJds_KK2cMosVfycBVIIrmy_3sCaTkb9-C9o,1566
|
1672
1682
|
fastlife/components/icons/solid/XCircle.jinja,sha256=pO93hG8JImNOy94B62tN7fdzkzGvSsqkSkkZlkLaxeo,791
|
1673
1683
|
fastlife/components/icons/solid/XMark.jinja,sha256=c-ngdLuYwEMicwm4-Aj4xcEc1uQ_LrBoPhdDhQutEA8,705
|
1674
|
-
fastlife/components/pydantic_form/Boolean.jinja,sha256=PsuEGHO8Fo0tqsgY1S1vyDZkrtwNo9zOGBLQM3doUCM,589
|
1675
|
-
fastlife/components/pydantic_form/Checklist.jinja,sha256=mWFntBPhJJV1oX-Y4ATQirQYd8o0qxLOyoup0hwiItg,919
|
1676
|
-
fastlife/components/pydantic_form/Dropdown.jinja,sha256=zAXRPE3as2nCAqvheqh9J2S1e46olwVm18CWUQ3Tj5g,688
|
1677
1684
|
fastlife/components/pydantic_form/Error.jinja,sha256=vVSb1BKyKLOD4IOAM7aCKSNh7aAlmoiZVgRuvDCwLIo,205
|
1678
|
-
fastlife/components/pydantic_form/
|
1685
|
+
fastlife/components/pydantic_form/FatalError.jinja,sha256=lFVlNrXzBR6ExMahq77h0tYlD46T2yUzsBwqO8Gn58g,338
|
1679
1686
|
fastlife/components/pydantic_form/Hint.jinja,sha256=8leBpfMGDmalc_KAjr2paTojr_rwq-luS6m_1BGj7Tw,202
|
1680
|
-
fastlife/components/pydantic_form/
|
1681
|
-
fastlife/
|
1682
|
-
fastlife/
|
1683
|
-
fastlife/
|
1684
|
-
fastlife/components/pydantic_form/Union.jinja,sha256=czTska54z9KCZKu-FaycLmOvtH6y6CGUFQ8DHnkjrJk,1461
|
1685
|
-
fastlife/components/pydantic_form/Widget.jinja,sha256=EXskDqt22D5grpGVwlZA3ndve2Wr_6yQH4qVE9c31Og,397
|
1686
|
-
fastlife/config/__init__.py,sha256=R0HXh0rt6Aecf5kJmXvhH-6QrQb1SyuI83bOU8T80fc,488
|
1687
|
-
fastlife/config/configurator.py,sha256=sVecDJbjeRQRjULjbQH1JCeBOqvS6DUeQGJ5Nh2HQlw,22649
|
1688
|
-
fastlife/config/exceptions.py,sha256=kH2-akbzGeODlY_1bUhbzDKqBFrpOoqnVom0WPm0IGg,1237
|
1687
|
+
fastlife/components/pydantic_form/Widget.jinja,sha256=PgguUpvhG6CY9AW6H8qQMjKqjlybjDCAaFFAOHzrzVQ,418
|
1688
|
+
fastlife/config/__init__.py,sha256=5qpuaVYqi-AS0GgsfggM6rFsSwXgrqrLBo9jH6dVroc,407
|
1689
|
+
fastlife/config/configurator.py,sha256=nxowUriGj_MYcBlcBLB49HepDIbHiF4gG3baC_V3mFM,24702
|
1690
|
+
fastlife/config/exceptions.py,sha256=9MdBnbfy-Aw-KaIFzju0Kh8Snk41-v9LqK2w48Tdy1s,1169
|
1689
1691
|
fastlife/config/openapiextra.py,sha256=rYoerrn9sni2XwnO3gIWqaz7M0aDZPhVLjzqhDxue0o,514
|
1690
|
-
fastlife/config/
|
1691
|
-
fastlife/config/
|
1692
|
-
fastlife/
|
1693
|
-
fastlife/
|
1692
|
+
fastlife/config/resources.py,sha256=u6OgnbHfGkC5idH-YPNkIPf8GJnZpJoGVZ-Ym022BCo,8533
|
1693
|
+
fastlife/config/views.py,sha256=9CZ0qNi8vKvQuGo1GgM6cwNK8WwHOxwIHqtikAOaOHY,2399
|
1694
|
+
fastlife/domain/__init__.py,sha256=3zDDos5InVX0el9OO0lgSDGzdUNYIhlA6w4uhBh2pF8,29
|
1695
|
+
fastlife/domain/model/__init__.py,sha256=aoBjaSpDscuFXvtknJHwiNyoJRUpE-v4X54h_wNuo2Y,27
|
1696
|
+
fastlife/domain/model/asgi.py,sha256=RSTnfTsofOmCaWzHNuRGowjlyHYmoDCrXFbvNY_B55k,129
|
1697
|
+
fastlife/domain/model/csrf.py,sha256=BUiWK-S7rVciWHO1qTkM8e_KxzpF6gGC4MMJK1v6iDo,414
|
1698
|
+
fastlife/domain/model/form.py,sha256=WriBT1qUUIbf5x5iewo9ChEcr6k0en8jMTD0iaei5Pk,3253
|
1699
|
+
fastlife/domain/model/request.py,sha256=K0_pSOboKw5IRL8SCIsEuPZlPPe3h0F5cugZEVFdfoo,2531
|
1700
|
+
fastlife/domain/model/security_policy.py,sha256=iYBKXOYaXxM_n-rsyB25lO6RblSx9icTx1Bg-s3Iz9k,2942
|
1701
|
+
fastlife/domain/model/template.py,sha256=z9oxdKme1hMPuvk7mBiKR_tuVY8TqH77aTYqMgvEGl8,876
|
1702
|
+
fastlife/domain/model/types.py,sha256=64jJKFAi5x0e3vr8naHU1m_as0Qy8MS-s9CG0z6K1qc,381
|
1694
1703
|
fastlife/middlewares/__init__.py,sha256=C3DUOzR5EhlAv5Zq7h-Abyvkd7bUsJohTRSB2wpRYQE,220
|
1695
|
-
fastlife/middlewares/base.py,sha256=
|
1704
|
+
fastlife/middlewares/base.py,sha256=7FZE_1YU7wNew2u1qdYXjamosk4CXJmg1mJWGp6Xhc0,649
|
1696
1705
|
fastlife/middlewares/reverse_proxy/__init__.py,sha256=g1SoVDmenKzpAAPYHTEsWgdBByOxtLg9fGx6RV3i0ok,846
|
1697
|
-
fastlife/middlewares/reverse_proxy/x_forwarded.py,sha256=
|
1698
|
-
fastlife/middlewares/session/__init__.py,sha256=
|
1699
|
-
fastlife/middlewares/session/middleware.py,sha256=
|
1700
|
-
fastlife/middlewares/session/serializer.py,sha256=
|
1706
|
+
fastlife/middlewares/reverse_proxy/x_forwarded.py,sha256=PPDjcfwik5eoYaolSY1Y4x5QMKpDV0XrOP_i4Am0y30,1724
|
1707
|
+
fastlife/middlewares/session/__init__.py,sha256=ZhXWXs53A__F9wJKBJ87rW8Qyt5Mn866vhzKDxVZ4t0,1348
|
1708
|
+
fastlife/middlewares/session/middleware.py,sha256=ituZ5hNipDMkgCXNE4zbnmOcWEF151sucPo4I_FpY-I,3137
|
1709
|
+
fastlife/middlewares/session/serializer.py,sha256=nbJGiCJ_ryZxkW1I28kmK6hD3U98D4ZlUQA7B8_tngQ,635
|
1701
1710
|
fastlife/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1702
|
-
fastlife/
|
1703
|
-
fastlife/
|
1704
|
-
fastlife/
|
1705
|
-
fastlife/
|
1706
|
-
fastlife/
|
1707
|
-
fastlife/
|
1708
|
-
fastlife/
|
1709
|
-
fastlife/
|
1710
|
-
fastlife/
|
1711
|
-
fastlife/security/csrf.py,sha256=PIKG83LPqKz4kDALnZxIyPdYVwbNqsIryi7JPqRPQag,2168
|
1712
|
-
fastlife/security/policy.py,sha256=4WHu8xhR7tAdXUHpHY1kdVIdTOFsUl92R8IsIRyYMSU,5579
|
1713
|
-
fastlife/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1714
|
-
fastlife/services/locale_negociator.py,sha256=Np2O8s7xnYTpf5eCG7LvcfFJ2LV7p_k86NNrU9Lju88,846
|
1715
|
-
fastlife/services/policy.py,sha256=RfYGPjfEAAoHECUnZVLPZgN0iRanu8UKQSky6oAz81o,1687
|
1716
|
-
fastlife/services/templates.py,sha256=xSoVofpKXrZc1fDLAJyDDceJrKZaZRL1K8wFp2rGsE0,4272
|
1717
|
-
fastlife/services/translations.py,sha256=Akazow9YTb6N2IDdMZOAMef-grbAC7fM0nA3hw-mHt4,5315
|
1711
|
+
fastlife/service/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1712
|
+
fastlife/service/check_permission.py,sha256=-XD9qA11dLwen0bNCTy2Id_dCjzTJ0j7xuwB9IOtEY0,1695
|
1713
|
+
fastlife/service/csrf.py,sha256=wC1PaKOmZ3il0FF_kevxnlg9PxDqruRdLrNnOA3ZHrU,1886
|
1714
|
+
fastlife/service/locale_negociator.py,sha256=wXgQR8jCtPd5XtM-vvGZ4OrVnBQlt0deSoE2nInNfb0,770
|
1715
|
+
fastlife/service/registry.py,sha256=B6n5b_b0RgxJj0qFOpnrJFmG7_MPtvShwV6yH9V6vi0,2098
|
1716
|
+
fastlife/service/security_policy.py,sha256=Ytl8hgXtytvBNoBRHRmqVD96fJMnERnaL90q6XG7yI8,3036
|
1717
|
+
fastlife/service/templates.py,sha256=QPAIUbbZiekazz_jV3q4JCwQd6Q4KA6a4RDek2RWuhE,2548
|
1718
|
+
fastlife/service/translations.py,sha256=D-1D3pVNytEcps1u-0K7FmgQ8Wo6Yu4XVHvZrPhBmAI,5795
|
1719
|
+
fastlife/settings.py,sha256=q-rz4CEF2RQGow5-m-yZJOvdh3PPb2c1Q_ZLJGnu4VQ,3647
|
1718
1720
|
fastlife/shared_utils/__init__.py,sha256=i66ytuf-Ezo7jSiNQHIsBMVIcB-tDX0tg28-pUOlhzE,26
|
1719
|
-
fastlife/shared_utils/infer.py,sha256=
|
1721
|
+
fastlife/shared_utils/infer.py,sha256=0GflLkaWJ-4LZ1Ig3moR-_o55wwJ_p_vJ4xo-yi3lyA,1406
|
1720
1722
|
fastlife/shared_utils/resolver.py,sha256=Wb9cO2MWavpti63hju15xmwFMgaD5DsQaxikRpB39E8,3713
|
1721
|
-
fastlife/
|
1722
|
-
fastlife/templates/binding.py,sha256=0pE2btOwLf4xOEgBXVOyz_dIX9tBCYCaJ7RhZI3knbs,1464
|
1723
|
-
fastlife/templates/constants.py,sha256=MGdUjkF9hsPMN8rOS49eWbAApcb8FL-FAeFvJU8k90M,8387
|
1724
|
-
fastlife/templates/inline.py,sha256=wrZDAtd7zXcACHl2LVz0HqDT1VSPsiVy4srt3JSDiu4,704
|
1723
|
+
fastlife/template_globals.py,sha256=rJ7XB9DlPubejs_GDlEyO9V98QZTJnmdTznlguYOyoc,8386
|
1725
1724
|
fastlife/testing/__init__.py,sha256=VpxkS3Zp3t_hH8dBiLaGFGhsvt511dhBS_8fMoFXdmU,99
|
1726
1725
|
fastlife/testing/dom.py,sha256=dVzDoZokn-ii681UaEwAr-khM5KE-CHgXSSLSo24oH0,4489
|
1727
1726
|
fastlife/testing/form.py,sha256=ST0xNCoUqz_oD92cWHzQ6CbJ5hFopvu_NNKpOfiuYWY,7874
|
1728
1727
|
fastlife/testing/session.py,sha256=LEFFbiR67_x_g-ioudkY0C7PycHdbDfaIaoo_G7GXQ8,2226
|
1729
|
-
fastlife/testing/testclient.py,sha256=
|
1730
|
-
fastlife/views/__init__.py,sha256=
|
1731
|
-
fastlife/views/pydantic_form.py,sha256=
|
1732
|
-
fastlifeweb-0.
|
1733
|
-
fastlifeweb-0.
|
1734
|
-
fastlifeweb-0.
|
1735
|
-
fastlifeweb-0.
|
1736
|
-
tailwind.config.js,sha256=
|
1737
|
-
fastlifeweb-0.
|
1728
|
+
fastlife/testing/testclient.py,sha256=JTIgeMKooA8L4gEodeC3gy4Lo27y3WNswSEIKLlVVPs,6745
|
1729
|
+
fastlife/views/__init__.py,sha256=zG8gveL8e2zBdYx6_9jtZfpQ6qJT-MFnBY3xXkLwHZI,22
|
1730
|
+
fastlife/views/pydantic_form.py,sha256=o7EUItciAGL1OSaGNHo-3BTrYAk34GuWE7zGikjiAGY,1486
|
1731
|
+
fastlifeweb-0.22.0.dist-info/METADATA,sha256=8ual_JaeNHufsRyP5pdCPu2yHuVpzMzR53aitRbHmjo,3663
|
1732
|
+
fastlifeweb-0.22.0.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90
|
1733
|
+
fastlifeweb-0.22.0.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
|
1734
|
+
fastlifeweb-0.22.0.dist-info/licenses/LICENSE,sha256=NlRX9Z-dcv8X1VFW9odlIQBbgNN9pcO94XzvKp2R16o,1075
|
1735
|
+
tailwind.config.js,sha256=EN3EahBDmQBbmJvkw3SdGWNOkfkzw0cg-QvBikOhkrw,1348
|
1736
|
+
fastlifeweb-0.22.0.dist-info/RECORD,,
|
tailwind.config.js
CHANGED
@@ -1,13 +0,0 @@
|
|
1
|
-
{# doc Render a checkbox and a label for boolean field. #}
|
2
|
-
{# def widget: Annotated[fastlife.adapters.jinjax.widgets.boolean.BooleanWidget, "widget to display."] #}
|
3
|
-
<pydantic_form.Widget :widget="widget">
|
4
|
-
<div class="pt-4">
|
5
|
-
<div class="flex items-center">
|
6
|
-
<Checkbox :name="widget.name" type="checkbox" :id="widget.id" :checked="widget.value" value="1" />
|
7
|
-
<Label :for="widget.id" class="ms-2 text-base text-neutral-900 dark:text-white">
|
8
|
-
{{widget.title|safe}}
|
9
|
-
</Label>
|
10
|
-
</div>
|
11
|
-
<pydantic_form.Error :text="widget.error" />
|
12
|
-
</div>
|
13
|
-
</pydantic_form.Widget>
|
@@ -1,21 +0,0 @@
|
|
1
|
-
{# doc Render a list of checkbox and a label for Literal and enum fields #}
|
2
|
-
{# def widget: Annotated[fastlife.adapters.jinjax.widgets.checklist.ChecklistWidget, "widget to display."] #}
|
3
|
-
<pydantic_form.Widget :widget="widget">
|
4
|
-
<div class="pt-4">
|
5
|
-
<Details>
|
6
|
-
<Summary :id="widget.id + '-summary'">
|
7
|
-
<H3 :class="H3_SUMMARY_CLASS">{{widget.title}}</H3>
|
8
|
-
<pydantic_form.Error :text="widget.error" />
|
9
|
-
</Summary>
|
10
|
-
<div>
|
11
|
-
{% for value in widget.value %}
|
12
|
-
<div class="flex items-center mb-4">
|
13
|
-
<Checkbox :name="value.field_name" type="checkbox" :id="value.id" :value="value.value" :checked="value.checked" />
|
14
|
-
<Label :for="value.id" class="ms-2 text-base text-neutral-900 dark:text-white">{{value.label}}</Label>
|
15
|
-
<pydantic_form.Error :text="value.error" />
|
16
|
-
</div>
|
17
|
-
{% endfor %}
|
18
|
-
</div>
|
19
|
-
</Details>
|
20
|
-
</div>
|
21
|
-
</pydantic_form.Widget>
|
@@ -1,18 +0,0 @@
|
|
1
|
-
{# doc Render a Select with options #}
|
2
|
-
{# def widget: Annotated[fastlife.adapters.jinjax.widgets.dropdown.DropDownWidget, "widget to display."] #}
|
3
|
-
|
4
|
-
<pydantic_form.Widget :widget="widget">
|
5
|
-
<div class="pt-4">
|
6
|
-
<Label :for="widget.id">{{widget.title}}</Label>
|
7
|
-
<Select :name="widget.name" :id="widget.id">
|
8
|
-
{%- for opt in widget.options -%}
|
9
|
-
<Option :value="opt.value" id={{widget.id + "-" + opt.value.replace(" ", " -")}}
|
10
|
-
:selected="widget.value==opt.value">
|
11
|
-
{{- opt.text -}}
|
12
|
-
</Option>
|
13
|
-
{%- endfor -%}
|
14
|
-
</Select>
|
15
|
-
<pydantic_form.Error :text="widget.error" />
|
16
|
-
<pydantic_form.Hint :text="widget.hint" />
|
17
|
-
</div>
|
18
|
-
</pydantic_form.Widget>
|