jararaca 0.3.11a12__tar.gz → 0.3.27__tar.gz
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.
Potentially problematic release.
This version of jararaca might be problematic. Click here for more details.
- {jararaca-0.3.11a12 → jararaca-0.3.27}/PKG-INFO +8 -6
- {jararaca-0.3.11a12 → jararaca-0.3.27}/README.md +1 -0
- jararaca-0.3.27/docs/expose-type.md +221 -0
- jararaca-0.3.27/docs/http-rpc.md +564 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/docs/index.md +144 -20
- jararaca-0.3.27/docs/interceptors.md +210 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/docs/messagebus.md +26 -6
- jararaca-0.3.27/docs/retry.md +79 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/docs/scheduler.md +44 -24
- {jararaca-0.3.11a12 → jararaca-0.3.27}/docs/websocket.md +24 -10
- {jararaca-0.3.11a12 → jararaca-0.3.27}/pyproject.toml +45 -4
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/__init__.py +147 -9
- jararaca-0.3.27/src/jararaca/cli.py +1022 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/core/uow.py +33 -5
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/messagebus/decorators.py +7 -4
- jararaca-0.3.27/src/jararaca/messagebus/implicit_headers.py +45 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/messagebus/interceptors/aiopika_publisher_interceptor.py +6 -1
- jararaca-0.3.27/src/jararaca/messagebus/worker.py +1778 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/microservice.py +73 -1
- jararaca-0.3.27/src/jararaca/observability/decorators.py +235 -0
- jararaca-0.3.27/src/jararaca/observability/hooks.py +86 -0
- jararaca-0.3.27/src/jararaca/observability/providers/otel.py +323 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/persistence/interceptors/aiosqa_interceptor.py +82 -73
- jararaca-0.3.27/src/jararaca/persistence/interceptors/constants.py +1 -0
- jararaca-0.3.27/src/jararaca/persistence/interceptors/decorators.py +45 -0
- jararaca-0.3.27/src/jararaca/presentation/server.py +196 -0
- jararaca-0.3.27/src/jararaca/presentation/websocket/redis.py +376 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/presentation/websocket/websocket_interceptor.py +35 -12
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/reflect/metadata.py +1 -1
- jararaca-0.3.27/src/jararaca/rpc/http/__init__.py +97 -0
- jararaca-0.3.27/src/jararaca/rpc/http/backends/__init__.py +10 -0
- jararaca-0.3.27/src/jararaca/rpc/http/backends/httpx.py +71 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/rpc/http/decorators.py +302 -6
- jararaca-0.3.27/src/jararaca/scheduler/beat_worker.py +802 -0
- jararaca-0.3.27/src/jararaca/tools/typescript/decorators.py +141 -0
- jararaca-0.3.27/src/jararaca/tools/typescript/interface_parser.py +1682 -0
- jararaca-0.3.27/src/jararaca/utils/retry.py +141 -0
- jararaca-0.3.11a12/src/jararaca/cli.py +0 -653
- jararaca-0.3.11a12/src/jararaca/messagebus/worker.py +0 -644
- jararaca-0.3.11a12/src/jararaca/observability/decorators.py +0 -97
- jararaca-0.3.11a12/src/jararaca/observability/providers/otel.py +0 -186
- jararaca-0.3.11a12/src/jararaca/presentation/server.py +0 -144
- jararaca-0.3.11a12/src/jararaca/presentation/websocket/redis.py +0 -155
- jararaca-0.3.11a12/src/jararaca/rpc/http/backends/httpx.py +0 -41
- jararaca-0.3.11a12/src/jararaca/scheduler/beat_worker.py +0 -342
- jararaca-0.3.11a12/src/jararaca/tools/typescript/interface_parser.py +0 -872
- jararaca-0.3.11a12/src/jararaca/utils/__init__.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/LICENSE +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/docs/CNAME +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/docs/architecture.md +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/docs/assets/_f04774c9-7e05-4da4-8b17-8be23f6a1475.jpeg +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/docs/assets/_f04774c9-7e05-4da4-8b17-8be23f6a1475.webp +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/docs/assets/tracing_example.png +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/docs/stylesheets/custom.css +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/__main__.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/broker_backend/__init__.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/broker_backend/mapper.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/broker_backend/redis_broker_backend.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/common/__init__.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/core/__init__.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/core/providers.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/di.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/files/entity.py.mako +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/lifecycle.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/messagebus/__init__.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/messagebus/bus_message_controller.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/messagebus/consumers/__init__.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/messagebus/interceptors/__init__.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/messagebus/interceptors/publisher_interceptor.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/messagebus/message.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/messagebus/publisher.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/observability/interceptor.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/observability/providers/__init__.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/persistence/base.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/persistence/exports.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/persistence/interceptors/__init__.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/persistence/session.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/persistence/sort_filter.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/persistence/utilities.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/presentation/__init__.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/presentation/decorators.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/presentation/hooks.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/presentation/http_microservice.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/presentation/websocket/__init__.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/presentation/websocket/base_types.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/presentation/websocket/context.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/presentation/websocket/decorators.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/presentation/websocket/types.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/py.typed +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/reflect/__init__.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/reflect/controller_inspect.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/rpc/__init__.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/rpc/http/backends/otel.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/rpc/http/httpx.py +0 -0
- {jararaca-0.3.11a12/src/jararaca/rpc/http → jararaca-0.3.27/src/jararaca/scheduler}/__init__.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/scheduler/decorators.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/scheduler/types.py +0 -0
- {jararaca-0.3.11a12/src/jararaca/rpc/http/backends → jararaca-0.3.27/src/jararaca/tools/app_config}/__init__.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/tools/app_config/decorators.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/tools/app_config/interceptor.py +0 -0
- {jararaca-0.3.11a12/src/jararaca/scheduler → jararaca-0.3.27/src/jararaca/tools/typescript}/__init__.py +0 -0
- {jararaca-0.3.11a12/src/jararaca/tools/app_config → jararaca-0.3.27/src/jararaca/utils}/__init__.py +0 -0
- {jararaca-0.3.11a12 → jararaca-0.3.27}/src/jararaca/utils/rabbitmq_utils.py +0 -0
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
2
|
Name: jararaca
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.27
|
|
4
4
|
Summary: A simple and fast API framework for Python
|
|
5
|
+
Home-page: https://github.com/LuscasLeo/jararaca
|
|
5
6
|
Author: Lucas S
|
|
6
7
|
Author-email: me@luscasleo.dev
|
|
7
8
|
Requires-Python: >=3.11,<4.0
|
|
8
9
|
Classifier: Programming Language :: Python :: 3
|
|
9
10
|
Classifier: Programming Language :: Python :: 3.11
|
|
10
11
|
Classifier: Programming Language :: Python :: 3.12
|
|
11
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
12
12
|
Provides-Extra: docs
|
|
13
13
|
Provides-Extra: http
|
|
14
14
|
Provides-Extra: opentelemetry
|
|
@@ -18,15 +18,16 @@ Requires-Dist: croniter (>=3.0.3,<4.0.0)
|
|
|
18
18
|
Requires-Dist: fastapi (>=0.113.0,<0.114.0)
|
|
19
19
|
Requires-Dist: frozendict (>=2.4.6,<3.0.0)
|
|
20
20
|
Requires-Dist: mako (>=1.3.5,<2.0.0)
|
|
21
|
-
Requires-Dist: opentelemetry-api (>=1.
|
|
22
|
-
Requires-Dist: opentelemetry-distro (>=0.
|
|
21
|
+
Requires-Dist: opentelemetry-api (>=1.38.0,<2.0.0) ; extra == "opentelemetry"
|
|
22
|
+
Requires-Dist: opentelemetry-distro (>=0.59b0,<0.60) ; extra == "opentelemetry"
|
|
23
23
|
Requires-Dist: opentelemetry-exporter-otlp (>=1.27.0,<2.0.0) ; extra == "opentelemetry"
|
|
24
24
|
Requires-Dist: opentelemetry-exporter-otlp-proto-http (>=1.27.0,<2.0.0) ; extra == "opentelemetry"
|
|
25
|
-
Requires-Dist: opentelemetry-sdk (>=1.
|
|
25
|
+
Requires-Dist: opentelemetry-sdk (>=1.38.0,<2.0.0) ; extra == "opentelemetry"
|
|
26
26
|
Requires-Dist: redis (>=5.0.8,<6.0.0)
|
|
27
27
|
Requires-Dist: sqlalchemy (>=2.0.34,<3.0.0)
|
|
28
28
|
Requires-Dist: types-croniter (>=3.0.3.20240731,<4.0.0.0)
|
|
29
29
|
Requires-Dist: types-redis (>=4.6.0.20240903,<5.0.0.0)
|
|
30
|
+
Requires-Dist: urllib3 (>=2.3.0,<3.0.0)
|
|
30
31
|
Requires-Dist: uvicorn (>=0.30.6,<0.31.0)
|
|
31
32
|
Requires-Dist: uvloop (>=0.20.0,<0.21.0)
|
|
32
33
|
Requires-Dist: watchdog (>=3.0.0,<4.0.0) ; extra == "watch"
|
|
@@ -73,6 +74,7 @@ Jararaca is an async-first microservice framework designed to simplify the devel
|
|
|
73
74
|
- Command-line tool for generating TypeScript types
|
|
74
75
|
- Support for REST endpoints, WebSocket events, and message bus payloads
|
|
75
76
|
- Type-safe frontend-backend communication
|
|
77
|
+
- **`@ExposeType` decorator** - Explicitly expose types for TypeScript generation without needing them in endpoints
|
|
76
78
|
|
|
77
79
|
### Hexagonal Architecture
|
|
78
80
|
- Clear separation of concerns
|
|
@@ -37,6 +37,7 @@ Jararaca is an async-first microservice framework designed to simplify the devel
|
|
|
37
37
|
- Command-line tool for generating TypeScript types
|
|
38
38
|
- Support for REST endpoints, WebSocket events, and message bus payloads
|
|
39
39
|
- Type-safe frontend-backend communication
|
|
40
|
+
- **`@ExposeType` decorator** - Explicitly expose types for TypeScript generation without needing them in endpoints
|
|
40
41
|
|
|
41
42
|
### Hexagonal Architecture
|
|
42
43
|
- Clear separation of concerns
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# Exposing Types for TypeScript Generation
|
|
2
|
+
|
|
3
|
+
The `@ExposeType` decorator allows you to explicitly expose types for TypeScript interface generation without requiring them to be directly referenced in REST endpoints, WebSocket messages, or as indirect dependencies.
|
|
4
|
+
|
|
5
|
+
## Use Cases
|
|
6
|
+
|
|
7
|
+
The `@ExposeType` decorator is useful when you have types that:
|
|
8
|
+
|
|
9
|
+
1. **Are used only on the frontend** - Types that exist for frontend state management, validation, or business logic
|
|
10
|
+
2. **Are part of a shared schema** - Common types that multiple parts of your application use but aren't directly in API contracts
|
|
11
|
+
3. **Need to be pre-generated** - Types that you want available immediately even if they're not yet used in any endpoints
|
|
12
|
+
4. **Are utility types** - Helper types, enums, or constants that the frontend needs to know about
|
|
13
|
+
|
|
14
|
+
## Basic Usage
|
|
15
|
+
|
|
16
|
+
Simply decorate any Pydantic model with `@ExposeType()`:
|
|
17
|
+
|
|
18
|
+
```python
|
|
19
|
+
from pydantic import BaseModel
|
|
20
|
+
|
|
21
|
+
from jararaca import ExposeType
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@ExposeType()
|
|
25
|
+
class UserPermission(BaseModel):
|
|
26
|
+
id: str
|
|
27
|
+
name: str
|
|
28
|
+
description: str
|
|
29
|
+
resource: str
|
|
30
|
+
action: str
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
This type will now be included in the generated TypeScript output when you run:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
jararaca gen-tsi app:app output.ts
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Example: Frontend-Only Types
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
from pydantic import BaseModel
|
|
43
|
+
|
|
44
|
+
from jararaca import ExposeType
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@ExposeType()
|
|
48
|
+
class FilterState(BaseModel):
|
|
49
|
+
"""Frontend state for table filtering."""
|
|
50
|
+
search_query: str
|
|
51
|
+
sort_column: str
|
|
52
|
+
sort_direction: str
|
|
53
|
+
page: int
|
|
54
|
+
page_size: int
|
|
55
|
+
|
|
56
|
+
@ExposeType()
|
|
57
|
+
class UITheme(BaseModel):
|
|
58
|
+
"""Frontend theme configuration."""
|
|
59
|
+
primary_color: str
|
|
60
|
+
secondary_color: str
|
|
61
|
+
dark_mode: bool
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Example: Error Codes and Constants
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
from enum import Enum
|
|
68
|
+
|
|
69
|
+
from pydantic import BaseModel
|
|
70
|
+
|
|
71
|
+
from jararaca import ExposeType
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
@ExposeType()
|
|
75
|
+
class ErrorCode(str, Enum):
|
|
76
|
+
"""Standard error codes."""
|
|
77
|
+
UNAUTHORIZED = "UNAUTHORIZED"
|
|
78
|
+
NOT_FOUND = "NOT_FOUND"
|
|
79
|
+
VALIDATION_ERROR = "VALIDATION_ERROR"
|
|
80
|
+
INTERNAL_ERROR = "INTERNAL_ERROR"
|
|
81
|
+
|
|
82
|
+
@ExposeType()
|
|
83
|
+
class ApiErrorDetail(BaseModel):
|
|
84
|
+
"""Detailed error information."""
|
|
85
|
+
code: ErrorCode
|
|
86
|
+
message: str
|
|
87
|
+
field: str | None = None
|
|
88
|
+
details: dict[str, str] | None = None
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Example: Complex Nested Types
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
from pydantic import BaseModel
|
|
95
|
+
|
|
96
|
+
from jararaca import ExposeType
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
@ExposeType()
|
|
100
|
+
class Address(BaseModel):
|
|
101
|
+
street: str
|
|
102
|
+
city: str
|
|
103
|
+
country: str
|
|
104
|
+
postal_code: str
|
|
105
|
+
|
|
106
|
+
@ExposeType()
|
|
107
|
+
class ContactInfo(BaseModel):
|
|
108
|
+
email: str
|
|
109
|
+
phone: str | None = None
|
|
110
|
+
address: Address
|
|
111
|
+
|
|
112
|
+
@ExposeType()
|
|
113
|
+
class Organization(BaseModel):
|
|
114
|
+
"""Complete organization structure."""
|
|
115
|
+
id: str
|
|
116
|
+
name: str
|
|
117
|
+
contacts: list[ContactInfo]
|
|
118
|
+
settings: dict[str, str]
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
When you expose a type with nested structures, the decorator ensures that all related types are also included in the TypeScript generation.
|
|
122
|
+
|
|
123
|
+
## Comparison: With vs Without @ExposeType
|
|
124
|
+
|
|
125
|
+
### Without @ExposeType
|
|
126
|
+
|
|
127
|
+
```python
|
|
128
|
+
class UserRole(BaseModel):
|
|
129
|
+
"""Only generated if used in an endpoint or as a dependency."""
|
|
130
|
+
id: str
|
|
131
|
+
name: str
|
|
132
|
+
|
|
133
|
+
@RestController("/api/users")
|
|
134
|
+
class UserController:
|
|
135
|
+
@Get("/{user_id}")
|
|
136
|
+
async def get_user(self, user_id: str) -> UserResponse:
|
|
137
|
+
# UserRole is only generated if UserResponse references it
|
|
138
|
+
return UserResponse(...)
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### With @ExposeType
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
@ExposeType()
|
|
145
|
+
class UserRole(BaseModel):
|
|
146
|
+
"""Always generated, available immediately."""
|
|
147
|
+
id: str
|
|
148
|
+
name: str
|
|
149
|
+
|
|
150
|
+
@RestController("/api/users")
|
|
151
|
+
class UserController:
|
|
152
|
+
@Get("/{user_id}")
|
|
153
|
+
async def get_user(self, user_id: str) -> UserResponse:
|
|
154
|
+
# UserRole is available in TypeScript even if not used yet
|
|
155
|
+
return UserResponse(...)
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Integration with Other Decorators
|
|
159
|
+
|
|
160
|
+
The `@ExposeType` decorator works seamlessly with other TypeScript generation decorators:
|
|
161
|
+
|
|
162
|
+
```python
|
|
163
|
+
from jararaca import ExposeType, SplitInputOutput
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
@ExposeType()
|
|
167
|
+
@SplitInputOutput()
|
|
168
|
+
class UserProfile(BaseModel):
|
|
169
|
+
"""Generates UserProfileInput and UserProfileOutput interfaces."""
|
|
170
|
+
id: str
|
|
171
|
+
username: str
|
|
172
|
+
email: str
|
|
173
|
+
created_at: str
|
|
174
|
+
updated_at: str
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
This creates both `UserProfileInput` and `UserProfileOutput` TypeScript interfaces.
|
|
178
|
+
|
|
179
|
+
## Best Practices
|
|
180
|
+
|
|
181
|
+
1. **Use for shared types**: Apply `@ExposeType` to types that are used across multiple parts of your application
|
|
182
|
+
2. **Document the purpose**: Add clear docstrings explaining why a type is exposed
|
|
183
|
+
3. **Avoid overuse**: Only expose types that the frontend actually needs - don't expose internal implementation details
|
|
184
|
+
4. **Combine with other decorators**: Use alongside `@SplitInputOutput` when appropriate
|
|
185
|
+
5. **Group related types**: Keep exposed types in dedicated modules (e.g., `shared_types.py`)
|
|
186
|
+
|
|
187
|
+
## Viewing Exposed Types
|
|
188
|
+
|
|
189
|
+
All types decorated with `@ExposeType` are tracked globally. You can check which types are exposed:
|
|
190
|
+
|
|
191
|
+
```python
|
|
192
|
+
from jararaca.tools.typescript.decorators import ExposeType
|
|
193
|
+
|
|
194
|
+
# Get all exposed types
|
|
195
|
+
exposed = ExposeType.get_all_exposed_types()
|
|
196
|
+
print(f"Exposed {len(exposed)} types: {[t.__name__ for t in exposed]}")
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## Generated TypeScript
|
|
200
|
+
|
|
201
|
+
Given this Python code:
|
|
202
|
+
|
|
203
|
+
```python
|
|
204
|
+
@ExposeType()
|
|
205
|
+
class NotificationPreference(BaseModel):
|
|
206
|
+
email_enabled: bool
|
|
207
|
+
push_enabled: bool
|
|
208
|
+
frequency: str
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
The generated TypeScript will be:
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
export interface NotificationPreference {
|
|
215
|
+
emailEnabled: boolean;
|
|
216
|
+
pushEnabled: boolean;
|
|
217
|
+
frequency: string;
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
The type is available in your TypeScript code even if no REST endpoint uses it yet.
|