pyxle-framework 0.2.2__tar.gz → 0.2.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (200) hide show
  1. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/PKG-INFO +1 -1
  2. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/docs/README.md +1 -1
  3. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/docs/faq.md +1 -1
  4. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyproject.toml +1 -1
  5. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/ssr/_escape.py +15 -8
  6. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/ssr/test_escape.py +34 -4
  7. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/.github/pyxle-logo.svg +0 -0
  8. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/.github/workflows/publish.yml +0 -0
  9. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/.gitignore +0 -0
  10. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/CLAUDE.md +0 -0
  11. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/LICENSE +0 -0
  12. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/Makefile +0 -0
  13. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/README.md +0 -0
  14. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/docs/advanced/compiler-internals.md +0 -0
  15. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/docs/advanced/ssr-pipeline.md +0 -0
  16. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/docs/architecture/README.md +0 -0
  17. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/docs/architecture/build-and-serve.md +0 -0
  18. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/docs/architecture/cli.md +0 -0
  19. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/docs/architecture/compiler.md +0 -0
  20. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/docs/architecture/dev-server.md +0 -0
  21. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/docs/architecture/overview.md +0 -0
  22. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/docs/architecture/parser.md +0 -0
  23. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/docs/architecture/pyxl-files.md +0 -0
  24. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/docs/architecture/routing.md +0 -0
  25. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/docs/architecture/runtime.md +0 -0
  26. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/docs/architecture/ssr.md +0 -0
  27. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/docs/core-concepts/data-loading.md +0 -0
  28. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/docs/core-concepts/layouts.md +0 -0
  29. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/docs/core-concepts/pyxl-files.md +0 -0
  30. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/docs/core-concepts/routing.md +0 -0
  31. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/docs/core-concepts/server-actions.md +0 -0
  32. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/docs/getting-started/installation.md +0 -0
  33. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/docs/getting-started/project-structure.md +0 -0
  34. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/docs/getting-started/quick-start.md +0 -0
  35. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/docs/guides/api-routes.md +0 -0
  36. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/docs/guides/client-components.md +0 -0
  37. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/docs/guides/deployment.md +0 -0
  38. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/docs/guides/editor-setup.md +0 -0
  39. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/docs/guides/environment-variables.md +0 -0
  40. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/docs/guides/error-handling.md +0 -0
  41. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/docs/guides/for-ai-agents.md +0 -0
  42. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/docs/guides/head-management.md +0 -0
  43. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/docs/guides/middleware.md +0 -0
  44. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/docs/guides/migration-pyx-to-pyxl.md +0 -0
  45. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/docs/guides/security.md +0 -0
  46. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/docs/guides/styling.md +0 -0
  47. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/docs/reference/cli.md +0 -0
  48. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/docs/reference/client-api.md +0 -0
  49. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/docs/reference/configuration.md +0 -0
  50. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/docs/reference/runtime-api.md +0 -0
  51. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/__init__.py +0 -0
  52. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/build/__init__.py +0 -0
  53. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/build/manifest.py +0 -0
  54. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/build/pipeline.py +0 -0
  55. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/build/vite.py +0 -0
  56. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/cli/__init__.py +0 -0
  57. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/cli/assets.py +0 -0
  58. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/cli/init.py +0 -0
  59. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/cli/logger.py +0 -0
  60. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/cli/scaffold.py +0 -0
  61. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/cli/templates.py +0 -0
  62. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/client/ClientOnly.jsx +0 -0
  63. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/client/Form.jsx +0 -0
  64. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/client/Head.jsx +0 -0
  65. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/client/Image.jsx +0 -0
  66. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/client/Script.jsx +0 -0
  67. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/client/index.js +0 -0
  68. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/client/useAction.jsx +0 -0
  69. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/client/usePathname.jsx +0 -0
  70. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/compiler/__init__.py +0 -0
  71. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/compiler/core.py +0 -0
  72. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/compiler/exceptions.py +0 -0
  73. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/compiler/jsx_imports.py +0 -0
  74. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/compiler/jsx_parser.py +0 -0
  75. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/compiler/model.py +0 -0
  76. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/compiler/parser.py +0 -0
  77. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/compiler/writers.py +0 -0
  78. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/config.py +0 -0
  79. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/devserver/__init__.py +0 -0
  80. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/devserver/_security.py +0 -0
  81. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/devserver/build.py +0 -0
  82. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/devserver/builder.py +0 -0
  83. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/devserver/client_files.py +0 -0
  84. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/devserver/csrf.py +0 -0
  85. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/devserver/error_pages.py +0 -0
  86. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/devserver/layouts.py +0 -0
  87. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/devserver/middleware.py +0 -0
  88. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/devserver/overlay.py +0 -0
  89. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/devserver/path_utils.py +0 -0
  90. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/devserver/proxy.py +0 -0
  91. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/devserver/registry.py +0 -0
  92. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/devserver/route_hooks.py +0 -0
  93. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/devserver/routes.py +0 -0
  94. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/devserver/scanner.py +0 -0
  95. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/devserver/scripts.py +0 -0
  96. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/devserver/settings.py +0 -0
  97. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/devserver/starlette_app.py +0 -0
  98. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/devserver/styles.py +0 -0
  99. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/devserver/tailwind.py +0 -0
  100. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/devserver/vite.py +0 -0
  101. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/devserver/watcher.py +0 -0
  102. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/env.py +0 -0
  103. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/routing/__init__.py +0 -0
  104. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/routing/paths.py +0 -0
  105. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/runtime/ClientOnly.jsx +0 -0
  106. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/runtime/Head.jsx +0 -0
  107. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/runtime/Image.jsx +0 -0
  108. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/runtime/Script.jsx +0 -0
  109. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/runtime.py +0 -0
  110. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/ssr/__init__.py +0 -0
  111. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/ssr/head_merger.py +0 -0
  112. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/ssr/render_component.mjs +0 -0
  113. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/ssr/renderer.py +0 -0
  114. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/ssr/ssr_worker.mjs +0 -0
  115. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/ssr/template.py +0 -0
  116. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/ssr/view.py +0 -0
  117. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/ssr/worker_pool.py +0 -0
  118. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/templates/__init__.py +0 -0
  119. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/templates/scaffold/.gitignore +0 -0
  120. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/templates/scaffold/__init__.py +0 -0
  121. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/templates/scaffold/package.json +0 -0
  122. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/templates/scaffold/pages/api/pulse.py +0 -0
  123. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/templates/scaffold/pages/index.pyxl +0 -0
  124. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/templates/scaffold/pages/layout.pyxl +0 -0
  125. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/templates/scaffold/pages/styles/tailwind.css +0 -0
  126. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/templates/scaffold/postcss.config.cjs +0 -0
  127. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/templates/scaffold/public/branding/pyxle-mark.svg +0 -0
  128. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/templates/scaffold/public/styles/tailwind.css +0 -0
  129. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/templates/scaffold/pyxle.config.json +0 -0
  130. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/templates/scaffold/requirements.txt +0 -0
  131. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/pyxle/templates/scaffold/tailwind.config.cjs +0 -0
  132. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/__init__.py +0 -0
  133. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/build/__init__.py +0 -0
  134. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/build/test_manifest.py +0 -0
  135. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/build/test_pipeline.py +0 -0
  136. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/build/test_pipeline_css.py +0 -0
  137. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/build/test_vite.py +0 -0
  138. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/cli/__init__.py +0 -0
  139. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/cli/test_commands.py +0 -0
  140. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/cli/test_logger.py +0 -0
  141. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/cli/test_scaffold.py +0 -0
  142. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/cli/test_templates.py +0 -0
  143. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/compiler/__init__.py +0 -0
  144. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/compiler/test_action_compile.py +0 -0
  145. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/compiler/test_action_model.py +0 -0
  146. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/compiler/test_action_parser.py +0 -0
  147. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/compiler/test_action_writers.py +0 -0
  148. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/compiler/test_compile.py +0 -0
  149. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/compiler/test_head_jsx.py +0 -0
  150. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/compiler/test_jsx_imports.py +0 -0
  151. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/compiler/test_jsx_parser.py +0 -0
  152. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/compiler/test_parser.py +0 -0
  153. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/compiler/test_parser_diagnostics.py +0 -0
  154. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/compiler/test_parser_hardening.py +0 -0
  155. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/compiler/test_script_image_detection.py +0 -0
  156. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/compiler/test_script_image_integration.py +0 -0
  157. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/devserver/__init__.py +0 -0
  158. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/devserver/sample_middlewares.py +0 -0
  159. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/devserver/test_action_routes.py +0 -0
  160. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/devserver/test_build.py +0 -0
  161. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/devserver/test_builder.py +0 -0
  162. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/devserver/test_client_files.py +0 -0
  163. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/devserver/test_client_only.py +0 -0
  164. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/devserver/test_csrf.py +0 -0
  165. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/devserver/test_devserver_start.py +0 -0
  166. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/devserver/test_error_pages.py +0 -0
  167. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/devserver/test_layouts.py +0 -0
  168. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/devserver/test_middleware.py +0 -0
  169. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/devserver/test_overlay.py +0 -0
  170. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/devserver/test_proxy.py +0 -0
  171. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/devserver/test_registry.py +0 -0
  172. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/devserver/test_route_error_boundary.py +0 -0
  173. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/devserver/test_route_hooks.py +0 -0
  174. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/devserver/test_routes.py +0 -0
  175. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/devserver/test_scanner.py +0 -0
  176. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/devserver/test_scripts.py +0 -0
  177. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/devserver/test_security_utils.py +0 -0
  178. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/devserver/test_settings.py +0 -0
  179. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/devserver/test_starlette_app.py +0 -0
  180. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/devserver/test_styles.py +0 -0
  181. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/devserver/test_tailwind.py +0 -0
  182. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/devserver/test_vite.py +0 -0
  183. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/devserver/test_watcher.py +0 -0
  184. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/ssr/__init__.py +0 -0
  185. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/ssr/test_dynamic_head.py +0 -0
  186. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/ssr/test_head_merger_extra.py +0 -0
  187. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/ssr/test_head_merging.py +0 -0
  188. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/ssr/test_integration.py +0 -0
  189. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/ssr/test_renderer.py +0 -0
  190. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/ssr/test_script_injection.py +0 -0
  191. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/ssr/test_template.py +0 -0
  192. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/ssr/test_view.py +0 -0
  193. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/ssr/test_view_error_boundaries.py +0 -0
  194. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/ssr/test_worker_pool.py +0 -0
  195. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/ssr/utils.py +0 -0
  196. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/test_config.py +0 -0
  197. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/test_config_security.py +0 -0
  198. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/test_env.py +0 -0
  199. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/test_runtime.py +0 -0
  200. {pyxle_framework-0.2.2 → pyxle_framework-0.2.3}/tests/test_runtime_errors.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyxle-framework
