Skip to content

Commit 8bf6c95

Browse files
committed
✨ Update error pages (#178)
1 parent f3ff9ff commit 8bf6c95

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

87 files changed

+8607
-13583
lines changed

.github/workflows/test_and_publish.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ jobs:
3232
- name: Setup node
3333
uses: actions/setup-node@v3
3434
with:
35-
node-version: 16
35+
node-version: 22
3636
- name: Install uv
3737
uses: astral-sh/setup-uv@v5
3838
with:

.github/workflows/test_pull_request_branch.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
- name: Setup node
2121
uses: actions/setup-node@v3
2222
with:
23-
node-version: 16
23+
node-version: 22
2424
- name: Install uv
2525
uses: astral-sh/setup-uv@v5
2626
with:

.gitignore

+3-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ dist/
1717
downloads/
1818
eggs/
1919
.eggs/
20-
lib/
20+
./lib/
2121
lib64/
2222
parts/
2323
sdist/
@@ -61,4 +61,5 @@ demo.db
6161
test.db
6262

6363
# Templates
64-
flama/templates
64+
flama/templates
65+
templates/out

flama/debug/data_structures.py

+12-6
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,11 @@ def from_exception(cls, exc: Exception, context: int = 10) -> "Error":
9191
frames = inspect.getinnerframes(exc.__traceback__, context) if exc.__traceback__ else []
9292
exc_cls = exc if inspect.isclass(exc) else exc.__class__
9393
return cls(
94-
error=f"{exc_cls.__module__}.{exc_cls.__name__}" if exc_cls.__module__ != "builtins" else exc_cls.__name__,
94+
error=(
95+
f"{exc_cls.__module__}.{exc_cls.__name__}"
96+
if exc_cls.__module__ not in ("builtins", "__main__")
97+
else exc_cls.__name__
98+
),
9599
description=str(exc),
96100
traceback=[Frame.from_frame_info(frame=frame) for frame in frames],
97101
)
@@ -144,20 +148,22 @@ def from_route(cls, route: t.Union["Route", "WebSocketRoute"]) -> "Endpoint":
144148

145149
@dataclasses.dataclass(frozen=True)
146150
class App:
147-
urls: list[t.Union[Endpoint, "App"]]
151+
apps: list["App"]
152+
endpoints: list[Endpoint]
148153
path: str
149154
name: t.Optional[str] = None
150155

151156
@classmethod
152157
def from_app(cls, app: t.Any, path: str = "/", name: t.Optional[str] = None) -> "App":
153-
urls: list[t.Union[Endpoint, App]] = []
158+
apps: list[App] = []
159+
endpoints: list[Endpoint] = []
154160
for route in app.routes:
155161
try:
156-
urls.append(App.from_app(route.app, path=route.path.path, name=route.name))
162+
apps.append(App.from_app(route.app, path=route.path.path, name=route.name))
157163
except AttributeError:
158-
urls.append(Endpoint.from_route(route))
164+
endpoints.append(Endpoint.from_route(route))
159165

160-
return cls(urls=urls, path=path, name=name)
166+
return cls(apps=apps, endpoints=endpoints, path=path, name=name)
161167

162168

163169
@dataclasses.dataclass(frozen=True)

flama/http.py

+19-1
Original file line numberDiff line numberDiff line change
@@ -210,15 +210,30 @@ def __init__(self, *args, **kwargs):
210210
*args,
211211
**{
212212
**kwargs,
213+
"comment_start_string": "||*",
214+
"comment_end_string": "*||",
213215
"block_start_string": "||%",
214216
"block_end_string": "%||",
215217
"variable_start_string": "||@",
216218
"variable_end_string": "@||",
217219
},
218220
)
219221

222+
self.filters["safe"] = self.safe
220223
self.filters["safe_json"] = self.safe_json
221224

225+
@t.overload
226+
def _escape(self, value: str) -> str: ...
227+
@t.overload
228+
def _escape(self, value: bool) -> bool: ...
229+
@t.overload
230+
def _escape(self, value: int) -> int: ...
231+
@t.overload
232+
def _escape(self, value: float) -> float: ...
233+
@t.overload
234+
def _escape(self, value: None) -> None: ...
235+
@t.overload
236+
def _escape(self, value: types.JSONField) -> types.JSONField: ...
222237
def _escape(self, value: types.JSONField) -> types.JSONField:
223238
if isinstance(value, (list, tuple)):
224239
return [self._escape(x) for x in value]
@@ -227,10 +242,13 @@ def _escape(self, value: types.JSONField) -> types.JSONField:
227242
return {k: self._escape(v) for k, v in value.items()}
228243

