django-cfg 1.4.15__py3-none-any.whl → 1.4.19__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.
Files changed (29) hide show
  1. django_cfg/apps/leads/urls.py +2 -1
  2. django_cfg/apps/payments/urls.py +4 -4
  3. django_cfg/core/base/config_model.py +7 -7
  4. django_cfg/core/generation/core_generators/settings.py +2 -3
  5. django_cfg/core/generation/core_generators/static.py +9 -9
  6. django_cfg/core/generation/integration_generators/api.py +1 -1
  7. django_cfg/models/infrastructure/security.py +33 -2
  8. django_cfg/modules/django_client/core/generator/base.py +18 -20
  9. django_cfg/modules/django_client/core/generator/typescript/fetchers_generator.py +56 -113
  10. django_cfg/modules/django_client/core/generator/typescript/generator.py +1 -1
  11. django_cfg/modules/django_client/core/generator/typescript/hooks_generator.py +102 -232
  12. django_cfg/modules/django_client/core/generator/typescript/models_generator.py +9 -4
  13. django_cfg/modules/django_client/core/generator/typescript/naming.py +83 -0
  14. django_cfg/modules/django_client/core/generator/typescript/operations_generator.py +19 -7
  15. django_cfg/modules/django_client/core/generator/typescript/schemas_generator.py +40 -33
  16. django_cfg/modules/django_client/core/generator/typescript/templates/fetchers/function.ts.jinja +25 -0
  17. django_cfg/modules/django_client/core/generator/typescript/templates/hooks/hooks.ts.jinja +31 -0
  18. django_cfg/modules/django_client/core/generator/typescript/templates/hooks/index.ts.jinja +29 -0
  19. django_cfg/modules/django_client/core/generator/typescript/templates/hooks/mutation_hook.ts.jinja +25 -0
  20. django_cfg/modules/django_client/core/generator/typescript/templates/hooks/query_hook.ts.jinja +20 -0
  21. django_cfg/modules/django_client/core/groups/manager.py +51 -26
  22. django_cfg/modules/django_client/spectacular/__init__.py +3 -2
  23. django_cfg/modules/django_client/spectacular/schema.py +50 -0
  24. django_cfg/pyproject.toml +1 -1
  25. {django_cfg-1.4.15.dist-info → django_cfg-1.4.19.dist-info}/METADATA +1 -1
  26. {django_cfg-1.4.15.dist-info → django_cfg-1.4.19.dist-info}/RECORD +29 -22
  27. {django_cfg-1.4.15.dist-info → django_cfg-1.4.19.dist-info}/WHEEL +0 -0
  28. {django_cfg-1.4.15.dist-info → django_cfg-1.4.19.dist-info}/entry_points.txt +0 -0
  29. {django_cfg-1.4.15.dist-info → django_cfg-1.4.19.dist-info}/licenses/LICENSE +0 -0
@@ -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.nativeEnum)
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.nativeEnum()
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.string().email(),
49
+ email: z.email(),
50
50
  username: z.string().min(1).max(150),
51
51
  })
52
52
  """
@@ -92,20 +92,20 @@ class SchemasGenerator:
92
92
 
93
93
  Examples:
94
94
  id: z.number()
95
- email: z.string().email()
95
+ email: z.email()
96
96
  username: z.string().min(1).max(150)
97
- status: z.nativeEnum(Enums.StatusEnum)
98
- created_at: z.string().datetime()
97
+ status: z.nativeEnum(Enums.StatusEnum) # Reference to TypeScript enum
98
+ created_at: z.iso.datetime()
99
99
  """
100
100
  # Check if this field is an enum
101
101
  if schema.enum and schema.name:
102
- # Use enum validation
102
+ # Use nativeEnum to reference TypeScript enum from enums.ts
103
103
  zod_type = f"z.nativeEnum(Enums.{self.base.sanitize_enum_name(schema.name)})"
104
104
  # Check if this field is a reference to an enum
105
105
  elif schema.ref and schema.ref in self.context.schemas:
106
106
  ref_schema = self.context.schemas[schema.ref]
107
107
  if ref_schema.enum:
108
- # Reference to enum component
108
+ # Reference to enum component - use nativeEnum
109
109
  zod_type = f"z.nativeEnum(Enums.{self.base.sanitize_enum_name(schema.ref)})"
110
110
  else:
111
111
  # Reference to another schema
@@ -117,9 +117,13 @@ class SchemasGenerator:
117
117
  # Check if required
118
118
  is_required = name in required_fields
119
119
 
120
- # Handle optional fields - use .optional() for both non-required AND nullable
121
- # This converts Django's nullable=True to TypeScript's optional (undefined)
122
- if not is_required or schema.nullable:
120
+ # Handle nullable and optional separately
121
+ # - nullable: field can be null (use .nullable())
122
+ # - not required: field can be undefined (use .optional())
123
+ if schema.nullable:
124
+ zod_type = f"{zod_type}.nullable()"
125
+
126
+ if not is_required:
123
127
  zod_type = f"{zod_type}.optional()"
124
128
 
125
129
  return f"{name}: {zod_type}"
@@ -136,10 +140,10 @@ class SchemasGenerator:
136
140
 
137
141
  Examples:
138
142
  string -> z.string()