3
- Version: 0.2.2
3
+ Version: 0.2.3
4
4
  Summary: Python-first full-stack framework with an intelligent CLI.
5
5
  Project-URL: Homepage, https://pyxle.dev
6
6
  Project-URL: Repository, https://github.com/pyxle-framework/pyxle
@@ -2,7 +2,7 @@
2
2
 
3
3
  Pyxle is a Python-first full-stack web framework that brings the Next.js developer experience to the Python ecosystem. Write server logic in Python, UI in React, and ship them together in `.pyxl` files.
4
4
 
5
- **Current version:** 0.2.2 (beta)
5
+ **Current version:** 0.2.3 (beta)
6
6
 
7
7
  ---
8
8
 
@@ -22,7 +22,7 @@ Django and Flask are backend frameworks that render templates. Pyxle is a full-s
22
22
 
23
23
  ### Is Pyxle production-ready?
24
24
 
25
- Pyxle is in **beta** (version 0.2.2). The core features are implemented and tested (1100+ tests, 95%+ coverage), but the API may change before 1.0. Use it for new projects and experiments, but be prepared for breaking changes.
25
+ Pyxle is in **beta** (version 0.2.3). The core features are implemented and tested (1100+ tests, 95%+ coverage), but the API may change before 1.0. Use it for new projects and experiments, but be prepared for breaking changes.
26
26
 