229244
if isinstance(value, str):
230-
return html.escape(value).replace("\n", "
")
245+
return html.escape(value).replace("\n", "

")
231246

232247
return value
233248

249+
def safe(self, value: str) -> str:
250+
return self._escape(value)
251+
234252
def safe_json(self, value: types.JSONField):
235253
return json.dumps(self._escape(value)).replace('"', '\\"')
236254

flama/types/json.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33
__all__ = ["JSONField", "JSONSchema"]
44

55

6-
JSONField = t.Union[str, int, float, bool, None, list["JSONField"], dict[str, "JSONField"]]
6+
JSONField = t.Union[str, bool, int, float, None, list["JSONField"], dict[str, "JSONField"]]
77
JSONSchema = dict[str, JSONField]

package-lock.json

+48
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"dependencies": {
3+
"@tabler/icons-react": "^3.30.0"
4+
}
5+
}

templates/.babelrc

-11
This file was deleted.

templates/.eslintignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
*.config.js
22
*.config.ts
33
.husky/
4-
node_modules/
4+
node_modules/

templates/babel.config.js

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/** @type {import("@babel/core").TransformOptions} */
2+
const config = {
3+
presets: [
4+
[
5+
'@babel/preset-env',
6+
{
7+
targets: '> 0.25%, not dead',
8+
useBuiltIns: 'usage',
9+
corejs: { version: 3, proposals: true },
10+
},
11+
],
12+
[
13+
'@babel/preset-react',
14+
{
15+
runtime: 'automatic',
16+
},
17+
],
18+
'@babel/preset-typescript',
19+
],
20+
plugins: ['@babel/plugin-transform-runtime', '@babel/plugin-transform-spread'],
21+
}
22+
23+
export default config

templates/eslint.config.js

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import path from 'node:path'
2+
3+
import js from '@eslint/js'
4+
import prettierConfig from 'eslint-config-prettier'
5+
import importPlugin from 'eslint-plugin-import'
6+
import reactPlugin from 'eslint-plugin-react'
7+
import reactHooksPlugin from 'eslint-plugin-react-hooks'
8+
import globals from 'globals'
9+
import ts from 'typescript-eslint'
10+
11+
/** @type {import("eslint").Linter.Config[]} */
12+
export default [
13+
{
14+
ignores: ['.*.js', '.*.ts', 'node_modules/', 'dist/', '.next/', 'public/', 'out/'],
15+
},
16+
{
17+
languageOptions: {
18+
globals: { ...globals.browser, ...globals.node, ...globals.serviceworker },
19+
},
20+
},
21+
prettierConfig,
22+
js.configs.recommended,
23+
...ts.configs.strict,
24+
...ts.configs.stylistic,
25+
{
26+
files: ['**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx'],
27+
...importPlugin.flatConfigs.recommended,
28+
rules: {
29+
// turn on errors for missing imports
30+
'import/no-unresolved': 'error',
31+
'@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_', varsIgnorePattern: '^React$' }],
32+
},
33+
settings: {
34+
'import/parsers': {
35+
'@typescript-eslint/parser': ['.ts', '.tsx'],
36+
},
37+
'import/resolver': {
38+
typescript: {
39+
project: path.resolve(process.cwd(), 'tsconfig.json'),
40+
},
41+
},
42+
},
43+
},
44+
{
45+
files: ['**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx'],
46+
...reactPlugin.configs.flat.recommended,
47+
plugins: {
48+
...reactPlugin.configs.flat.recommended.plugins,
49+
react: reactPlugin,
50+
'react-hooks': reactHooksPlugin,
51+
},
52+
rules: {
53+
...reactPlugin.configs.flat.recommended.rules,
54+
...reactPlugin.configs['jsx-runtime'].rules,
55+
...reactHooksPlugin.configs.recommended.rules,
56+
},
57+
},
58+
]

0 commit comments

Comments
 (0)