139
- string (format: email) -> z.string().email()
140
- string (format: date-time) -> z.string().datetime()
141
- string (format: uri) -> z.string().url()
142
- integer -> z.number().int()
143
+ string (format: email) -> z.email()
144
+ string (format: date-time) -> z.iso.datetime()
145
+ string (format: uri) -> z.url()
146
+ integer -> z.int()
143
147
  number -> z.number()
144
148
  boolean -> z.boolean()
145
149
  array -> z.array(...)
@@ -151,35 +155,36 @@ class SchemasGenerator:
151
155
  if schema_type == "string":
152
156
  base_type = "z.string()"
153
157
 
154
- # Add format validation
158
+ # Add format validation - use new Zod v4 format APIs
155
159
  if schema_format == "email":
156
- base_type = "z.string().email()"
160
+ base_type = "z.email()"
157
161
  elif schema_format in ("date-time", "datetime"):
158
- base_type = "z.string().datetime()"
162
+ base_type = "z.iso.datetime()"
159
163
  elif schema_format == "date":
160
- base_type = "z.string().date()"
164
+ base_type = "z.iso.date()"
161
165
  elif schema_format in ("uri", "url"):
162
- base_type = "z.string().url()"
166
+ base_type = "z.url()"
163
167
  elif schema_format == "uuid":
164
- base_type = "z.string().uuid()"
168
+ base_type = "z.uuid()"
165
169
 
166
- # Add length constraints
167
- if schema.min_length is not None:
168
- base_type = f"{base_type}.min({schema.min_length})"
169
- if schema.max_length is not None:
170
- base_type = f"{base_type}.max({schema.max_length})"
170
+ # Add length constraints (only for plain strings, not formatted ones)
171
+ if base_type == "z.string()":
172
+ if schema.min_length is not None:
173
+ base_type = f"{base_type}.min({schema.min_length})"
174
+ if schema.max_length is not None:
175
+ base_type = f"{base_type}.max({schema.max_length})"
171
176
 
172
- # Add pattern validation
173
- if schema.pattern:
174
- # Escape regex pattern for JS
175
- escaped_pattern = schema.pattern.replace('\\', '\\\\')
176
- base_type = f"{base_type}.regex(/{escaped_pattern}/)"
177
+ # Add pattern validation
178
+ if schema.pattern:
179
+ # Escape regex pattern for JS
180
+ escaped_pattern = schema.pattern.replace('\\', '\\\\')
181
+ base_type = f"{base_type}.regex(/{escaped_pattern}/)"
177
182
 
178
183
  return base_type
179
184
 
180
185
  # Integer type
181
186
  elif schema_type == "integer":
182
- base_type = "z.number().int()"
187
+ base_type = "z.int()"
183
188
 
184
189
  # Add range constraints
185
190
  if schema.minimum is not None:
@@ -246,7 +251,7 @@ class SchemasGenerator:
246
251
  return "\n".join(lines)
247
252
 
248
253
  def _generate_enum_schema(self, schema: IRSchemaObject) -> str:
249
- """Generate z.nativeEnum() schema."""
254
+ """Generate z.nativeEnum() schema that references TypeScript enum."""
250
255
  enum_name = self.base.sanitize_enum_name(schema.name)
251
256
 
252
257
  lines = []
@@ -254,6 +259,8 @@ class SchemasGenerator:
254
259
  if schema.description:
255
260
  lines.append(f"/**\n * {schema.description}\n */")
256
261
 
262
+ # Use z.nativeEnum to reference TypeScript enum from enums.ts
263
+ # This ensures type compatibility with models.ts
257
264
  lines.append(f"export const {enum_name}Schema = z.nativeEnum(Enums.{enum_name})")
258
265
 
259
266
  return "\n".join(lines)
