litestar-vite 0.1.1__py3-none-any.whl → 0.15.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. litestar_vite/__init__.py +54 -4
  2. litestar_vite/__metadata__.py +12 -7
  3. litestar_vite/cli.py +1048 -10
  4. litestar_vite/codegen/__init__.py +48 -0
  5. litestar_vite/codegen/_export.py +229 -0
  6. litestar_vite/codegen/_inertia.py +619 -0
  7. litestar_vite/codegen/_openapi.py +280 -0
  8. litestar_vite/codegen/_routes.py +720 -0
  9. litestar_vite/codegen/_ts.py +235 -0
  10. litestar_vite/codegen/_utils.py +141 -0
  11. litestar_vite/commands.py +73 -0
  12. litestar_vite/config/__init__.py +997 -0
  13. litestar_vite/config/_constants.py +97 -0
  14. litestar_vite/config/_deploy.py +70 -0
  15. litestar_vite/config/_inertia.py +241 -0
  16. litestar_vite/config/_paths.py +63 -0
  17. litestar_vite/config/_runtime.py +235 -0
  18. litestar_vite/config/_spa.py +93 -0
  19. litestar_vite/config/_types.py +94 -0
  20. litestar_vite/deploy.py +366 -0
  21. litestar_vite/doctor.py +1181 -0
  22. litestar_vite/exceptions.py +78 -0
  23. litestar_vite/executor.py +360 -0
  24. litestar_vite/handler/__init__.py +9 -0
  25. litestar_vite/handler/_app.py +612 -0
  26. litestar_vite/handler/_routing.py +130 -0
  27. litestar_vite/html_transform.py +569 -0
  28. litestar_vite/inertia/__init__.py +77 -0
  29. litestar_vite/inertia/_utils.py +119 -0
  30. litestar_vite/inertia/exception_handler.py +178 -0
  31. litestar_vite/inertia/helpers.py +1571 -0
  32. litestar_vite/inertia/middleware.py +54 -0
  33. litestar_vite/inertia/plugin.py +199 -0
  34. litestar_vite/inertia/precognition.py +274 -0
  35. litestar_vite/inertia/request.py +334 -0
  36. litestar_vite/inertia/response.py +802 -0
  37. litestar_vite/inertia/types.py +335 -0
  38. litestar_vite/loader.py +464 -123
  39. litestar_vite/plugin/__init__.py +687 -0
  40. litestar_vite/plugin/_process.py +185 -0
  41. litestar_vite/plugin/_proxy.py +689 -0
  42. litestar_vite/plugin/_proxy_headers.py +244 -0
  43. litestar_vite/plugin/_static.py +37 -0
  44. litestar_vite/plugin/_utils.py +489 -0
  45. litestar_vite/py.typed +0 -0
  46. litestar_vite/scaffolding/__init__.py +20 -0
  47. litestar_vite/scaffolding/generator.py +270 -0
  48. litestar_vite/scaffolding/templates.py +437 -0
  49. litestar_vite/templates/__init__.py +0 -0
  50. litestar_vite/templates/addons/tailwindcss/tailwind.css.j2 +1 -0
  51. litestar_vite/templates/angular/index.html.j2 +12 -0
  52. litestar_vite/templates/angular/openapi-ts.config.ts.j2 +18 -0
  53. litestar_vite/templates/angular/package.json.j2 +36 -0
  54. litestar_vite/templates/angular/src/app/app.component.css.j2 +3 -0
  55. litestar_vite/templates/angular/src/app/app.component.html.j2 +1 -0
  56. litestar_vite/templates/angular/src/app/app.component.ts.j2 +9 -0
  57. litestar_vite/templates/angular/src/app/app.config.ts.j2 +5 -0
  58. litestar_vite/templates/angular/src/main.ts.j2 +9 -0
  59. litestar_vite/templates/angular/src/styles.css.j2 +9 -0
  60. litestar_vite/templates/angular/tsconfig.app.json.j2 +34 -0
  61. litestar_vite/templates/angular/tsconfig.json.j2 +20 -0
  62. litestar_vite/templates/angular/vite.config.ts.j2 +21 -0
  63. litestar_vite/templates/angular-cli/.postcssrc.json.j2 +5 -0
  64. litestar_vite/templates/angular-cli/angular.json.j2 +36 -0
  65. litestar_vite/templates/angular-cli/openapi-ts.config.ts.j2 +18 -0
  66. litestar_vite/templates/angular-cli/package.json.j2 +28 -0
  67. litestar_vite/templates/angular-cli/proxy.conf.json.j2 +18 -0
  68. litestar_vite/templates/angular-cli/src/app/app.component.css.j2 +3 -0
  69. litestar_vite/templates/angular-cli/src/app/app.component.html.j2 +1 -0
  70. litestar_vite/templates/angular-cli/src/app/app.component.ts.j2 +9 -0
  71. litestar_vite/templates/angular-cli/src/app/app.config.ts.j2 +5 -0
  72. litestar_vite/templates/angular-cli/src/index.html.j2 +13 -0
  73. litestar_vite/templates/angular-cli/src/main.ts.j2 +6 -0
  74. litestar_vite/templates/angular-cli/src/styles.css.j2 +10 -0
  75. litestar_vite/templates/angular-cli/tailwind.config.js.j2 +4 -0
  76. litestar_vite/templates/angular-cli/tsconfig.app.json.j2 +16 -0
  77. litestar_vite/templates/angular-cli/tsconfig.json.j2 +26 -0
  78. litestar_vite/templates/angular-cli/tsconfig.spec.json.j2 +9 -0
  79. litestar_vite/templates/astro/astro.config.mjs.j2 +28 -0
  80. litestar_vite/templates/astro/openapi-ts.config.ts.j2 +15 -0
  81. litestar_vite/templates/astro/src/layouts/Layout.astro.j2 +63 -0
  82. litestar_vite/templates/astro/src/pages/index.astro.j2 +36 -0
  83. litestar_vite/templates/astro/src/styles/global.css.j2 +1 -0
  84. litestar_vite/templates/base/.gitignore.j2 +42 -0
  85. litestar_vite/templates/base/openapi-ts.config.ts.j2 +15 -0
  86. litestar_vite/templates/base/package.json.j2 +39 -0
  87. litestar_vite/templates/base/resources/vite-env.d.ts.j2 +1 -0
  88. litestar_vite/templates/base/tsconfig.json.j2 +37 -0
  89. litestar_vite/templates/htmx/src/main.js.j2 +8 -0
  90. litestar_vite/templates/htmx/templates/base.html.j2.j2 +56 -0
  91. litestar_vite/templates/htmx/templates/index.html.j2.j2 +13 -0
  92. litestar_vite/templates/htmx/vite.config.ts.j2 +40 -0
  93. litestar_vite/templates/nuxt/app.vue.j2 +29 -0
  94. litestar_vite/templates/nuxt/composables/useApi.ts.j2 +33 -0
  95. litestar_vite/templates/nuxt/nuxt.config.ts.j2 +31 -0
  96. litestar_vite/templates/nuxt/openapi-ts.config.ts.j2 +15 -0
  97. litestar_vite/templates/nuxt/pages/index.vue.j2 +54 -0
  98. litestar_vite/templates/react/index.html.j2 +13 -0
  99. litestar_vite/templates/react/src/App.css.j2 +56 -0
  100. litestar_vite/templates/react/src/App.tsx.j2 +19 -0
  101. litestar_vite/templates/react/src/main.tsx.j2 +10 -0
  102. litestar_vite/templates/react/vite.config.ts.j2 +39 -0
  103. litestar_vite/templates/react-inertia/index.html.j2 +14 -0
  104. litestar_vite/templates/react-inertia/package.json.j2 +47 -0
  105. litestar_vite/templates/react-inertia/resources/App.css.j2 +68 -0
  106. litestar_vite/templates/react-inertia/resources/main.tsx.j2 +17 -0
  107. litestar_vite/templates/react-inertia/resources/pages/Home.tsx.j2 +18 -0
  108. litestar_vite/templates/react-inertia/resources/ssr.tsx.j2 +19 -0
  109. litestar_vite/templates/react-inertia/vite.config.ts.j2 +59 -0
  110. litestar_vite/templates/react-router/index.html.j2 +12 -0
  111. litestar_vite/templates/react-router/src/App.css.j2 +17 -0
  112. litestar_vite/templates/react-router/src/App.tsx.j2 +7 -0
  113. litestar_vite/templates/react-router/src/main.tsx.j2 +10 -0
  114. litestar_vite/templates/react-router/vite.config.ts.j2 +39 -0
  115. litestar_vite/templates/react-tanstack/index.html.j2 +12 -0
  116. litestar_vite/templates/react-tanstack/openapi-ts.config.ts.j2 +18 -0
  117. litestar_vite/templates/react-tanstack/src/App.css.j2 +17 -0
  118. litestar_vite/templates/react-tanstack/src/main.tsx.j2 +21 -0
  119. litestar_vite/templates/react-tanstack/src/routeTree.gen.ts.j2 +7 -0
  120. litestar_vite/templates/react-tanstack/src/routes/__root.tsx.j2 +9 -0
  121. litestar_vite/templates/react-tanstack/src/routes/books.tsx.j2 +9 -0
  122. litestar_vite/templates/react-tanstack/src/routes/index.tsx.j2 +9 -0
  123. litestar_vite/templates/react-tanstack/vite.config.ts.j2 +39 -0
  124. litestar_vite/templates/svelte/index.html.j2 +13 -0
  125. litestar_vite/templates/svelte/src/App.svelte.j2 +30 -0
  126. litestar_vite/templates/svelte/src/app.css.j2 +45 -0
  127. litestar_vite/templates/svelte/src/main.ts.j2 +8 -0
  128. litestar_vite/templates/svelte/src/vite-env.d.ts.j2 +2 -0
  129. litestar_vite/templates/svelte/svelte.config.js.j2 +5 -0
  130. litestar_vite/templates/svelte/vite.config.ts.j2 +39 -0
  131. litestar_vite/templates/svelte-inertia/index.html.j2 +14 -0
  132. litestar_vite/templates/svelte-inertia/resources/app.css.j2 +21 -0
  133. litestar_vite/templates/svelte-inertia/resources/main.ts.j2 +11 -0
  134. litestar_vite/templates/svelte-inertia/resources/pages/Home.svelte.j2 +43 -0
  135. litestar_vite/templates/svelte-inertia/resources/vite-env.d.ts.j2 +2 -0
  136. litestar_vite/templates/svelte-inertia/svelte.config.js.j2 +5 -0
  137. litestar_vite/templates/svelte-inertia/vite.config.ts.j2 +37 -0
  138. litestar_vite/templates/sveltekit/openapi-ts.config.ts.j2 +15 -0
  139. litestar_vite/templates/sveltekit/src/app.css.j2 +40 -0
  140. litestar_vite/templates/sveltekit/src/app.html.j2 +12 -0
  141. litestar_vite/templates/sveltekit/src/hooks.server.ts.j2 +55 -0
  142. litestar_vite/templates/sveltekit/src/routes/+layout.svelte.j2 +12 -0
  143. litestar_vite/templates/sveltekit/src/routes/+page.svelte.j2 +34 -0
  144. litestar_vite/templates/sveltekit/svelte.config.js.j2 +12 -0
  145. litestar_vite/templates/sveltekit/tsconfig.json.j2 +14 -0
  146. litestar_vite/templates/sveltekit/vite.config.ts.j2 +31 -0
  147. litestar_vite/templates/vue/env.d.ts.j2 +7 -0
  148. litestar_vite/templates/vue/index.html.j2 +13 -0
  149. litestar_vite/templates/vue/src/App.vue.j2 +28 -0
  150. litestar_vite/templates/vue/src/main.ts.j2 +5 -0
  151. litestar_vite/templates/vue/src/style.css.j2 +45 -0
  152. litestar_vite/templates/vue/vite.config.ts.j2 +39 -0
  153. litestar_vite/templates/vue-inertia/env.d.ts.j2 +7 -0
  154. litestar_vite/templates/vue-inertia/index.html.j2 +14 -0
  155. litestar_vite/templates/vue-inertia/package.json.j2 +50 -0
  156. litestar_vite/templates/vue-inertia/resources/main.ts.j2 +18 -0
  157. litestar_vite/templates/vue-inertia/resources/pages/Home.vue.j2 +22 -0
  158. litestar_vite/templates/vue-inertia/resources/ssr.ts.j2 +21 -0
  159. litestar_vite/templates/vue-inertia/resources/style.css.j2 +21 -0
  160. litestar_vite/templates/vue-inertia/vite.config.ts.j2 +59 -0
  161. litestar_vite-0.15.0.dist-info/METADATA +230 -0
  162. litestar_vite-0.15.0.dist-info/RECORD +164 -0
  163. {litestar_vite-0.1.1.dist-info → litestar_vite-0.15.0.dist-info}/WHEEL +1 -1
  164. litestar_vite/config.py +0 -100
  165. litestar_vite/plugin.py +0 -45
  166. litestar_vite/template_engine.py +0 -103
  167. litestar_vite-0.1.1.dist-info/METADATA +0 -68
  168. litestar_vite-0.1.1.dist-info/RECORD +0 -11
  169. {litestar_vite-0.1.1.dist-info → litestar_vite-0.15.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,48 @@
1
+ """Public code generation API.
2
+
3
+ This package provides code generation utilities for:
4
+
5
+ - Unified asset export (``export_integration_assets``)
6
+ - Route metadata export (``routes.json`` + Ziggy-compatible TS)
7
+ - Inertia page props metadata export
8
+
9
+ Internal implementation details (OpenAPI integration, TypeScript conversion)
10
+ are kept in private submodules to keep the public API clean.
11
+ """
12
+
13
+ from litestar_vite.codegen._export import ExportResult, export_integration_assets
14
+ from litestar_vite.codegen._inertia import (
15
+ InertiaPageMetadata,
16
+ extract_inertia_pages,
17
+ generate_inertia_pages_json,
18
+ get_openapi_schema_ref, # pyright: ignore[reportUnusedImport]
19
+ get_return_type_name, # pyright: ignore[reportUnusedImport]
20
+ )
21
+ from litestar_vite.codegen._routes import (
22
+ RouteMetadata,
23
+ escape_ts_string, # pyright: ignore[reportUnusedImport]
24
+ extract_route_metadata,
25
+ generate_routes_json,
26
+ generate_routes_ts,
27
+ is_type_required, # pyright: ignore[reportUnusedImport]
28
+ ts_type_for_param, # pyright: ignore[reportUnusedImport]
29
+ )
30
+ from litestar_vite.codegen._ts import (
31
+ ts_type_from_openapi as _ts_type_from_openapi, # pyright: ignore[reportUnusedImport]
32
+ )
33
+ from litestar_vite.codegen._utils import encode_deterministic_json, strip_timestamp_for_comparison, write_if_changed
34
+
35
+ __all__ = (
36
+ "ExportResult",
37
+ "InertiaPageMetadata",
38
+ "RouteMetadata",
39
+ "encode_deterministic_json",
40
+ "export_integration_assets",
41
+ "extract_inertia_pages",
42
+ "extract_route_metadata",
43
+ "generate_inertia_pages_json",
44
+ "generate_routes_json",
45
+ "generate_routes_ts",
46
+ "strip_timestamp_for_comparison",
47
+ "write_if_changed",
48
+ )
@@ -0,0 +1,229 @@
1
+ """Unified asset export pipeline for deterministic code generation.
2
+
3
+ This module provides a single entry point for exporting all integration artifacts:
4
+ - openapi.json (OpenAPI schema with Inertia types registered)
5
+ - routes.json (route metadata)
6
+ - routes.ts (Ziggy-style typed routes)
7
+ - inertia-pages.json (Inertia page props metadata)
8
+
9
+ Both CLI and Plugin should call this function to guarantee byte-identical output.
10
+ """
11
+
12
+ from dataclasses import dataclass, field
13
+ from functools import partial
14
+ from pathlib import Path
15
+ from typing import TYPE_CHECKING, Any
16
+
17
+ if TYPE_CHECKING:
18
+ from collections.abc import Callable
19
+
20
+ from litestar import Litestar
21
+
22
+ from litestar_vite.config import TypeGenConfig, ViteConfig
23
+
24
+
25
+ @dataclass
26
+ class ExportResult:
27
+ """Result of the export operation."""
28
+
29
+ exported_files: list[str] = field(default_factory=list) # pyright: ignore[reportUnknownVariableType]
30
+ """Files that were written (content changed)."""
31
+
32
+ unchanged_files: list[str] = field(default_factory=list) # pyright: ignore[reportUnknownVariableType]
33
+ """Files that were skipped (content unchanged)."""
34
+
35
+ openapi_schema: "dict[str, Any] | None" = None
36
+ """The OpenAPI schema dict (for downstream use)."""
37
+
38
+
39
+ def fmt_path(path: Path) -> str:
40
+ """Format path for display, using relative path when possible.
41
+
42
+ Returns:
43
+ The result.
44
+ """
45
+ try:
46
+ return str(path.relative_to(Path.cwd()))
47
+ except ValueError:
48
+ return str(path)
49
+
50
+
51
+ def export_integration_assets(
52
+ app: "Litestar", config: "ViteConfig", *, serializer: "Callable[[Any], bytes] | None" = None
53
+ ) -> ExportResult:
54
+ """Export all integration artifacts with deterministic output.
55
+
56
+ This is the single source of truth for code generation. Both CLI commands
57
+ and Plugin startup should call this function to ensure byte-identical output.
58
+
59
+ The export order is critical:
60
+ 1. Register Inertia page prop types in OpenAPI schema (mutates schema_dict)
61
+ 2. Export openapi.json (now includes session prop types)
62
+ 3. Export routes.json (uses schema for component refs)
63
+ 4. Export routes.ts (if enabled)
64
+ 5. Export inertia-pages.json (if enabled)
65
+
66
+ Args:
67
+ app: The Litestar application instance.
68
+ config: The ViteConfig instance.
69
+ serializer: Optional custom serializer for OpenAPI schema encoding.
70
+
71
+ Returns:
72
+ ExportResult with lists of exported and unchanged files.
73
+ """
74
+ from litestar._openapi.plugin import OpenAPIPlugin
75
+ from litestar.serialization import encode_json, get_serializer
76
+
77
+ from litestar_vite.codegen._inertia import generate_inertia_pages_json
78
+ from litestar_vite.config import InertiaConfig, InertiaTypeGenConfig, TypeGenConfig
79
+
80
+ result = ExportResult()
81
+
82
+ if not isinstance(config.types, TypeGenConfig):
83
+ return result
84
+
85
+ types_config = config.types
86
+
87
+ # Check if OpenAPI is available
88
+ openapi_plugin = next((p for p in app.plugins._plugins if isinstance(p, OpenAPIPlugin)), None) # pyright: ignore[reportPrivateUsage]
89
+ has_openapi = openapi_plugin is not None and openapi_plugin._openapi_config is not None # pyright: ignore[reportPrivateUsage]
90
+
91
+ if not has_openapi:
92
+ return result
93
+
94
+ # Get serializer for OpenAPI encoding
95
+ if serializer is None:
96
+ encoders: Any
97
+ try:
98
+ encoders = app.type_encoders # pyright: ignore[reportUnknownMemberType]
99
+ except AttributeError:
100
+ encoders = None
101
+ serializer = partial(encode_json, serializer=get_serializer(encoders if isinstance(encoders, dict) else None)) # pyright: ignore[reportUnknownArgumentType]
102
+
103
+ # Step 1: Get OpenAPI schema and register Inertia types
104
+ schema_dict = app.openapi_schema.to_schema()
105
+
106
+ # Register Inertia page prop types in OpenAPI schema BEFORE exporting
107
+ # This ensures types like EmailSent, NoProps, CurrentTeam are included
108
+ inertia_pages_data: dict[str, Any] | None = None
109
+ if isinstance(config.inertia, InertiaConfig) and types_config.generate_page_props:
110
+ inertia_type_gen = config.inertia.type_gen or InertiaTypeGenConfig()
111
+ inertia_pages_data = generate_inertia_pages_json(
112
+ app,
113
+ openapi_schema=schema_dict,
114
+ include_default_auth=inertia_type_gen.include_default_auth,
115
+ include_default_flash=inertia_type_gen.include_default_flash,
116
+ inertia_config=config.inertia,
117
+ types_config=types_config,
118
+ )
119
+
120
+ result.openapi_schema = schema_dict
121
+
122
+ # Step 2: Export openapi.json
123
+ export_openapi(schema_dict=schema_dict, types_config=types_config, serializer=serializer, result=result)
124
+
125
+ # Step 3: Export routes.json (always pass openapi_schema for consistency)
126
+ export_routes_json(app=app, types_config=types_config, openapi_schema=schema_dict, result=result)
127
+
128
+ # Step 4: Export routes.ts (if enabled)
129
+ if types_config.generate_routes:
130
+ export_routes_ts(app=app, types_config=types_config, openapi_schema=schema_dict, result=result)
131
+
132
+ # Step 5: Export inertia-pages.json (if enabled)
133
+ if (
134
+ isinstance(config.inertia, InertiaConfig)
135
+ and types_config.generate_page_props
136
+ and types_config.page_props_path
137
+ and inertia_pages_data is not None
138
+ ):
139
+ export_inertia_pages(pages_data=inertia_pages_data, types_config=types_config, result=result)
140
+
141
+ return result
142
+
143
+
144
+ def export_openapi(
145
+ *,
146
+ schema_dict: "dict[str, Any]",
147
+ types_config: "TypeGenConfig",
148
+ serializer: "Callable[[Any], bytes]",
149
+ result: ExportResult,
150
+ ) -> None:
151
+ """Export OpenAPI schema to file."""
152
+ from litestar_vite.codegen._utils import encode_deterministic_json, write_if_changed
153
+
154
+ openapi_path = types_config.openapi_path
155
+ if openapi_path is None:
156
+ openapi_path = types_config.output / "openapi.json"
157
+
158
+ schema_content = encode_deterministic_json(schema_dict, serializer=serializer)
159
+
160
+ if write_if_changed(openapi_path, schema_content):
161
+ result.exported_files.append(f"openapi: {fmt_path(openapi_path)}")
162
+ else:
163
+ result.unchanged_files.append("openapi.json")
164
+
165
+
166
+ def export_routes_json(
167
+ *, app: "Litestar", types_config: "TypeGenConfig", openapi_schema: "dict[str, Any]", result: ExportResult
168
+ ) -> None:
169
+ """Export routes metadata to JSON file."""
170
+ from litestar_vite.codegen._routes import generate_routes_json
171
+ from litestar_vite.codegen._utils import encode_deterministic_json, write_if_changed
172
+
173
+ try:
174
+ from litestar import __version__ as _version
175
+
176
+ litestar_version = str(_version)
177
+ except ImportError:
178
+ litestar_version = "unknown"
179
+
180
+ routes_path = types_config.routes_path
181
+ if routes_path is None:
182
+ routes_path = types_config.output / "routes.json"
183
+
184
+ # Always pass openapi_schema for consistent output between CLI and plugin
185
+ routes_data = generate_routes_json(app, include_components=True, openapi_schema=openapi_schema)
186
+ routes_data["litestar_version"] = litestar_version
187
+
188
+ routes_content = encode_deterministic_json(routes_data)
189
+
190
+ if write_if_changed(routes_path, routes_content):
191
+ result.exported_files.append(fmt_path(routes_path))
192
+ else:
193
+ result.unchanged_files.append("routes.json")
194
+
195
+
196
+ def export_routes_ts(
197
+ *, app: "Litestar", types_config: "TypeGenConfig", openapi_schema: "dict[str, Any]", result: ExportResult
198
+ ) -> None:
199
+ """Export typed routes TypeScript file."""
200
+ from litestar_vite.codegen._routes import generate_routes_ts
201
+ from litestar_vite.codegen._utils import write_if_changed
202
+
203
+ routes_ts_path = types_config.routes_ts_path
204
+ if routes_ts_path is None:
205
+ routes_ts_path = types_config.output / "routes.ts"
206
+
207
+ # Always pass openapi_schema for consistent output
208
+ routes_ts_content = generate_routes_ts(app, openapi_schema=openapi_schema, global_route=types_config.global_route)
209
+
210
+ if write_if_changed(routes_ts_path, routes_ts_content):
211
+ result.exported_files.append(fmt_path(routes_ts_path))
212
+ else:
213
+ result.unchanged_files.append("routes.ts")
214
+
215
+
216
+ def export_inertia_pages(*, pages_data: "dict[str, Any]", types_config: "TypeGenConfig", result: ExportResult) -> None:
217
+ """Export Inertia pages metadata to JSON file."""
218
+ from litestar_vite.codegen._utils import encode_deterministic_json, write_if_changed
219
+
220
+ page_props_path = types_config.page_props_path
221
+ if page_props_path is None:
222
+ return
223
+
224
+ pages_content = encode_deterministic_json(pages_data)
225
+
226
+ if write_if_changed(page_props_path, pages_content):
227
+ result.exported_files.append(fmt_path(page_props_path))
228
+ else:
229
+ result.unchanged_files.append("inertia-pages.json")