django-cfg 1.4.17__py3-none-any.whl → 1.4.20__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.
- django_cfg/apps/knowbase/models/archive.py +2 -2
- django_cfg/apps/knowbase/urls.py +3 -24
- django_cfg/apps/knowbase/urls_admin.py +23 -0
- django_cfg/apps/knowbase/urls_system.py +26 -0
- django_cfg/apps/urls.py +5 -3
- django_cfg/modules/django_client/core/generator/typescript/fetchers_generator.py +57 -11
- django_cfg/modules/django_client/core/generator/typescript/generator.py +1 -1
- django_cfg/modules/django_client/core/generator/typescript/hooks_generator.py +21 -12
- django_cfg/modules/django_client/core/generator/typescript/models_generator.py +15 -6
- django_cfg/modules/django_client/core/generator/typescript/operations_generator.py +65 -10
- django_cfg/modules/django_client/core/generator/typescript/schemas_generator.py +54 -36
- django_cfg/modules/django_client/core/generator/typescript/templates/hooks/hooks.ts.jinja +1 -0
- django_cfg/modules/django_client/core/generator/typescript/templates/hooks/mutation_hook.ts.jinja +3 -3
- django_cfg/modules/django_client/core/generator/typescript/templates/hooks/query_hook.ts.jinja +8 -9
- django_cfg/pyproject.toml +1 -1
- {django_cfg-1.4.17.dist-info → django_cfg-1.4.20.dist-info}/METADATA +1 -1
- {django_cfg-1.4.17.dist-info → django_cfg-1.4.20.dist-info}/RECORD +20 -18
- {django_cfg-1.4.17.dist-info → django_cfg-1.4.20.dist-info}/WHEEL +0 -0
- {django_cfg-1.4.17.dist-info → django_cfg-1.4.20.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.4.17.dist-info → django_cfg-1.4.20.dist-info}/licenses/LICENSE +0 -0
@@ -20,8 +20,8 @@ class ArchiveType(models.TextChoices):
|
|
20
20
|
"""Supported archive formats."""
|
21
21
|
ZIP = "zip", "ZIP"
|
22
22
|
TAR = "tar", "TAR"
|
23
|
-
TAR_GZ = "tar.gz", "TAR
|
24
|
-
TAR_BZ2 = "tar.bz2", "TAR
|
23
|
+
TAR_GZ = "tar.gz", "TAR GZ"
|
24
|
+
TAR_BZ2 = "tar.bz2", "TAR BZ2"
|
25
25
|
|
26
26
|
|
27
27
|
class ContentType(models.TextChoices):
|
django_cfg/apps/knowbase/urls.py
CHANGED
@@ -4,24 +4,8 @@ Knowledge Base URL Configuration
|
|
4
4
|
|
5
5
|
from django.urls import path, include
|
6
6
|
from rest_framework.routers import DefaultRouter
|
7
|
-
from .views import (
|
8
|
-
DocumentViewSet, ChatViewSet, ChatSessionViewSet,
|
9
|
-
DocumentArchiveViewSet, ArchiveItemViewSet, ArchiveItemChunkViewSet
|
10
|
-
)
|
11
7
|
from .views.public_views import PublicDocumentViewSet, PublicCategoryViewSet
|
12
8
|
|
13
|
-
# Create router and register viewsets
|
14
|
-
router = DefaultRouter()
|
15
|
-
router.register(r'documents', DocumentViewSet, basename='document')
|
16
|
-
router.register(r'chat', ChatViewSet, basename='chat')
|
17
|
-
router.register(r'sessions', ChatSessionViewSet, basename='session')
|
18
|
-
|
19
|
-
# Archive router for authenticated users
|
20
|
-
archive_router = DefaultRouter()
|
21
|
-
archive_router.register(r'archives', DocumentArchiveViewSet, basename='archive')
|
22
|
-
archive_router.register(r'items', ArchiveItemViewSet, basename='archive-item')
|
23
|
-
archive_router.register(r'chunks', ArchiveItemChunkViewSet, basename='archive-chunk')
|
24
|
-
|
25
9
|
# Public router for client access
|
26
10
|
public_router = DefaultRouter()
|
27
11
|
public_router.register(r'documents', PublicDocumentViewSet, basename='public-document')
|
@@ -29,15 +13,10 @@ public_router.register(r'categories', PublicCategoryViewSet, basename='public-ca
|
|
29
13
|
|
30
14
|
# URL patterns
|
31
15
|
urlpatterns = [
|
32
|
-
|
33
|
-
path('admin/', include(router.urls)),
|
34
|
-
|
35
|
-
# Archive API endpoints (require authentication)
|
36
|
-
path('', include(archive_router.urls)),
|
37
|
-
|
16
|
+
|
38
17
|
# Public API endpoints (no authentication required)
|
39
|
-
path('
|
18
|
+
path('', include(public_router.urls)),
|
40
19
|
]
|
41
20
|
|
42
21
|
# Add app name for namespacing
|
43
|
-
app_name = '
|
22
|
+
app_name = 'cfg_knowbase'
|
@@ -0,0 +1,23 @@
|
|
1
|
+
"""
|
2
|
+
Knowledge Base URL Configuration
|
3
|
+
"""
|
4
|
+
|
5
|
+
from django.urls import path, include
|
6
|
+
from rest_framework.routers import DefaultRouter
|
7
|
+
from .views import (
|
8
|
+
DocumentViewSet, ChatViewSet, ChatSessionViewSet,
|
9
|
+
)
|
10
|
+
|
11
|
+
# Create router and register viewsets
|
12
|
+
router = DefaultRouter()
|
13
|
+
router.register(r'documents', DocumentViewSet, basename='document')
|
14
|
+
router.register(r'chat', ChatViewSet, basename='chat')
|
15
|
+
router.register(r'sessions', ChatSessionViewSet, basename='session')
|
16
|
+
|
17
|
+
# URL patterns
|
18
|
+
urlpatterns = [
|
19
|
+
# Admin API endpoints (require authentication + admin rights)
|
20
|
+
path('', include(router.urls)),
|
21
|
+
]
|
22
|
+
|
23
|
+
app_name = 'cfg_knowbase_admin'
|
@@ -0,0 +1,26 @@
|
|
1
|
+
"""
|
2
|
+
Knowledge Base URL Configuration
|
3
|
+
"""
|
4
|
+
|
5
|
+
from django.urls import path, include
|
6
|
+
from rest_framework.routers import DefaultRouter
|
7
|
+
from .views import (
|
8
|
+
DocumentArchiveViewSet, ArchiveItemViewSet, ArchiveItemChunkViewSet
|
9
|
+
)
|
10
|
+
|
11
|
+
# Archive router for authenticated users
|
12
|
+
archive_router = DefaultRouter()
|
13
|
+
archive_router.register(r'archives', DocumentArchiveViewSet, basename='archive')
|
14
|
+
archive_router.register(r'items', ArchiveItemViewSet, basename='archive-item')
|
15
|
+
archive_router.register(r'chunks', ArchiveItemChunkViewSet, basename='archive-chunk')
|
16
|
+
|
17
|
+
# URL patterns
|
18
|
+
urlpatterns = [
|
19
|
+
|
20
|
+
# Archive API endpoints (require authentication)
|
21
|
+
path('', include(archive_router.urls)),
|
22
|
+
|
23
|
+
]
|
24
|
+
|
25
|
+
# Add app name for namespacing
|
26
|
+
app_name = 'cfg_knowbase_system'
|
django_cfg/apps/urls.py
CHANGED
@@ -22,6 +22,9 @@ def get_enabled_cfg_apps() -> List[str]:
|
|
22
22
|
|
23
23
|
if base_module.is_accounts_enabled():
|
24
24
|
enabled_apps.append("django_cfg.apps.accounts")
|
25
|
+
|
26
|
+
if base_module.is_knowbase_enabled():
|
27
|
+
enabled_apps.append("django_cfg.apps.knowbase")
|
25
28
|
|
26
29
|
if base_module.is_support_enabled():
|
27
30
|
enabled_apps.append("django_cfg.apps.support")
|
@@ -32,9 +35,6 @@ def get_enabled_cfg_apps() -> List[str]:
|
|
32
35
|
if base_module.is_leads_enabled():
|
33
36
|
enabled_apps.append("django_cfg.apps.leads")
|
34
37
|
|
35
|
-
if base_module.is_knowbase_enabled():
|
36
|
-
enabled_apps.append("django_cfg.apps.knowbase")
|
37
|
-
|
38
38
|
if base_module.is_agents_enabled():
|
39
39
|
enabled_apps.append("django_cfg.apps.agents")
|
40
40
|
|
@@ -114,6 +114,8 @@ APP_URL_MAP = {
|
|
114
114
|
],
|
115
115
|
"django_cfg.apps.knowbase": [
|
116
116
|
("cfg/knowbase/", "django_cfg.apps.knowbase.urls"),
|
117
|
+
("cfg/knowbase/admin/", "django_cfg.apps.knowbase.urls_admin"),
|
118
|
+
("cfg/knowbase/system/", "django_cfg.apps.knowbase.urls_system"),
|
117
119
|
],
|
118
120
|
"django_cfg.apps.agents": [
|
119
121
|
("cfg/agents/", "django_cfg.apps.agents.urls"),
|
@@ -159,7 +159,58 @@ class FetchersGenerator:
|
|
159
159
|
func_params.append(f"{param.name}: {param_type}")
|
160
160
|
api_call_params.append(param.name)
|
161
161
|
|
162
|
+
# Request body (passed as data or unpacked for multipart)
|
163
|
+
# NOTE: This must come BEFORE query params to match client method signature order!
|
164
|
+
if operation.request_body:
|
165
|
+
# Check if this is a file upload operation
|
166
|
+
is_multipart = operation.request_body.content_type == "multipart/form-data"
|
167
|
+
|
168
|
+
if is_multipart:
|
169
|
+
# For multipart, unpack data properties to match client signature
|
170
|
+
schema_name = operation.request_body.schema_name
|
171
|
+
if schema_name and schema_name in self.context.schemas:
|
172
|
+
schema = self.context.schemas[schema_name]
|
173
|
+
# Add data parameter in func signature (keeps API simple)
|
174
|
+
func_params.append(f"data: {schema_name}")
|
175
|
+
# But unpack when calling client (which expects individual params)
|
176
|
+
# IMPORTANT: Order must match client - required first, then optional
|
177
|
+
required_props = []
|
178
|
+
optional_props = []
|
179
|
+
|
180
|
+
for prop_name, prop in schema.properties.items():
|
181
|
+
if prop_name in schema.required:
|
182
|
+
required_props.append(prop_name)
|
183
|
+
else:
|
184
|
+
optional_props.append(prop_name)
|
185
|
+
|
186
|
+
# Add required first, then optional (matches client signature)
|
187
|
+
for prop_name in required_props + optional_props:
|
188
|
+
api_call_params.append(f"data.{prop_name}")
|
189
|
+
else:
|
190
|
+
# Inline schema - use data as-is
|
191
|
+
func_params.append(f"data: FormData")
|
192
|
+
api_call_params.append("data")
|
193
|
+
else:
|
194
|
+
# JSON request body - pass data object
|
195
|
+
schema_name = operation.request_body.schema_name
|
196
|
+
if schema_name and schema_name in self.context.schemas:
|
197
|
+
body_type = schema_name
|
198
|
+
else:
|
199
|
+
body_type = "any"
|
200
|
+
func_params.append(f"data: {body_type}")
|
201
|
+
api_call_params.append("data")
|
202
|
+
elif operation.patch_request_body:
|
203
|
+
# PATCH request body (optional)
|
204
|
+
schema_name = operation.patch_request_body.schema_name
|
205
|
+
if schema_name and schema_name in self.context.schemas:
|
206
|
+
func_params.append(f"data?: {schema_name}")
|
207
|
+
api_call_params.append("data")
|
208
|
+
else:
|
209
|
+
func_params.append(f"data?: any")
|
210
|
+
api_call_params.append("data")
|
211
|
+
|
162
212
|
# Query parameters (passed as params object, but unpacked when calling API)
|
213
|
+
# NOTE: This must come AFTER request body to match client method signature order!
|
163
214
|
if operation.query_parameters:
|
164
215
|
query_fields = []
|
165
216
|
# params is required only if all parameters are required
|
@@ -177,17 +228,6 @@ class FetchersGenerator:
|
|
177
228
|
params_optional = "" if all_required else "?"
|
178
229
|
func_params.append(f"params{params_optional}: {{ {'; '.join(query_fields)} }}")
|
179
230
|
|
180
|
-
# Request body (passed as data)
|
181
|
-
if operation.request_body:
|
182
|
-
schema_name = operation.request_body.schema_name
|
183
|
-
# Use schema only if it exists as a component (not inline)
|
184
|
-
if schema_name and schema_name in self.context.schemas:
|
185
|
-
body_type = schema_name
|
186
|
-
else:
|
187
|
-
body_type = "any"
|
188
|
-
func_params.append(f"data: {body_type}")
|
189
|
-
api_call_params.append("data")
|
190
|
-
|
191
231
|
return {
|
192
232
|
'func_params': ", ".join(func_params) if func_params else "",
|
193
233
|
'api_call_params': ", ".join(api_call_params) if api_call_params else ""
|
@@ -338,6 +378,12 @@ class FetchersGenerator:
|
|
338
378
|
# Only add if schema exists in components (not inline)
|
339
379
|
if operation.request_body.schema_name in self.context.schemas:
|
340
380
|
schema_names.add(operation.request_body.schema_name)
|
381
|
+
|
382
|
+
# Add patch request body schemas
|
383
|
+
if operation.patch_request_body and operation.patch_request_body.schema_name:
|
384
|
+
# Only add if schema exists in components (not inline)
|
385
|
+
if operation.patch_request_body.schema_name in self.context.schemas:
|
386
|
+
schema_names.add(operation.patch_request_body.schema_name)
|
341
387
|
|
342
388
|
# Get display name and folder name (use same naming as APIClient)
|
343
389
|
tag_display_name = self.base.tag_to_display_name(tag)
|
@@ -327,7 +327,7 @@ class TypeScriptGenerator(BaseGenerator):
|
|
327
327
|
|
328
328
|
# Generate individual schema files
|
329
329
|
for schema_name, schema in sorted(all_schemas.items()):
|
330
|
-
# Skip enum schemas (they use z.
|
330
|
+
# Skip enum schemas (they use z.enum() with literal values)
|
331
331
|
if schema.enum:
|
332
332
|
continue
|
333
333
|
|
@@ -207,7 +207,27 @@ class HooksGenerator:
|
|
207
207
|
func_params.append(f"{param.name}: {param_type}")
|
208
208
|
fetcher_params.append(param.name)
|
209
209
|
|
210
|
-
#
|
210
|
+
# Request body (must come BEFORE query params to match fetcher signature!)
|
211
|
+
if operation.request_body:
|
212
|
+
schema_name = operation.request_body.schema_name
|
213
|
+
# Use schema only if it exists as a component (not inline)
|
214
|
+
if schema_name and schema_name in self.context.schemas:
|
215
|
+
body_type = schema_name
|
216
|
+
else:
|
217
|
+
body_type = "any"
|
218
|
+
func_params.append(f"data: {body_type}")
|
219
|
+
fetcher_params.append("data")
|
220
|
+
elif operation.patch_request_body:
|
221
|
+
# PATCH request body (optional)
|
222
|
+
schema_name = operation.patch_request_body.schema_name
|
223
|
+
if schema_name and schema_name in self.context.schemas:
|
224
|
+
func_params.append(f"data?: {schema_name}")
|
225
|
+
fetcher_params.append("data")
|
226
|
+
else:
|
227
|
+
func_params.append(f"data?: any")
|
228
|
+
fetcher_params.append("data")
|
229
|
+
|
230
|
+
# Query parameters (must come AFTER request body to match fetcher signature!)
|
211
231
|
if operation.query_parameters:
|
212
232
|
query_fields = []
|
213
233
|
all_required = all(param.required for param in operation.query_parameters)
|
@@ -222,17 +242,6 @@ class HooksGenerator:
|
|
222
242
|
func_params.append(f"params{params_optional}: {{ {'; '.join(query_fields)} }}")
|
223
243
|
fetcher_params.append("params")
|
224
244
|
|
225
|
-
# Request body
|
226
|
-
if operation.request_body:
|
227
|
-
schema_name = operation.request_body.schema_name
|
228
|
-
# Use schema only if it exists as a component (not inline)
|
229
|
-
if schema_name and schema_name in self.context.schemas:
|
230
|
-
body_type = schema_name
|
231
|
-
else:
|
232
|
-
body_type = "any"
|
233
|
-
func_params.append(f"data: {body_type}")
|
234
|
-
fetcher_params.append("data")
|
235
|
-
|
236
245
|
return {
|
237
246
|
'func_params': ", ".join(func_params) if func_params else "",
|
238
247
|
'fetcher_params': ", ".join(fetcher_params) if fetcher_params else ""
|
@@ -162,17 +162,22 @@ class ModelsGenerator:
|
|
162
162
|
if ts_type.endswith(" | null"):
|
163
163
|
ts_type = ts_type[:-7] # Remove " | null"
|
164
164
|
else:
|
165
|
-
# Get TypeScript type
|
165
|
+
# Get TypeScript type
|
166
166
|
ts_type = schema.typescript_type
|
167
|
+
# Remove | null suffix to rebuild it properly based on schema.nullable
|
167
168
|
if ts_type.endswith(" | null"):
|
168
169
|
ts_type = ts_type[:-7] # Remove " | null"
|
169
170
|
|
170
171
|
# Check if required
|
171
172
|
is_required = name in required_fields
|
172
173
|
|
173
|
-
#
|
174
|
-
#
|
175
|
-
|
174
|
+
# Handle nullable and optional separately
|
175
|
+
# - nullable: add | null to type
|
176
|
+
# - not required: add ? optional marker
|
177
|
+
if schema.nullable:
|
178
|
+
ts_type = f"{ts_type} | null"
|
179
|
+
|
180
|
+
optional_marker = "" if is_required else "?"
|
176
181
|
|
177
182
|
# Comment
|
178
183
|
if schema.description:
|
@@ -203,10 +208,14 @@ class ModelsGenerator:
|
|
203
208
|
if not var_name or (isinstance(value, str) and value == ''):
|
204
209
|
continue
|
205
210
|
|
211
|
+
# Sanitize var_name: replace dots and spaces with underscores, convert to UPPER_CASE
|
212
|
+
# "TAR.GZ" -> "TAR_GZ", "TAR GZ" -> "TAR_GZ"
|
213
|
+
sanitized_var_name = var_name.replace('.', '_').replace(' ', '_').upper()
|
214
|
+
|
206
215
|
if isinstance(value, str):
|
207
|
-
member_lines.append(f'{
|
216
|
+
member_lines.append(f'{sanitized_var_name} = "{value}",')
|
208
217
|
else:
|
209
|
-
member_lines.append(f"{
|
218
|
+
member_lines.append(f"{sanitized_var_name} = {value},")
|
210
219
|
|
211
220
|
# Build enum
|
212
221
|
lines = []
|
@@ -56,17 +56,31 @@ class OperationsGenerator:
|
|
56
56
|
schema_name = operation.request_body.schema_name
|
57
57
|
if schema_name and schema_name in self.context.schemas:
|
58
58
|
schema = self.context.schemas[schema_name]
|
59
|
+
# Add required params first, then optional (TypeScript requirement)
|
60
|
+
required_params = []
|
61
|
+
optional_params = []
|
62
|
+
|
59
63
|
for prop_name, prop in schema.properties.items():
|
60
64
|
# Check if it's a file field (format: binary)
|
61
65
|
if prop.format == "binary":
|
62
|
-
|
66
|
+
param_str = f"{prop_name}: File | Blob"
|
63
67
|
else:
|
64
68
|
# Regular field in multipart
|
65
69
|
prop_type = self._map_param_type(prop.type)
|
66
70
|
if prop_name in schema.required:
|
67
|
-
|
71
|
+
param_str = f"{prop_name}: {prop_type}"
|
68
72
|
else:
|
69
|
-
|
73
|
+
param_str = f"{prop_name}?: {prop_type}"
|
74
|
+
|
75
|
+
# Separate required and optional
|
76
|
+
if prop_name in schema.required:
|
77
|
+
required_params.append(param_str)
|
78
|
+
else:
|
79
|
+
optional_params.append(param_str)
|
80
|
+
|
81
|
+
# Add required first, then optional
|
82
|
+
params.extend(required_params)
|
83
|
+
params.extend(optional_params)
|
70
84
|
else:
|
71
85
|
# Inline schema - use FormData
|
72
86
|
params.append("data: FormData")
|
@@ -98,7 +112,9 @@ class OperationsGenerator:
|
|
98
112
|
# Return type
|
99
113
|
primary_response = operation.primary_success_response
|
100
114
|
if primary_response and primary_response.schema_name:
|
101
|
-
if
|
115
|
+
# Check if response is paginated (has 'results' field)
|
116
|
+
is_paginated = primary_response.schema_name.startswith('Paginated')
|
117
|
+
if operation.is_list_operation and not is_paginated:
|
102
118
|
return_type = f"Models.{primary_response.schema_name}[]"
|
103
119
|
else:
|
104
120
|
return_type = f"Models.{primary_response.schema_name}"
|
@@ -151,15 +167,37 @@ class OperationsGenerator:
|
|
151
167
|
if use_rest_params and query_params_list:
|
152
168
|
# Extract parameters from args array
|
153
169
|
path_params_count = len(operation.path_parameters)
|
154
|
-
|
170
|
+
|
171
|
+
# For multipart, body params are unpacked as individual fields
|
172
|
+
if is_multipart and operation.request_body:
|
173
|
+
schema_name = operation.request_body.schema_name
|
174
|
+
if schema_name and schema_name in self.context.schemas:
|
175
|
+
schema = self.context.schemas[schema_name]
|
176
|
+
body_params_count = len(schema.properties)
|
177
|
+
else:
|
178
|
+
body_params_count = 1 # data: FormData
|
179
|
+
else:
|
180
|
+
body_params_count = 1 if (operation.request_body or operation.patch_request_body) else 0
|
181
|
+
|
155
182
|
first_query_pos = path_params_count + body_params_count
|
156
183
|
|
157
184
|
# Extract path parameters
|
158
185
|
for i, param in enumerate(operation.path_parameters):
|
159
186
|
body_lines.append(f"const {param.name} = args[{i}];")
|
160
187
|
|
161
|
-
# Extract body/data parameter
|
162
|
-
if
|
188
|
+
# Extract body/data parameter(s)
|
189
|
+
if is_multipart and operation.request_body:
|
190
|
+
schema_name = operation.request_body.schema_name
|
191
|
+
if schema_name and schema_name in self.context.schemas:
|
192
|
+
schema = self.context.schemas[schema_name]
|
193
|
+
# Extract each property as separate variable
|
194
|
+
arg_idx = path_params_count
|
195
|
+
for prop_name in schema.properties.keys():
|
196
|
+
body_lines.append(f"const {prop_name} = args[{arg_idx}];")
|
197
|
+
arg_idx += 1
|
198
|
+
else:
|
199
|
+
body_lines.append(f"const data = args[{path_params_count}];")
|
200
|
+
elif operation.request_body or operation.patch_request_body:
|
163
201
|
body_lines.append(f"const data = args[{path_params_count}];")
|
164
202
|
|
165
203
|
# Check if first query arg is object (params style) or primitive (old style)
|
@@ -185,7 +223,18 @@ class OperationsGenerator:
|
|
185
223
|
if use_rest_params:
|
186
224
|
# Extract params from args array - handle both calling styles
|
187
225
|
path_params_count = len(operation.path_parameters)
|
188
|
-
|
226
|
+
|
227
|
+
# For multipart, body params are unpacked as individual fields
|
228
|
+
if is_multipart and operation.request_body:
|
229
|
+
schema_name = operation.request_body.schema_name
|
230
|
+
if schema_name and schema_name in self.context.schemas:
|
231
|
+
schema = self.context.schemas[schema_name]
|
232
|
+
body_params_count = len(schema.properties)
|
233
|
+
else:
|
234
|
+
body_params_count = 1 # data: FormData
|
235
|
+
else:
|
236
|
+
body_params_count = 1 if (operation.request_body or operation.patch_request_body) else 0
|
237
|
+
|
189
238
|
first_query_pos = path_params_count + body_params_count
|
190
239
|
|
191
240
|
body_lines.append("let params;")
|
@@ -242,8 +291,14 @@ class OperationsGenerator:
|
|
242
291
|
|
243
292
|
# Handle response
|
244
293
|
if operation.is_list_operation and primary_response:
|
245
|
-
#
|
246
|
-
|
294
|
+
# Check if response is paginated
|
295
|
+
is_paginated = primary_response.schema_name.startswith('Paginated')
|
296
|
+
if is_paginated:
|
297
|
+
# Return full paginated response object
|
298
|
+
body_lines.append("return response;")
|
299
|
+
else:
|
300
|
+
# Extract results from array response
|
301
|
+
body_lines.append("return (response as any).results || [];")
|
247
302
|
elif return_type != "void":
|
248
303
|
body_lines.append("return response;")
|
249
304
|
else:
|
@@ -3,7 +3,7 @@ Zod Schemas Generator - Generates Zod validation schemas from IR.
|
|
3
3
|
|
4
4
|
This generator creates Zod schemas for runtime validation:
|
5
5
|
- Object schemas (z.object)
|
6
|
-
- Enum schemas (z.
|
6
|
+
- Enum schemas (z.enum)
|
7
7
|
- Array schemas (z.array)
|
8
8
|
- Type inference (z.infer<typeof Schema>)
|
9
9
|
"""
|
@@ -22,7 +22,7 @@ class SchemasGenerator:
|
|
22
22
|
Features:
|
23
23
|
- Runtime validation with Zod
|
24
24
|
- Type inference from schemas
|
25
|
-
- Enum validation with z.
|
25
|
+
- Enum validation with z.enum()
|
26
26
|
- Nested object validation
|
27
27
|
- Array and nullable types
|
28
28
|
"""
|
@@ -46,7 +46,7 @@ class SchemasGenerator:
|
|
46
46
|
>>> generate_schema(User)
|
47
47
|
export const UserSchema = z.object({
|
48
48
|
id: z.number(),
|
49
|
-
email: z.
|
49
|
+
email: z.email(),
|
50
50
|
username: z.string().min(1).max(150),
|
51
51
|
})
|
52
52
|
"""
|
@@ -74,7 +74,7 @@ class SchemasGenerator:
|
|
74
74
|
# Generate fields
|
75
75
|
if schema.properties:
|
76
76
|
for prop_name, prop_schema in schema.properties.items():
|
77
|
-
field_code = self._generate_field(prop_name, prop_schema, schema.required)
|
77
|
+
field_code = self._generate_field(prop_name, prop_schema, schema.required, parent_schema=schema)
|
78
78
|
lines.append(f" {field_code},")
|
79
79
|
|
80
80
|
lines.append("})")
|
@@ -86,60 +86,66 @@ class SchemasGenerator:
|
|
86
86
|
name: str,
|
87
87
|
schema: IRSchemaObject,
|
88
88
|
required_fields: list[str],
|
89
|
+
parent_schema: IRSchemaObject | None = None,
|
89
90
|
) -> str:
|
90
91
|
"""
|
91
92
|
Generate Zod field validation.
|
92
93
|
|
93
94
|
Examples:
|
94
95
|
id: z.number()
|
95
|
-
email: z.
|
96
|
+
email: z.email()
|
96
97
|
username: z.string().min(1).max(150)
|
97
|
-
status: z.nativeEnum(Enums.StatusEnum)
|
98
|
-
created_at: z.
|
98
|
+
status: z.nativeEnum(Enums.StatusEnum) # Reference to TypeScript enum
|
99
|
+
created_at: z.iso.datetime()
|
99
100
|
"""
|
100
101
|
# Check if this field is an enum
|
101
102
|
if schema.enum and schema.name:
|
102
|
-
# Use enum
|
103
|
+
# Use nativeEnum to reference TypeScript enum from enums.ts
|
103
104
|
zod_type = f"z.nativeEnum(Enums.{self.base.sanitize_enum_name(schema.name)})"
|
104
105
|
# Check if this field is a reference to an enum
|
105
106
|
elif schema.ref and schema.ref in self.context.schemas:
|
106
107
|
ref_schema = self.context.schemas[schema.ref]
|
107
108
|
if ref_schema.enum:
|
108
|
-
# Reference to enum component
|
109
|
+
# Reference to enum component - use nativeEnum
|
109
110
|
zod_type = f"z.nativeEnum(Enums.{self.base.sanitize_enum_name(schema.ref)})"
|
110
111
|
else:
|
111
112
|
# Reference to another schema
|
112
113
|
zod_type = f"{schema.ref}Schema"
|
113
114
|
else:
|
114
115
|
# Map TypeScript type to Zod type
|
115
|
-
zod_type = self._map_type_to_zod(schema)
|
116
|
+
zod_type = self._map_type_to_zod(schema, parent_schema=parent_schema)
|
116
117
|
|
117
118
|
# Check if required
|
118
119
|
is_required = name in required_fields
|
119
120
|
|
120
|
-
# Handle
|
121
|
-
#
|
122
|
-
|
121
|
+
# Handle nullable and optional separately
|
122
|
+
# - nullable: field can be null (use .nullable())
|
123
|
+
# - not required: field can be undefined (use .optional())
|
124
|
+
if schema.nullable:
|
125
|
+
zod_type = f"{zod_type}.nullable()"
|
126
|
+
|
127
|
+
if not is_required:
|
123
128
|
zod_type = f"{zod_type}.optional()"
|
124
129
|
|
125
130
|
return f"{name}: {zod_type}"
|
126
131
|
|
127
|
-
def _map_type_to_zod(self, schema: IRSchemaObject) -> str:
|
132
|
+
def _map_type_to_zod(self, schema: IRSchemaObject, parent_schema: IRSchemaObject | None = None) -> str:
|
128
133
|
"""
|
129
134
|
Map OpenAPI/TypeScript type to Zod validation.
|
130
135
|
|
131
136
|
Args:
|
132
137
|
schema: IRSchemaObject with type information
|
138
|
+
parent_schema: Parent schema (for context about patch models, etc.)
|
133
139
|
|
134
140
|
Returns:
|
135
141
|
Zod validation code
|
136
142
|
|
137
143
|
Examples:
|
138
144
|
string -> z.string()
|
139
|
-
string (format: email) -> z.
|
140
|
-
string (format: date-time) -> z.
|
141
|
-
string (format: uri) -> z.
|
142
|
-
integer -> z.
|
145
|
+
string (format: email) -> z.email()
|
146
|
+
string (format: date-time) -> z.iso.datetime()
|
147
|
+
string (format: uri) -> z.url()
|
148
|
+
integer -> z.int()
|
143
149
|
number -> z.number()
|
144
150
|
boolean -> z.boolean()
|
145
151
|
array -> z.array(...)
|
@@ -147,39 +153,49 @@ class SchemasGenerator:
|
|
147
153
|
schema_type = schema.type
|
148
154
|
schema_format = schema.format
|
149
155
|
|
156
|
+
# Binary type (File/Blob for file uploads)
|
157
|
+
# NOTE: Skip binary validation for PATCH models (they use JSON, not multipart)
|
158
|
+
# PATCH models typically don't allow file uploads
|
159
|
+
parent_is_patch = parent_schema and parent_schema.is_patch_model if parent_schema else False
|
160
|
+
if schema.is_binary and not parent_is_patch:
|
161
|
+
# For multipart/form-data file uploads, use z.instanceof()
|
162
|
+
# This works for both File and Blob in browser/React Native
|
163
|
+
return "z.union([z.instanceof(File), z.instanceof(Blob)])"
|
164
|
+
|
150
165
|
# String types with format validation
|
151
166
|
if schema_type == "string":
|
152
167
|
base_type = "z.string()"
|
153
168
|
|
154
|
-
# Add format validation
|
169
|
+
# Add format validation - use new Zod v4 format APIs
|
155
170
|
if schema_format == "email":
|
156
|
-
base_type = "z.
|
171
|
+
base_type = "z.email()"
|
157
172
|
elif schema_format in ("date-time", "datetime"):
|
158
|
-
base_type = "z.
|
173
|
+
base_type = "z.iso.datetime()"
|
159
174
|
elif schema_format == "date":
|
160
|
-
base_type = "z.
|
175
|
+
base_type = "z.iso.date()"
|
161
176
|
elif schema_format in ("uri", "url"):
|
162
|
-
base_type = "z.
|
177
|
+
base_type = "z.url()"
|
163
178
|
elif schema_format == "uuid":
|
164
|
-
base_type = "z.
|
179
|
+
base_type = "z.uuid()"
|
165
180
|
|
166
|
-
# Add length constraints
|
167
|
-
if
|
168
|
-
|
169
|
-
|
170
|
-
|
181
|
+
# Add length constraints (only for plain strings, not formatted ones)
|
182
|
+
if base_type == "z.string()":
|
183
|
+
if schema.min_length is not None:
|
184
|
+
base_type = f"{base_type}.min({schema.min_length})"
|
185
|
+
if schema.max_length is not None:
|
186
|
+
base_type = f"{base_type}.max({schema.max_length})"
|
171
187
|
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
188
|
+
# Add pattern validation
|
189
|
+
if schema.pattern:
|
190
|
+
# Escape forward slashes for JS regex literal
|
191
|
+
escaped_pattern = schema.pattern.replace('/', r'\/')
|
192
|
+
base_type = f"{base_type}.regex(/{escaped_pattern}/)"
|
177
193
|
|
178
194
|
return base_type
|
179
195
|
|
180
196
|
# Integer type
|
181
197
|
elif schema_type == "integer":
|
182
|
-
base_type = "z.
|
198
|
+
base_type = "z.int()"
|
183
199
|
|
184
200
|
# Add range constraints
|
185
201
|
if schema.minimum is not None:
|
@@ -246,7 +262,7 @@ class SchemasGenerator:
|
|
246
262
|
return "\n".join(lines)
|
247
263
|
|
248
264
|
def _generate_enum_schema(self, schema: IRSchemaObject) -> str:
|
249
|
-
"""Generate z.nativeEnum() schema."""
|
265
|
+
"""Generate z.nativeEnum() schema that references TypeScript enum."""
|
250
266
|
enum_name = self.base.sanitize_enum_name(schema.name)
|
251
267
|
|
252
268
|
lines = []
|
@@ -254,6 +270,8 @@ class SchemasGenerator:
|
|
254
270
|
if schema.description:
|
255
271
|
lines.append(f"/**\n * {schema.description}\n */")
|
256
272
|
|
273
|
+
# Use z.nativeEnum to reference TypeScript enum from enums.ts
|
274
|
+
# This ensures type compatibility with models.ts
|
257
275
|
lines.append(f"export const {enum_name}Schema = z.nativeEnum(Enums.{enum_name})")
|
258
276
|
|
259
277
|
return "\n".join(lines)
|
@@ -17,6 +17,7 @@
|
|
17
17
|
import useSWR from 'swr'
|
18
18
|
import { useSWRConfig } from 'swr'
|
19
19
|
import * as Fetchers from '../fetchers/{{ tag_file }}'
|
20
|
+
import type { API } from '../../index'
|
20
21
|
{% if has_schemas %}
|
21
22
|
{% for schema_name in schema_names %}
|
22
23
|
import type { {{ schema_name }} } from '../schemas/{{ schema_name }}.schema'
|
django_cfg/modules/django_client/core/generator/typescript/templates/hooks/mutation_hook.ts.jinja
CHANGED
@@ -7,11 +7,11 @@
|
|
7
7
|
export function {{ hook_name }}() {
|
8
8
|
const { mutate } = useSWRConfig()
|
9
9
|
|
10
|
-
return async ({% if func_params %}{{ func_params }}{% endif %}): Promise<{{ response_type }}> => {
|
10
|
+
return async ({% if func_params %}{{ func_params }}, client?: API{% else %}client?: API{% endif %}): Promise<{{ response_type }}> => {
|
11
11
|
{% if fetcher_params %}
|
12
|
-
const result = await Fetchers.{{ fetcher_name }}({{ fetcher_params }})
|
12
|
+
const result = await Fetchers.{{ fetcher_name }}({{ fetcher_params }}, client)
|
13
13
|
{% else %}
|
14
|
-
const result = await Fetchers.{{ fetcher_name }}()
|
14
|
+
const result = await Fetchers.{{ fetcher_name }}(client)
|
15
15
|
{% endif %}
|
16
16
|
{% if revalidation_keys %}
|
17
17
|
// Revalidate related queries
|
django_cfg/modules/django_client/core/generator/typescript/templates/hooks/query_hook.ts.jinja
CHANGED
@@ -6,16 +6,15 @@
|
|
6
6
|
*/
|
7
7
|
export function {{ hook_name }}(
|
8
8
|
{%- if func_params -%}
|
9
|
-
{{ func_params }}
|
10
|
-
{%- endif -%}
|
11
|
-
) {
|
12
|
-
return useSWR<{{ response_type }}>(
|
13
|
-
{{ swr_key }},
|
14
|
-
{%- if fetcher_params %}
|
15
|
-
() => Fetchers.{{ fetcher_name }}({{ fetcher_params }})
|
9
|
+
{{ func_params }}, client?: API
|
16
10
|
{%- else %}
|
17
|
-
|
11
|
+
client?: API
|
18
12
|
{%- endif %}
|
19
|
-
|
13
|
+
): ReturnType<typeof useSWR<{{ response_type }}>> {
|
14
|
+
return useSWR<{{ response_type }}>(
|
15
|
+
{{ swr_key }},
|
16
|
+
{% if fetcher_params %} () => Fetchers.{{ fetcher_name }}({{ fetcher_params }}, client)
|
17
|
+
{% else %} () => Fetchers.{{ fetcher_name }}(client)
|
18
|
+
{% endif %} )
|
20
19
|
}
|
21
20
|
|
django_cfg/pyproject.toml
CHANGED
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
4
4
|
|
5
5
|
[project]
|
6
6
|
name = "django-cfg"
|
7
|
-
version = "1.4.
|
7
|
+
version = "1.4.20"
|
8
8
|
description = "Django AI framework with built-in agents, type-safe Pydantic v2 configuration, and 8 enterprise apps. Replace settings.py, validate at startup, 90% less code. Production-ready AI workflows for Django."
|
9
9
|
readme = "README.md"
|
10
10
|
keywords = [ "django", "configuration", "pydantic", "settings", "type-safety", "pydantic-settings", "django-environ", "startup-validation", "ide-autocomplete", "ai-agents", "enterprise-django", "django-settings", "type-safe-config",]
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: django-cfg
|
3
|
-
Version: 1.4.
|
3
|
+
Version: 1.4.20
|
4
4
|
Summary: Django AI framework with built-in agents, type-safe Pydantic v2 configuration, and 8 enterprise apps. Replace settings.py, validate at startup, 90% less code. Production-ready AI workflows for Django.
|
5
5
|
Project-URL: Homepage, https://djangocfg.com
|
6
6
|
Project-URL: Documentation, https://djangocfg.com
|
@@ -3,7 +3,7 @@ django_cfg/__init__.py,sha256=4dZgnuTlq8YmLISTJAqnPrr080kxPfmPKUjhiWhkEDc,1630
|
|
3
3
|
django_cfg/apps.py,sha256=k84brkeXJI7EgKZLEpTkM9YFZofKI4PzhFOn1cl9Msc,1656
|
4
4
|
django_cfg/config.py,sha256=3hX5bOCbOWdUvtD9Z5qEHEOEyWzY1-4CsvFs_EO7VSw,1398
|
5
5
|
django_cfg/apps/__init__.py,sha256=JtDmEYt1OcleWM2ZaeX0LKDnRQzPOavfaXBWG4ECB5Q,26
|
6
|
-
django_cfg/apps/urls.py,sha256=
|
6
|
+
django_cfg/apps/urls.py,sha256=nQgaDWlr33h-fXawz6PA_KF5k_jfbfDVuinTPxCqcsw,4775
|
7
7
|
django_cfg/apps/accounts/README.md,sha256=YkUYJ3iKMYTmm9ALK2PDnX75SDqZxgnkzNLCD5efxRs,8227
|
8
8
|
django_cfg/apps/accounts/__init__.py,sha256=osecEQhMJVP8ejhZzElNsAqA1fX-GPD3K5_yNwDk6IE,100
|
9
9
|
django_cfg/apps/accounts/__models.py,sha256=65AomWYd78ptQ60drPbodxf0Ue310vmJQpQOPHL6V3E,10161
|
@@ -117,7 +117,9 @@ django_cfg/apps/api/health/views.py,sha256=D_HL7P4CrfV5tUqyto59MBCAKDoFG8x7PrQUb
|
|
117
117
|
django_cfg/apps/knowbase/README.md,sha256=HXt_J6WCN-LsMhA7p9mdvih07_vp_r_hkPdmqHhNEeo,3965
|
118
118
|
django_cfg/apps/knowbase/__init__.py,sha256=cfGnxDQwjajPhUoleKkgvdabJcB0LdXEglnsBojKkPo,1045
|
119
119
|
django_cfg/apps/knowbase/apps.py,sha256=FNvRmaUkZ64TierGSabWNb9IzzbDFMndscSldxUn1dU,3426
|
120
|
-
django_cfg/apps/knowbase/urls.py,sha256=
|
120
|
+
django_cfg/apps/knowbase/urls.py,sha256=lOMuEoNDIBE4Fhhr3aQ0RxWInNS1Ri4NYPgVLijsPuU,642
|
121
|
+
django_cfg/apps/knowbase/urls_admin.py,sha256=WN6Tm5lGlisrGGBK10PHCjPhztqQ2GotW6-WVUE5UHM,630
|
122
|
+
django_cfg/apps/knowbase/urls_system.py,sha256=c4zl7sMTJE0p-esoT2UC2V3qouVWJhi35z1Id1z4o4g,747
|
121
123
|
django_cfg/apps/knowbase/admin/__init__.py,sha256=NGYMzpLec7e8jYeQg3Gz5x-N-nMUePN6DHqzMHC4dAQ,499
|
122
124
|
django_cfg/apps/knowbase/admin/archive_admin.py,sha256=uQtK-6XRyiFR8H0polOwCKvufJE_pninjZL6sIlP-30,21239
|
123
125
|
django_cfg/apps/knowbase/admin/chat_admin.py,sha256=5iG5NEmTzQRlKjpy6wBjY8LLJkJNj1ZN9gT41dArtHY,16655
|
@@ -163,7 +165,7 @@ django_cfg/apps/knowbase/mixins/generators/content_generator.py,sha256=gBog40cfL
|
|
163
165
|
django_cfg/apps/knowbase/mixins/generators/field_analyzer.py,sha256=-r1ovN1LwAJLjuT8fVwf0BKtoHJDl7NsFBESzPyh35c,2759
|
164
166
|
django_cfg/apps/knowbase/mixins/generators/metadata_generator.py,sha256=gfF9SoWtKuCHfoVPtWsH9vAyYntJ4git2tMmIJg77OE,4476
|
165
167
|
django_cfg/apps/knowbase/models/__init__.py,sha256=MnMzbOZTB3dlo0IU1VsgQVY1uPOgU6FtQFiAUyaK6AU,742
|
166
|
-
django_cfg/apps/knowbase/models/archive.py,sha256=
|
168
|
+
django_cfg/apps/knowbase/models/archive.py,sha256=CiXfTRacHe9PuaF6_W78uKKWg2TBm468i80Y6tkBF_k,18600
|
167
169
|
django_cfg/apps/knowbase/models/base.py,sha256=ojkeEige-Z4W4HV96FSL3phjipVUwbUzKjRzWl_28vM,1478
|
168
170
|
django_cfg/apps/knowbase/models/chat.py,sha256=HBiYxwLpve5VTIJkhHuGWCK_OEZZKWzmMKSe1jHxSpU,4578
|
169
171
|
django_cfg/apps/knowbase/models/document.py,sha256=NVVQIaZHJFPgyAVQe8sJK-faUVWrymKagV6AIJUZA-0,8368
|
@@ -760,14 +762,14 @@ django_cfg/modules/django_client/core/generator/python/templates/utils/retry.py.
|
|
760
762
|
django_cfg/modules/django_client/core/generator/python/templates/utils/schema.py.jinja,sha256=xrnhAc-hNk6DigxHmTvhR3dyDFI9ocnkhL-_Hz9hCs8,270
|
761
763
|
django_cfg/modules/django_client/core/generator/typescript/__init__.py,sha256=eHOZp7M65WZ9u3tA_xQlON5-oijZZiGXDhz22Bq73s0,371
|
762
764
|
django_cfg/modules/django_client/core/generator/typescript/client_generator.py,sha256=7ql-m59YVt6zGKfVBCxy1OR3CNy6C9lkaMEUqexiRvo,5878
|
763
|
-
django_cfg/modules/django_client/core/generator/typescript/fetchers_generator.py,sha256=
|
765
|
+
django_cfg/modules/django_client/core/generator/typescript/fetchers_generator.py,sha256=2Gd-AIKx5m_0q5bVPr-PbQQjqAeRwL-dJgfbnIHAFHs,16445
|
764
766
|
django_cfg/modules/django_client/core/generator/typescript/files_generator.py,sha256=faRdhVVf9GQ-0esVz94dsaQMB56zK3csyNkhEHL4al4,7044
|
765
|
-
django_cfg/modules/django_client/core/generator/typescript/generator.py,sha256=
|
766
|
-
django_cfg/modules/django_client/core/generator/typescript/hooks_generator.py,sha256=
|
767
|
-
django_cfg/modules/django_client/core/generator/typescript/models_generator.py,sha256=
|
767
|
+
django_cfg/modules/django_client/core/generator/typescript/generator.py,sha256=oBM7CKlsD7arzIt0dSeow7Ujuo6RWl6h5to221Q19Gc,16984
|
768
|
+
django_cfg/modules/django_client/core/generator/typescript/hooks_generator.py,sha256=woTohitYEyo6R7s-XqO6o9KC5u-nbo2lAd1jAchvT-U,15694
|
769
|
+
django_cfg/modules/django_client/core/generator/typescript/models_generator.py,sha256=dvfBsXBds_SvGBXrmcIcODMgQMUYAMsHuqBo9Z5F80c,9131
|
768
770
|
django_cfg/modules/django_client/core/generator/typescript/naming.py,sha256=uUh2XVmorQ8gzfdzZJB8KNPng6UI4axe3lEaFtTqYks,2592
|
769
|
-
django_cfg/modules/django_client/core/generator/typescript/operations_generator.py,sha256=
|
770
|
-
django_cfg/modules/django_client/core/generator/typescript/schemas_generator.py,sha256=
|
771
|
+
django_cfg/modules/django_client/core/generator/typescript/operations_generator.py,sha256=Nwcx0m4Z0fnMEiwbsZJW9m4Ut6XBD-Hw4WPxXuPIEVg,16354
|
772
|
+
django_cfg/modules/django_client/core/generator/typescript/schemas_generator.py,sha256=DnattUopGrSazcLIIFbRC-BG2aD1DrZ_D0osp9Z8D1E,12041
|
771
773
|
django_cfg/modules/django_client/core/generator/typescript/templates/api_instance.ts.jinja,sha256=OPUjnz6Dk3kY97UFIRcgvxkEIKd6fUGqBzXJWOXKykE,2906
|
772
774
|
django_cfg/modules/django_client/core/generator/typescript/templates/app_index.ts.jinja,sha256=gLsoYyEzKD6Gv64vsO9sQHMPiFMGdaB5XVufLHeRyvQ,62
|
773
775
|
django_cfg/modules/django_client/core/generator/typescript/templates/client_file.ts.jinja,sha256=LHUt72fO2eRNAHYEscIYvqVR69GC6mxqjcgSlUzeCtc,251
|
@@ -784,10 +786,10 @@ django_cfg/modules/django_client/core/generator/typescript/templates/client/sub_
|
|
784
786
|
django_cfg/modules/django_client/core/generator/typescript/templates/fetchers/fetchers.ts.jinja,sha256=HNeYh8LnTTmeKTQS7uup37Oq-_HwBPZH8qE1kneaJsg,1296
|
785
787
|
django_cfg/modules/django_client/core/generator/typescript/templates/fetchers/function.ts.jinja,sha256=cR4Y4eJ1ENcON9BcfI-ttnJfKxv61efMW2oVDrmJga8,580
|
786
788
|
django_cfg/modules/django_client/core/generator/typescript/templates/fetchers/index.ts.jinja,sha256=DoAVm8EoglJKtLrE917Fk7Na6rn5Bt9L1nI39o9AwzM,747
|
787
|
-
django_cfg/modules/django_client/core/generator/typescript/templates/hooks/hooks.ts.jinja,sha256=
|
789
|
+
django_cfg/modules/django_client/core/generator/typescript/templates/hooks/hooks.ts.jinja,sha256=_iyvJBEQviLLtZ5z1qXNUM976zXPW-v9DXFyHJdrpCQ,802
|
788
790
|
django_cfg/modules/django_client/core/generator/typescript/templates/hooks/index.ts.jinja,sha256=c4Jru6DAKD-y8nzig1my0iE-BO3OwjSCENALbHvAp7E,694
|
789
|
-
django_cfg/modules/django_client/core/generator/typescript/templates/hooks/mutation_hook.ts.jinja,sha256=
|
790
|
-
django_cfg/modules/django_client/core/generator/typescript/templates/hooks/query_hook.ts.jinja,sha256=
|
791
|
+
django_cfg/modules/django_client/core/generator/typescript/templates/hooks/mutation_hook.ts.jinja,sha256=pOeyEY9nkYKVARTN6P4dfEj_mg-CIuPd8rrxzfaCfF8,697
|
792
|
+
django_cfg/modules/django_client/core/generator/typescript/templates/hooks/query_hook.ts.jinja,sha256=_Qit1DTZQTYIM_l6gmBkS2Fy7358EsGrUWr0iwCwyhw,526
|
791
793
|
django_cfg/modules/django_client/core/generator/typescript/templates/models/app_models.ts.jinja,sha256=hRJ06Z-L4M5IEB23dd_rVgwSzSEGmqaSsKVrg5NasY0,122
|
792
794
|
django_cfg/modules/django_client/core/generator/typescript/templates/models/enums.ts.jinja,sha256=8BguyHxV4r5JdJD9wYYgZrClysIdlkjf_Bp5toU81u8,49
|
793
795
|
django_cfg/modules/django_client/core/generator/typescript/templates/models/models.ts.jinja,sha256=mycvqd12K2LsnN4mnwMdQ_SepiIWx6e9gDlUMAGOoBA,121
|
@@ -1100,9 +1102,9 @@ django_cfg/utils/version_check.py,sha256=jI4v3YMdQriUEeb_TvRl511sDghy6I75iKRDUaN
|
|
1100
1102
|
django_cfg/CHANGELOG.md,sha256=jtT3EprqEJkqSUh7IraP73vQ8PmKUMdRtznQsEnqDZk,2052
|
1101
1103
|
django_cfg/CONTRIBUTING.md,sha256=DU2kyQ6PU0Z24ob7O_OqKWEYHcZmJDgzw-lQCmu6uBg,3041
|
1102
1104
|
django_cfg/LICENSE,sha256=xHuytiUkSZCRG3N11nk1X6q1_EGQtv6aL5O9cqNRhKE,1071
|
1103
|
-
django_cfg/pyproject.toml,sha256=
|
1104
|
-
django_cfg-1.4.
|
1105
|
-
django_cfg-1.4.
|
1106
|
-
django_cfg-1.4.
|
1107
|
-
django_cfg-1.4.
|
1108
|
-
django_cfg-1.4.
|
1105
|
+
django_cfg/pyproject.toml,sha256=nbORroIo8szkSqBsezUyoTy51R_ggBBDmb5C-iSIO3w,8210
|
1106
|
+
django_cfg-1.4.20.dist-info/METADATA,sha256=qxG77CBP_ISz9wRdUM9AzZe4bm7xHILFwZkwSO3xdRI,22533
|
1107
|
+
django_cfg-1.4.20.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
1108
|
+
django_cfg-1.4.20.dist-info/entry_points.txt,sha256=Ucmde4Z2wEzgb4AggxxZ0zaYDb9HpyE5blM3uJ0_VNg,56
|
1109
|
+
django_cfg-1.4.20.dist-info/licenses/LICENSE,sha256=xHuytiUkSZCRG3N11nk1X6q1_EGQtv6aL5O9cqNRhKE,1071
|
1110
|
+
django_cfg-1.4.20.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|