@@ -0,0 +1,25 @@
1
+ /**
2
+ * {{ operation.summary or 'API operation' }}
3
+ *
4
+ * @method {{ operation.http_method }}
5
+ * @path {{ operation.path }}
6
+ */
7
+ export async function {{ func_name }}(
8
+ {%- if func_params %}
9
+ {{ func_params }},
10
+ {%- endif %}
11
+ client?: API
12
+ ): Promise<{{ response_type }}> {
13
+ const api = client || getAPIInstance()
14
+ {% if api_call_params %}
15
+ const response = await {{ api_call }}({{ api_call_params }})
16
+ {% else %}
17
+ const response = await {{ api_call }}()
18
+ {% endif %}
19
+ {% if response_schema %}
20
+ return {{ response_schema }}.parse(response)
21
+ {% else %}
22
+ return response
23
+ {% endif %}
24
+ }
25
+
@@ -0,0 +1,31 @@
1
+ /**
2
+ * SWR Hooks for {{ tag_display_name }}
3
+ *
4
+ * React hooks powered by SWR for data fetching with automatic caching,
5
+ * revalidation, and optimistic updates.
6
+ *
7
+ * Usage:
8
+ * ```typescript
9
+ * // Query hooks (GET)
10
+ * const { data, error, isLoading } = useUsers({ page: 1 })
11
+ *
12
+ * // Mutation hooks (POST/PUT/PATCH/DELETE)
13
+ * const createUser = useCreateUser()
14
+ * await createUser({ name: 'John', email: 'john@example.com' })
15
+ * ```
16
+ */
17
+ import useSWR from 'swr'
18
+ import { useSWRConfig } from 'swr'
19
+ import * as Fetchers from '../fetchers/{{ tag_file }}'
20
+ import type { API } from '../../index'
21
+ {% if has_schemas %}
22
+ {% for schema_name in schema_names %}
23
+ import type { {{ schema_name }} } from '../schemas/{{ schema_name }}.schema'
24
+ {% endfor %}
25
+ {% endif %}
26
+
27
+ {% for hook in hooks %}
28
+ {{ hook }}
29
+
30
+ {% endfor %}
31
+
@@ -0,0 +1,29 @@
1
+ /**
2
+ * SWR Hooks - React data fetching hooks
3
+ *
4
+ * Auto-generated from OpenAPI specification.
5
+ * Powered by SWR for automatic caching and revalidation.
6
+ *
7
+ * Features:
8
+ * - Automatic caching and deduplication
9
+ * - Revalidation on focus/reconnect
10
+ * - Optimistic updates
11
+ * - Type-safe parameters and responses
12
+ *
13
+ * Usage:
14
+ * ```typescript
15
+ * import * as hooks from './hooks'
16
+ *
17
+ * // Query hooks (GET)
18
+ * const { data, error, isLoading } = hooks.useUsers({ page: 1 })
19
+ *
20
+ * // Mutation hooks (POST/PUT/PATCH/DELETE)
21
+ * const createUser = hooks.useCreateUser()
22
+ * await createUser({ name: 'John' })
23
+ * ```
24
+ */
25
+
26
+ {% for module_name in modules %}
27
+ export * from './{{ module_name }}'
28
+ {% endfor %}
29
+
@@ -0,0 +1,25 @@
1
+ /**
2
+ * {{ operation.summary or 'API operation' }}
3
+ *
4
+ * @method {{ operation.http_method }}
5
+ * @path {{ operation.path }}
6
+ */
7
+ export function {{ hook_name }}() {
8
+ const { mutate } = useSWRConfig()
9
+
10
+ return async ({% if func_params %}{{ func_params }}, client?: API{% else %}client?: API{% endif %}): Promise<{{ response_type }}> => {
11
+ {% if fetcher_params %}
12
+ const result = await Fetchers.{{ fetcher_name }}({{ fetcher_params }}, client)
13
+ {% else %}
14
+ const result = await Fetchers.{{ fetcher_name }}(client)
15
+ {% endif %}
16
+ {% if revalidation_keys %}
17
+ // Revalidate related queries
18
+ {% for key in revalidation_keys %}
19
+ mutate('{{ key }}')
20
+ {% endfor %}
21
+ {% endif %}
22
+ return result
23
+ }
24
+ }
25
+
@@ -0,0 +1,20 @@
1
+ /**
2
+ * {{ operation.summary or 'API operation' }}
3
+ *
4
+ * @method {{ operation.http_method }}
5
+ * @path {{ operation.path }}
6
+ */
7
+ export function {{ hook_name }}(
8
+ {%- if func_params -%}
9
+ {{ func_params }}, client?: API
10
+ {%- else %}
11
+ client?: API
12
+ {%- endif %}
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 %} )
19
+ }
20
+
@@ -203,32 +203,57 @@ class GroupManager:
203
203
  if not apps:
204
204
  raise ValueError(f"Group '{group_name}' has no apps")
205
205
 
206
- # Generate URL patterns
207
- urlpatterns = []
208
- from django.apps import apps as django_apps
209
-
210
- for app_name in apps:
211
- # Try to include app URLs
212
- try:
213
- # Find app config by full name
214
- app_config = None
215
- for config in django_apps.get_app_configs():
216
- if config.name == app_name:
217
- app_config = config
218
- break
219
-
220
- if app_config:
221
- # Use actual label from AppConfig
222
- app_label = app_config.label
223
- urlpatterns.append(f' path("{app_label}/", include("{app_name}.urls")),')
224
- else:
225
- logger.debug(f"App '{app_name}' not found in installed apps")
226
- except Exception as e:
227
- logger.debug(f"App '{app_name}' skipped: {e}")
228
- continue
229
-
230
- # Create module code
231
- module_code = f'''"""
206
+ # Check if this is django-cfg built-in apps group
207
+ is_django_cfg_group = all(
208
+ app_name.startswith("django_cfg.apps.")
209
+ for app_name in apps
210
+ )
211
+
212
+ if is_django_cfg_group:
213
+ # For django-cfg apps, use django_cfg.apps.urls which has all the correct URL structure
214
+ # with proper cfg/ prefixes and conditional app registration
215
+ module_code = f'''"""
216
+ Dynamic URL configuration for group: {group_name}
217
+
218
+ Uses django_cfg.apps.urls which includes all enabled cfg apps with correct prefixes.
219
+ Auto-generated by django-client GroupManager.
220
+ """
221
+
222
+ from django_cfg.apps.urls import urlpatterns
223
+ '''
224
+ else:
225
+ # For custom apps, generate URL patterns by including each app's URLs
226
+ urlpatterns = []
227
+ from django.apps import apps as django_apps
228
+
229
+ for app_name in apps:
230
+ # Try to include app URLs
231
+ try:
232
+ # Find app config by full name
233
+ app_config = None
234
+ for config in django_apps.get_app_configs():
235
+ if config.name == app_name:
236
+ app_config = config
237
+ break
238
+
239
+ if app_config:
240
+ # Use actual label from AppConfig
241
+ app_label = app_config.label
242
+ # Add API prefix from config (e.g., "api/workspaces/" instead of just "workspaces/")
243
+ api_prefix = getattr(self.config, 'api_prefix', '').strip('/')
244
+ if api_prefix:
245
+ url_path = f"{api_prefix}/{app_label}/"
246
+ else:
247
+ url_path = f"{app_label}/"
248
+ urlpatterns.append(f' path("{url_path}", include("{app_name}.urls")),')
249
+ else:
250
+ logger.debug(f"App '{app_name}' not found in installed apps")
251
+ except Exception as e:
252
+ logger.debug(f"App '{app_name}' skipped: {e}")
253
+ continue
254
+
255
+ # Create module code
256
+ module_code = f'''"""
232
257
  Dynamic URL configuration for group: {group_name}
233
258
 
234
259
  Auto-generated by django-client GroupManager.
@@ -1,10 +1,11 @@
1
1
  """