27
27
  ### What Python version do I need?
28
28
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "pyxle-framework"
7
- version = "0.2.2"
7
+ version = "0.2.3"
8
8
  description = "Python-first full-stack framework with an intelligent CLI."
9
9
  readme = "README.md"
10
10
  authors = [
@@ -15,13 +15,20 @@ from __future__ import annotations
15
15
  def escape_inline_json(value: str) -> str:
16
16
  """Escape *value* for safe inclusion inside an HTML ``<script>`` block.
17
17
 
18
- The following replacements are applied:
18
+ Every replacement is chosen to break an HTML-tokenizer sequence while
19
+ staying **valid JSON**, so the output can still be placed inside a
20
+ ``<script type="application/json">`` block and parsed with ``JSON.parse``:
19
21
 
20
- * ``</`` → ``<\\/`` prevents premature ``</script>`` close
21
- * ``<!--`` → ``<\\!--``prevents HTML comment opening
22
- * ``-->`` → ``--\\>``prevents HTML comment closing
23
- * U+2028 → ``\\u2028``— JS line separator (not valid in JSON strings)
24
- * U+2029 → ``\\u2029``— JS paragraph separator
22
+ * ``</`` → ``<\\/`` ``\\/`` is a valid JSON escape for ``/``
23
+ * ``<!--`` → ``\\u003c!--````\\u003c`` is the Unicode escape for ``<``
24
+ * ``-->`` → ``--\\u003e````\\u003e`` is the Unicode escape for ``>``
25
+ * U+2028 → ``\\u2028`` — JS line separator (not a newline in JSON)
26
+ * U+2029 → ``\\u2029`` — JS paragraph separator
27
+
28
+ The earlier implementation of the comment replacements used ``\\!`` and
29
+ ``\\>`` which are **not** valid JSON escape sequences and caused
30
+ ``JSON.parse`` to fail on pages whose props happened to contain
31
+ ``<!--`` or ``-->`` verbatim (e.g. docs pages embedding shell output).
25
32
 
26
33
  The input is expected to be the return value of :func:`json.dumps` or
27
34
  raw CSS text — **not** arbitrary HTML.
@@ -29,8 +36,8 @@ def escape_inline_json(value: str) -> str:
29
36
  return (
30
37
  value
31
38
  .replace("</", "<\\/")
32
- .replace("<!--", "<\\!--")
33
- .replace("-->", "--\\>")
39
+ .replace("<!--", "\\u003c!--")
40
+ .replace("-->", "--\\u003e")
34
41
  .replace("\u2028", "\\u2028")
35
42
  .replace("\u2029", "\\u2029")
36
43
  )
@@ -1,5 +1,7 @@
1
1
  """Tests for pyxle.ssr._escape — inline-JSON escaping utilities."""
2
2
 
3
+ import json
4
+
3
5
  import pytest
4
6
 
5
7
  from pyxle.ssr._escape import escape_inline_json
@@ -18,12 +20,12 @@ class TestEscapeInlineJson:
18
20
  def test_html_comment_open(self):
19
21
  result = escape_inline_json("<!-- comment -->")
20
22
  assert "<!--" not in result
21
- assert "<\\!--" in result
23
+ assert "\\u003c!--" in result
22
24
 
23
25
  def test_html_comment_close(self):
24
26
  result = escape_inline_json("<!-- comment -->")
25
27
  assert "-->" not in result
26
- assert "--\\>" in result
28
+ assert "--\\u003e" in result
27
29
 
28
30
  def test_unicode_line_separator(self):
29
31
  result = escape_inline_json('{"x":"\u2028"}')
@@ -55,11 +57,39 @@ class TestEscapeInlineJson:
55
57
  "input_val,expected_fragment",
56
58
  [
57
59
  ("</", "<\\/"),
58
- ("<!--", "<\\!--"),
59
- ("-->", "--\\>"),
60
+ ("<!--", "\\u003c!--"),
61
+ ("-->", "--\\u003e"),
60
62
  ("\u2028", "\\u2028"),
61
63
  ("\u2029", "\\u2029"),
62
64
  ],
63
65
  )
64
66
  def test_individual_replacements(self, input_val, expected_fragment):
65
67
  assert expected_fragment in escape_inline_json(input_val)
68
+
69
+ @pytest.mark.parametrize(
70
+ "payload",
71
+ [
72
+ {"raw": "--> shell prompt"},
73
+ {"raw": "<!-- html comment -->"},
74
+ {"raw": "</script><script>alert(1)</script>"},
75
+ {"raw": "line1\u2028line2"},
76
+ {"nested": {"list": ["-->", "<!--", "</script>"]}},
77
+ {"combo": "foo --> bar <!-- baz --> qux </script>"},
78
+ ],
79
+ )
80
+ def test_output_is_valid_json_after_escape(self, payload):
81
+ """Regression: the escaped output MUST still be parseable with
82
+ JSON.parse / json.loads, and it must round-trip to the original data.
83
+
84
+ Earlier versions replaced ``<!--`` with ``<\\!--`` and ``-->`` with
85
+ ``--\\>``, both of which are invalid JSON escape sequences — this
86
+ broke every docs page whose rendered content contained a literal
87
+ ``-->`` (e.g. shell output examples)."""
88
+ raw = json.dumps(payload, ensure_ascii=False)
89
+ escaped = escape_inline_json(raw)
90
+ # Must still parse, and must round-trip to the original data.
91
+ assert json.loads(escaped) == payload
92
+ # And none of the dangerous literal sequences survived.
93
+ assert "</" not in escaped or "<\\/" in escaped
94
+ assert "<!--" not in escaped
95
+ assert "-->" not in escaped
File without changes