2
- DRF Spectacular postprocessing hooks for django-cfg.
2
+ DRF Spectacular hooks and schema classes for django-cfg.
3
3
 
4
4
  Auto-fixes and enhancements for OpenAPI schema generation.
5
5
  """
6
6
 
7
7
  from .enum_naming import auto_fix_enum_names
8
8
  from .async_detection import mark_async_operations
9
+ from .schema import PathBasedAutoSchema
9
10
 
10
- __all__ = ['auto_fix_enum_names', 'mark_async_operations']
11
+ __all__ = ['auto_fix_enum_names', 'mark_async_operations', 'PathBasedAutoSchema']
@@ -0,0 +1,50 @@
1
+ """
2
+ Custom AutoSchema for drf-spectacular with intelligent tagging.
3
+
4
+ Automatically determines tags based on URL paths for better API organization.
5
+ """
6
+
7
+ import re
8
+ from drf_spectacular.openapi import AutoSchema
9
+
10
+
11
+ class PathBasedAutoSchema(AutoSchema):
12
+ """
13
+ AutoSchema that determines tags from URL paths instead of view names.
14
+
15
+ For cfg group URLs like /cfg/accounts/..., /cfg/support/...,
16
+ extracts the app name from the second path segment to create precise tags.
17
+
18
+ This provides better organization in generated API clients:
19
+ - /cfg/accounts/otp/request/ → tag: "cfg__accounts"
20
+ - /cfg/support/tickets/ → tag: "cfg__support"
21
+ - /cfg/payments/webhooks/ → tag: "cfg__payments"
22
+
23
+ The TypeScript generator will use these tags to create properly structured folders.
24
+ """
25
+
26
+ def get_tags(self):
27
+ """
28
+ Override tag determination to use path-based logic.
29
+
30
+ Returns:
31
+ List of tags for this operation
32
+ """
33
+ import re
34
+
35
+ # Get the path
36
+ path = self.path
37
+
38
+ # For cfg URLs (/cfg/app_name/...), extract app_name as tag
39
+ # The TypeScript generator will add the group prefix (cfg_) automatically
40
+ cfg_pattern = re.compile(r"^/cfg/([^/]+)/")
41
+ match = cfg_pattern.match(path)
42
+ if match:
43
+ app_name = match.group(1)
44
+ # Return just the app_name (e.g., "support", "accounts", "payments")
45
+ # Generator will create: cfg__support, cfg__accounts, etc.
46
+ return [app_name]
47
+
48
+ # For other URLs, use default behavior (usually based on view name)
49
+ return super().get_tags()
50
+
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.15"
7
+ version = "1.4.19"
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.15
3
+ Version: 1.4.19
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
@@ -235,7 +235,7 @@ django_cfg/apps/leads/models.py,sha256=Eco7HrQIl8jK4N8I6yYgNckb4nM9Vkp0kHpx7vEW9
235
235
  django_cfg/apps/leads/serializers.py,sha256=dg-FmFmaKrOBQetJDs9Inoya6WqY5DZhvE6pVS14ONg,1569
236
236
  django_cfg/apps/leads/signals.py,sha256=exZm9xhHs53a16jI6xTWsz0hDS7WYQppWKL-Qx24VZc,2501
237
237
  django_cfg/apps/leads/tests.py,sha256=DoWQH2l2QKriCl2ihOEpaBj0OkBXi-_bRZFLkE5vTq4,10690
238
- django_cfg/apps/leads/urls.py,sha256=KFCdB9x0LySJODeUElQ2c-dxcl_z79xzYNC_9i6vFPk,355
238
+ django_cfg/apps/leads/urls.py,sha256=ppTYR8DhcdQHQQdlteIVmU8A9ymvrWrhlPYLFRe8RZc,411
239
239
  django_cfg/apps/leads/views.py,sha256=3tnnxAwEnD_ycIhZeIvTqzOyNaMTA00gxnbywtnPe8A,3212
240
240
  django_cfg/apps/leads/admin/__init__.py,sha256=JoASy7SUAng8Ffay9YqUTA6RX_QviLQ6AzwubwZeRms,197
241
241
  django_cfg/apps/leads/admin/leads_admin.py,sha256=uwZrcOk_VZIaO-ghZ_ITSJ8F-IFOGx_rdEt_0ujSPaY,9816
@@ -303,7 +303,7 @@ django_cfg/apps/newsletter/views/subscriptions.py,sha256=1O_EZ5NSKqkfGXB9jfA9hWm
303
303
  django_cfg/apps/newsletter/views/tracking.py,sha256=EJlAltpASzc_0nslVPJt-6mnIqI_QCEmz3MQEGPKzmU,2481
304
304
  django_cfg/apps/payments/README.md,sha256=FlyMSGyFnHkUudn99RvQwT0Y77Y-WJgd025wdi5ZB1Y,8290
305
305
  django_cfg/apps/payments/apps.py,sha256=fPJ6ImgxcjI6Wdi7c5oL3vpbliVdX2tfYTNkirp0Tag,1737
306
- django_cfg/apps/payments/urls.py,sha256=sTfs6fMsYJtLPmNK_PKGKnUx17PIwRo4r23k_BwfDSQ,3987
306
+ django_cfg/apps/payments/urls.py,sha256=soDbm0vJDbuy5RZALSkvqn85qbgeehyezyBjXy1ZMrM,3983
307
307
  django_cfg/apps/payments/urls_admin.py,sha256=WDZL9D7dumSZ7v83UMLWBdFFZmnMydtMKCi14FrB6IM,2657
308
308
  django_cfg/apps/payments/admin/__init__.py,sha256=cwEXQddoeDWzJqZpjj-XnSrjRnrKpp5l21_-fwuPTPM,902
309
309
  django_cfg/apps/payments/admin/api_keys_admin.py,sha256=Jco52LU0deuhjbwMUf5bgnXPcyfCOk2LUhtkHxF17-4,8234
@@ -552,7 +552,7 @@ django_cfg/core/constants.py,sha256=vtzNJ6XAxOZ-gjRU4G6Yk7y-F1H91iIFvsBXYK9p5gs,
552
552
  django_cfg/core/exceptions.py,sha256=07BficpWNzyLxoBxtIjjiNafpPQpFPyPxTBUNOiMoqw,2215
553
553
  django_cfg/core/validation.py,sha256=QeM1k6jjlFp4Sc9FAfK3SS_3jyP6orXRqA7XBt24Q6w,6574
554
554
  django_cfg/core/base/__init__.py,sha256=Z3bZvxejxk4vvWqmqTBLUi9XJpo6A_5Bq4R0J8q81Y4,116
555
- django_cfg/core/base/config_model.py,sha256=KLDOnnPoqf7zcH3mH2vr7-Q1AV2xajOfimu38yx0gwQ,20980
555
+ django_cfg/core/base/config_model.py,sha256=fQqB7zJa5syjFH_VX8DTJmTEYvnuPmvs6jZO8I8gsDM,21079
556
556
  django_cfg/core/builders/__init__.py,sha256=jkInI7_jbxcjitapohw6QmbJPpacnnID6V1JovqtOFM,282
557
557
  django_cfg/core/builders/apps_builder.py,sha256=n56rWLqIi3xQMK65dM1k8bMfla_2O_rovB_XzOJeTYQ,8339
558
558
  django_cfg/core/builders/middleware_builder.py,sha256=onbNJcnJ6HfhW6v3Lz-d1dhME66vUiCCEbRimRB15Ig,3704
@@ -564,14 +564,14 @@ django_cfg/core/generation/generation.py,sha256=0mez_7yM_64SBe31rY728GrdkiTSkSqN
564
564
  django_cfg/core/generation/orchestrator.py,sha256=ZSFe0LLle-Oqb7h5exbn9F-k2ktSgv8HTvom2ay1NEo,10862
565
565
  django_cfg/core/generation/protocols.py,sha256=D0-lc9LSAm344dfBAhsV3k__bkWRKeUV78mccgH_Su4,676
566
566
  django_cfg/core/generation/core_generators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
567
- django_cfg/core/generation/core_generators/settings.py,sha256=3R0a0Isq5C5DHu1V65dynaIW_7cBQBZ_U_m9jdlczhY,2620
568
- django_cfg/core/generation/core_generators/static.py,sha256=zywzJyKJx9oFcDjqpHVe-kjrOqO1DX1uEh_CAMnO6m0,2298
567
+ django_cfg/core/generation/core_generators/settings.py,sha256=YE_9sHnkfqkLnIOghDBIqOPtOL7_Xf5ENrEQtp8Oegk,2632
568
+ django_cfg/core/generation/core_generators/static.py,sha256=Kr1c9dm1o_iE2aA3Ydj64sAzSoqEV2Hld681lqWzpSA,2279
569
569
  django_cfg/core/generation/core_generators/templates.py,sha256=wSgUEG1R4RA-JB_wT_fPyyFMOSW1g6lyvPLwy2_KhJw,4198
570
570
  django_cfg/core/generation/data_generators/__init__.py,sha256=t8YepmMhMysy95tRYGAyoorGhJTEH5NojbegteYVtFY,298
571
571
  django_cfg/core/generation/data_generators/cache.py,sha256=IEwyVBJ-QJgOm5C13z-974YzV73aZO9MCresGweE7PM,3840
572
572
  django_cfg/core/generation/data_generators/database.py,sha256=ixJOB5e-e3N06F2QNQ1NJV0KLy26RxyvoKaRI1x5FIE,3481
573
573
  django_cfg/core/generation/integration_generators/__init__.py,sha256=tBuO25IHxx5KFHlJumh4L-jA1hXi9smIECPCR2jcgy8,599
574
- django_cfg/core/generation/integration_generators/api.py,sha256=RmHvu9vfe5FFc7Qhf7BiF6chMlNhQg5pibCYZsHAp98,10017
574
+ django_cfg/core/generation/integration_generators/api.py,sha256=S1WbDqs5XvTcWgaP0an_1ExGuKD8I7-8BH3Nzjr56S4,10054
575
575
  django_cfg/core/generation/integration_generators/sessions.py,sha256=W2KJetdF-lgfo54fouLCM6a_iTWGpXZrj1xI2CrtZ7g,1644
576
576
  django_cfg/core/generation/integration_generators/tailwind.py,sha256=nEcaBu-uNJ_O2Y2lHCAc1pG7m8LthnrFFHPxDJqSh3k,1208
577
577
  django_cfg/core/generation/integration_generators/tasks.py,sha256=Wlh9f1dpn_05k7dZxGEm2TegGK-TuP4zVwbCMg5ocM4,2514
@@ -653,7 +653,7 @@ django_cfg/models/django/revolution_legacy.py,sha256=NONFa3U-w2HSMKumEh0BOD5HVI3
653
653
  django_cfg/models/infrastructure/__init__.py,sha256=If0XLyDNaR_F6rOhDJBCT5RmkOOoNcY61L70pQvaO1s,369
654
654
  django_cfg/models/infrastructure/cache.py,sha256=N6LWinyokWcmuJmInn0q48TQq0Je-xXMJdZ0DbelGPU,12175
655
655
  django_cfg/models/infrastructure/logging.py,sha256=6nQNQPUKEL7TAYX1KcYgsqHBKnHWoUnqhR54bxcr40s,10637
656
- django_cfg/models/infrastructure/security.py,sha256=H-7QkYz19qAPKWq9YRXiCelTN-YbNSUgQvaV9U8MD3E,5158
656
+ django_cfg/models/infrastructure/security.py,sha256=ZXQmsF9hgwkzVQ9d6WinEoe4axF-i6P7pBLF2dIPgd8,6345
657
657
  django_cfg/models/infrastructure/database/__init__.py,sha256=3BXDKeJwvjyFws4MAjox_PIp_g0N1YuXv6qNjRb7wqQ,500
658
658
  django_cfg/models/infrastructure/database/config.py,sha256=YQLajtbc1umJvhZ1n3-ielw3qGG5poMXJk4BMhIlAJw,7856
659
659
  django_cfg/models/infrastructure/database/converters.py,sha256=mk2iYWA3ZsqhhaSbonbcautXlUwvOKMZ0OVfEZiXNGs,3083
@@ -727,7 +727,7 @@ django_cfg/modules/django_client/core/config/config.py,sha256=P1x4PuTp9ZndlQ_lmC
727
727
  django_cfg/modules/django_client/core/config/group.py,sha256=jmFJLzzhozIBApENHJ_rzrZWd-abd2zXQhf54SLZZAc,2645
728
728
  django_cfg/modules/django_client/core/config/service.py,sha256=cWBlLfDiR_FTX5buUHvrn4j5tSPMs3A3jTq02sn3B-Q,6285
729
729
  django_cfg/modules/django_client/core/generator/__init__.py,sha256=r9oMGKjLKT3e7qOquzcN3k3K7jUMwDwiP4xp1xa_Cso,3204
730
- django_cfg/modules/django_client/core/generator/base.py,sha256=M2XZe-Nw8oSJ-tEChuIK5UEfmpNRp9arVPMm1D2q9yw,31549
730
+ django_cfg/modules/django_client/core/generator/base.py,sha256=xvZtlsIGBFDVB52Ubb7l4qw1RrhWR33JDVbkfEw5zOo,31787
731
731
  django_cfg/modules/django_client/core/generator/python/__init__.py,sha256=DOPkZBmNVX8qKZBulnE-49iMlBsMHszidzBhWG17c2E,448
732
732
  django_cfg/modules/django_client/core/generator/python/async_client_gen.py,sha256=cxskiVQPtG2fMhH2TTxZ6-UUIxp_Hb7rvo13CnYGtoc,6030
733
733
  django_cfg/modules/django_client/core/generator/python/files_generator.py,sha256=cWczErtcwAFw16JycRC0eRzdmCRtjQUNX4tJx3RlRpk,6420
@@ -760,13 +760,14 @@ django_cfg/modules/django_client/core/generator/python/templates/utils/retry.py.
760
760
  django_cfg/modules/django_client/core/generator/python/templates/utils/schema.py.jinja,sha256=xrnhAc-hNk6DigxHmTvhR3dyDFI9ocnkhL-_Hz9hCs8,270
761
761
  django_cfg/modules/django_client/core/generator/typescript/__init__.py,sha256=eHOZp7M65WZ9u3tA_xQlON5-oijZZiGXDhz22Bq73s0,371
762
762
  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=FxoAIVq8x1o2WxbU0zGzExP6geC4vH7ofF3w53OXC08,15649
763
+ django_cfg/modules/django_client/core/generator/typescript/fetchers_generator.py,sha256=ZiSXMyT7HV28IK0AE8p2Sma2xwFrWnzSurBZEaWw_Z8,13791
764
764
  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=_xuQC10SJ1ZKwA2_h3te4ZkSmH2jlnjUr__EJuBwNVE,16982
766
- django_cfg/modules/django_client/core/generator/typescript/hooks_generator.py,sha256=DVGb6z_HrNbtMC6QqsyKOjZmAUGBFSEqSo-AijPLw7A,19994
767
- django_cfg/modules/django_client/core/generator/typescript/models_generator.py,sha256=2cBA-YzeBkGekoKz0pzT-Rt56MCvRTT-lSb44AAujfk,8787
768
- django_cfg/modules/django_client/core/generator/typescript/operations_generator.py,sha256=CIcRLrCBqpxOrYcjFtk0mkZGJgUnQlaRDK6G0xADoUA,13171
769
- django_cfg/modules/django_client/core/generator/typescript/schemas_generator.py,sha256=tmFZ8yFJ_Nk_iT7QGDDUVSFJhg8WTF79lYDOqQDzz8c,10877
765
+ django_cfg/modules/django_client/core/generator/typescript/generator.py,sha256=oBM7CKlsD7arzIt0dSeow7Ujuo6RWl6h5to221Q19Gc,16984
766
+ django_cfg/modules/django_client/core/generator/typescript/hooks_generator.py,sha256=urnmej5isaPwnyo-kH_VVGP9kehcdeI2hR9mqHmVN4s,15133
767
+ django_cfg/modules/django_client/core/generator/typescript/models_generator.py,sha256=i7I1PJPx4r6KLaLJDJUJ_euDnKWnRQSiNFosUkP1eoM,8870
768
+ 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=6S2xs04UTIC6dOAa9h2Yjhsp4CnPjmYRvRTAof9BHQY,13947
770
+ django_cfg/modules/django_client/core/generator/typescript/schemas_generator.py,sha256=jM_3wzpQL3IgFGtDw4zWpCPYfiMfc1X1Yf6wEumamU4,11233
770
771
  django_cfg/modules/django_client/core/generator/typescript/templates/api_instance.ts.jinja,sha256=OPUjnz6Dk3kY97UFIRcgvxkEIKd6fUGqBzXJWOXKykE,2906
771
772
  django_cfg/modules/django_client/core/generator/typescript/templates/app_index.ts.jinja,sha256=gLsoYyEzKD6Gv64vsO9sQHMPiFMGdaB5XVufLHeRyvQ,62
772
773
  django_cfg/modules/django_client/core/generator/typescript/templates/client_file.ts.jinja,sha256=LHUt72fO2eRNAHYEscIYvqVR69GC6mxqjcgSlUzeCtc,251
@@ -781,7 +782,12 @@ django_cfg/modules/django_client/core/generator/typescript/templates/client/main
781
782
  django_cfg/modules/django_client/core/generator/typescript/templates/client/operation.ts.jinja,sha256=z6GD-r7Y-S_yhDtlOAjMgDSL10AF3YrBLLNLPiCt8rE,1869
782
783
  django_cfg/modules/django_client/core/generator/typescript/templates/client/sub_client.ts.jinja,sha256=1rtFMqJO8ynjNNblhMPwCbVFhbSbLJJwiMhuJJYf9Lw,215
783
784
  django_cfg/modules/django_client/core/generator/typescript/templates/fetchers/fetchers.ts.jinja,sha256=HNeYh8LnTTmeKTQS7uup37Oq-_HwBPZH8qE1kneaJsg,1296
785
+ django_cfg/modules/django_client/core/generator/typescript/templates/fetchers/function.ts.jinja,sha256=cR4Y4eJ1ENcON9BcfI-ttnJfKxv61efMW2oVDrmJga8,580
784
786
  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=_iyvJBEQviLLtZ5z1qXNUM976zXPW-v9DXFyHJdrpCQ,802
788
+ 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=pOeyEY9nkYKVARTN6P4dfEj_mg-CIuPd8rrxzfaCfF8,697
790
+ django_cfg/modules/django_client/core/generator/typescript/templates/hooks/query_hook.ts.jinja,sha256=_Qit1DTZQTYIM_l6gmBkS2Fy7358EsGrUWr0iwCwyhw,526
785
791
  django_cfg/modules/django_client/core/generator/typescript/templates/models/app_models.ts.jinja,sha256=hRJ06Z-L4M5IEB23dd_rVgwSzSEGmqaSsKVrg5NasY0,122
786
792
  django_cfg/modules/django_client/core/generator/typescript/templates/models/enums.ts.jinja,sha256=8BguyHxV4r5JdJD9wYYgZrClysIdlkjf_Bp5toU81u8,49
787
793
  django_cfg/modules/django_client/core/generator/typescript/templates/models/models.ts.jinja,sha256=mycvqd12K2LsnN4mnwMdQ_SepiIWx6e9gDlUMAGOoBA,121
@@ -795,7 +801,7 @@ django_cfg/modules/django_client/core/generator/typescript/templates/utils/schem
795
801
  django_cfg/modules/django_client/core/generator/typescript/templates/utils/storage.ts.jinja,sha256=Sbszp1L7b1pN9EScq7c2WmltdC7yXrbqU55v4FmRdT0,4899
796
802
  django_cfg/modules/django_client/core/groups/__init__.py,sha256=6Bw7XECMxamnTDgcNDS9HI8aQCD63_Frhj8ZtejHi4I,226
797
803
  django_cfg/modules/django_client/core/groups/detector.py,sha256=c6FHjveSbMgEbTEL0AnpU5NTWtWqAxXnSH48ebbVR7Y,5562
798
- django_cfg/modules/django_client/core/groups/manager.py,sha256=1GL6OTOQuClYZa7_3M7iH_ukhG6z9xxpksbtQjRc-tM,9697
804
+ django_cfg/modules/django_client/core/groups/manager.py,sha256=RhGl6PjSmxMPw5DXA5x6ww8Yak0iyi5PnCRyegHGVsg,10900
799
805
  django_cfg/modules/django_client/core/ir/__init__.py,sha256=58JBUka_gxjScbyTqGKrjOhIPbPQVqdyMMqs13vrSx0,2009
800
806
  django_cfg/modules/django_client/core/ir/context.py,sha256=gtr4toE2Qkl0QaPuoajjG5qD5A7drkax6i1GEDIrk7I,13386
801
807
  django_cfg/modules/django_client/core/ir/operation.py,sha256=gwvTciqIAUS0Hb7TqVU1Zr_StU9ulG3Vf73V7jYTp_U,17182
@@ -822,9 +828,10 @@ django_cfg/modules/django_client/management/__init__.py,sha256=mCTPP_bIOmqNnn0WA
822
828
  django_cfg/modules/django_client/management/commands/__init__.py,sha256=CJ55pHUNYQ5h-QHUe3axeTtxzlUJv7wbEuZmGN21iCM,36
823
829
  django_cfg/modules/django_client/management/commands/generate_client.py,sha256=iZvaJ371EikaIs__UB6XjyFuKmE_yWrIyYzaFZiPhME,16749
824
830
  django_cfg/modules/django_client/management/commands/validate_openapi.py,sha256=EtPhZPIistvxVjoyI4hto9L8bOEAtZS21qSIojJ1uSg,11153
825
- django_cfg/modules/django_client/spectacular/__init__.py,sha256=bZNK3hu-ww8BxISPirsTbklaKBNPsf-Jonw3-uIPDhY,278
831
+ django_cfg/modules/django_client/spectacular/__init__.py,sha256=7zrDMU-dQYYXmFiprou6zHRSAFAklkd7lzWla8YuAMo,345
826
832
  django_cfg/modules/django_client/spectacular/async_detection.py,sha256=6mFNl8EdIZd4evt2aFhCb3NXphYK3uf1AtzW3vAs7lE,5730
827
833
  django_cfg/modules/django_client/spectacular/enum_naming.py,sha256=GSTY8DCxtm75v-IBWs07jxM6mAmgSrq_9Nuz6ai2j3k,6496
834
+ django_cfg/modules/django_client/spectacular/schema.py,sha256=pYa4TaxcZGZeO0QL4NtrTm38YX3IFnHl1rKoy2-uK9E,1684
828
835
  django_cfg/modules/django_currency/README.md,sha256=4R7KtF-rhR6yRg5jbsXwOVXMZNGEpOyW4N3WGN89W7A,4670
829
836
  django_cfg/modules/django_currency/__init__.py,sha256=vAqVGR7_yL66jMsJSUTOOrRfXJVNIXHdAR6bJ1v3skw,2511
830
837
  django_cfg/modules/django_currency/clients/__init__.py,sha256=K5MehiFH9a1DLlVABvWOl57qfI45Np9b1ojFNBR0qS8,236
@@ -1093,9 +1100,9 @@ django_cfg/utils/version_check.py,sha256=jI4v3YMdQriUEeb_TvRl511sDghy6I75iKRDUaN
1093
1100
  django_cfg/CHANGELOG.md,sha256=jtT3EprqEJkqSUh7IraP73vQ8PmKUMdRtznQsEnqDZk,2052
1094
1101
  django_cfg/CONTRIBUTING.md,sha256=DU2kyQ6PU0Z24ob7O_OqKWEYHcZmJDgzw-lQCmu6uBg,3041
1095
1102
  django_cfg/LICENSE,sha256=xHuytiUkSZCRG3N11nk1X6q1_EGQtv6aL5O9cqNRhKE,1071
1096
- django_cfg/pyproject.toml,sha256=w_z0KHaUolA5t2-T5vEIyA1QwhXNa2jkBosNLNd4784,8210
1097
- django_cfg-1.4.15.dist-info/METADATA,sha256=8mSJYTS5wa4dnkWG-MOuVwQANoWkE1jJU6vZJ-AcA4Y,22533
1098
- django_cfg-1.4.15.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
1099
- django_cfg-1.4.15.dist-info/entry_points.txt,sha256=Ucmde4Z2wEzgb4AggxxZ0zaYDb9HpyE5blM3uJ0_VNg,56
1100
- django_cfg-1.4.15.dist-info/licenses/LICENSE,sha256=xHuytiUkSZCRG3N11nk1X6q1_EGQtv6aL5O9cqNRhKE,1071
1101
- django_cfg-1.4.15.dist-info/RECORD,,
1103
+ django_cfg/pyproject.toml,sha256=UGYbf8bxudDXVeR9helgvuKB60_CZ7DJKvSdZbGti3c,8210
1104
+ django_cfg-1.4.19.dist-info/METADATA,sha256=OSuPmdcBTsGy2UJfTMgA1aAzdpwoZmDKaW3bch5XKmM,22533
1105
+ django_cfg-1.4.19.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
1106
+ django_cfg-1.4.19.dist-info/entry_points.txt,sha256=Ucmde4Z2wEzgb4AggxxZ0zaYDb9HpyE5blM3uJ0_VNg,56
1107
+ django_cfg-1.4.19.dist-info/licenses/LICENSE,sha256=xHuytiUkSZCRG3N11nk1X6q1_EGQtv6aL5O9cqNRhKE,1071
1108
+ django_cfg-1.4.19.dist-info/RECORD,,