nextpy-framework 3.7.3__tar.gz → 3.9.0__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.
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/__init__.py +1 -1
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/cli.py +151 -360
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/core/component_renderer.py +19 -11
- nextpy_framework-3.9.0/.nextpy_framework/nextpy/main.py +72 -0
- nextpy_framework-3.9.0/.nextpy_framework/nextpy/psx/compiler/actions.py +878 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/compiler/handler_compiler.py +52 -11
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/components/component.py +18 -6
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/core/parser.py +117 -30
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/core/runtime.py +15 -4
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/hydration/decorators.py +460 -136
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/hydration/engine.py +60 -1
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/hydration/integration.py +18 -4
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/runtime/actions_runtime.py +157 -11
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/runtime/js_actions_runtime.py +232 -52
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0/.nextpy_framework/nextpy_framework.egg-info}/PKG-INFO +3 -3
- {nextpy_framework-3.7.3/.nextpy_framework/nextpy_framework.egg-info → nextpy_framework-3.9.0}/PKG-INFO +3 -3
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/README.md +2 -2
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/pyproject.toml +1 -1
- nextpy_framework-3.7.3/.nextpy_framework/nextpy/main.py +0 -81
- nextpy_framework-3.7.3/.nextpy_framework/nextpy/psx/compiler/actions.py +0 -431
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/ast_parser.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/auth.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/builder.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/components/__init__.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/components/debug/AutoDebug.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/components/debug/AutoDebug_v3.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/components/debug/DebugIcon.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/components/debug/DebugIconFixed.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/components/feedback.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/components/form.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/components/head.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/components/hooks_provider.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/components/image.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/components/layout.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/components/link.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/components/loader.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/components/navigation.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/components/toast.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/components/ui.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/components/visual.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/components.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/conf.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/config.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/core/__init__.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/core/builder.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/core/component_router.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/core/data_fetching.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/core/demo_pages_simple.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/core/demo_router.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/core/renderer.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/core/router.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/core/sync.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/db.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/debug/core.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/debug/performance.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/debug/ui.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/debug/websocket.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/dev_server.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/dev_tools.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/errors.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/hooks.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/hooks_provider.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/hooks_provider_new.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/jsx.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/jsx_preprocessor.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/jsx_transformer.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/performance.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/plugins/__init__.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/plugins/base.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/plugins/builtin.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/plugins/config.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/plugins.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/__init__.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/core/__init__.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/core/ast_nodes.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/core/evaluator.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/devtools/language_server.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/devtools/language_server_lsp.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/devtools/psx_formatter.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/devtools/server_client_components.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/devtools/setup.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/hydration/__init__.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/renderer/renderer.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/tests/test_full_integration.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/tests/test_html_attribute_support.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/utils/helpers.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/psx/vdom/vnode.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/py.typed +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/runtime/events.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/security.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/server/__init__.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/server/app.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/server/debug.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/server/middleware.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/source/conf.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/HANDLER_REGISTRATION_SYSTEM.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/setup_complete.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_autodebug_enhanced.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_cli_scaffolding.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_colors.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_component_rendering.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_conversion.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_critical_fixes.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_demo_mode.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_demo_server.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_enhanced_handlers.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_extraction.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_final.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_fixes.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_handler_system.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_hydration_engine.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_integration.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_interactive_bug.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_jsx_edgecases.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_jsx_preprocessor.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_migration.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_modular_debug.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_routing.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_server.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_server_features.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_server_working.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_tailwind.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_tailwind_full.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_tailwind_integration.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_tailwind_up_to_date.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/tests/test_websocket_complete.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/true_jsx.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/utils/__init__.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/utils/cache.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/utils/email.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/utils/file_upload.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/utils/logging.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/utils/search.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/utils/seo.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/utils/validators.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy/websocket.py +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy_framework.egg-info/SOURCES.txt +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy_framework.egg-info/dependency_links.txt +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy_framework.egg-info/entry_points.txt +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy_framework.egg-info/requires.txt +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/.nextpy_framework/nextpy_framework.egg-info/top_level.txt +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/LICENSE +0 -0
- {nextpy_framework-3.7.3 → nextpy_framework-3.9.0}/setup.cfg +0 -0
|
@@ -243,7 +243,7 @@ def cli():
|
|
|
243
243
|
|
|
244
244
|
|
|
245
245
|
@cli.command()
|
|
246
|
-
@click.option("--port", "-p", default=
|
|
246
|
+
@click.option("--port", "-p", default=8000, help="Port to run the server on")
|
|
247
247
|
@click.option("--host", "-h", default="0.0.0.0", help="Host to bind to")
|
|
248
248
|
@click.option("--reload/--no-reload", default=True, help="Enable hot reload")
|
|
249
249
|
@click.option("--debug/--no-debug", default=True, help="Enable debug mode")
|
|
@@ -322,6 +322,7 @@ def dev(port: int, host: str, reload: bool, debug: bool):
|
|
|
322
322
|
# Enhanced reload patterns for JSX files
|
|
323
323
|
reload_includes = [
|
|
324
324
|
"*.py",
|
|
325
|
+
"*.psx",
|
|
325
326
|
"*.py.jsx",
|
|
326
327
|
"*.jsx",
|
|
327
328
|
"*.html",
|
|
@@ -993,7 +994,10 @@ def _generate_page(name: str):
|
|
|
993
994
|
page_path.parent.mkdir(parents=True, exist_ok=True)
|
|
994
995
|
|
|
995
996
|
content = f'''"""Generated {name} page"""
|
|
997
|
+
|
|
998
|
+
from nextpy.psx import interactive_component as component
|
|
996
999
|
|
|
1000
|
+
@component
|
|
997
1001
|
def {name.title()}(props = None):
|
|
998
1002
|
"""{name.title()} page component"""
|
|
999
1003
|
props = props or {{}}
|
|
@@ -1160,6 +1164,37 @@ def _create_project_structure(
|
|
|
1160
1164
|
</body>
|
|
1161
1165
|
</html>""")
|
|
1162
1166
|
click.echo(" Created: templates/_404.html")
|
|
1167
|
+
|
|
1168
|
+
try:
|
|
1169
|
+
from importlib.resources import files, as_file
|
|
1170
|
+
import shutil
|
|
1171
|
+
|
|
1172
|
+
images_dir = project_dir / "public" / "images"
|
|
1173
|
+
images_dir.mkdir(parents=True, exist_ok=True)
|
|
1174
|
+
|
|
1175
|
+
logo_source = files("nextpy.public").joinpath("logo.png")
|
|
1176
|
+
|
|
1177
|
+
with as_file(logo_source) as logo_path:
|
|
1178
|
+
shutil.copy2(
|
|
1179
|
+
logo_path,
|
|
1180
|
+
images_dir / "logo.png"
|
|
1181
|
+
)
|
|
1182
|
+
click.echo(" Copied: logo.png to public/images/")
|
|
1183
|
+
except Exception as e:
|
|
1184
|
+
click.echo(click.style(f" ⚠️ Failed to copy logo.png: {str(e)}", fg="yellow"))
|
|
1185
|
+
|
|
1186
|
+
#create minimal stylesheet
|
|
1187
|
+
(project_dir / "public" / "css"/ "styles.css").write_text("""/* NextPy Styles */
|
|
1188
|
+
body{
|
|
1189
|
+
margin: 0;
|
|
1190
|
+
padding: 0;
|
|
1191
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
|
1192
|
+
}
|
|
1193
|
+
""")
|
|
1194
|
+
|
|
1195
|
+
click.echo(" Created: public/css/styles.css")
|
|
1196
|
+
|
|
1197
|
+
|
|
1163
1198
|
|
|
1164
1199
|
# Create styles.css with Tailwind directives
|
|
1165
1200
|
(project_dir / "styles" / "styles.css").write_text("""/* NextPy Styles */
|
|
@@ -1329,7 +1364,7 @@ module.exports = {
|
|
|
1329
1364
|
|
|
1330
1365
|
(project_dir / "pages" / "index.py").write_text('''"""Interactive Homepage """
|
|
1331
1366
|
|
|
1332
|
-
from nextpy.psx import component
|
|
1367
|
+
from nextpy.psx import interactive_component as component
|
|
1333
1368
|
|
|
1334
1369
|
|
|
1335
1370
|
@component
|
|
@@ -1337,204 +1372,143 @@ def Home(props=None):
|
|
|
1337
1372
|
props = props or {}
|
|
1338
1373
|
title = props.get("title", "Welcome to NextPy!")
|
|
1339
1374
|
message = props.get("message", "Build amazing web apps with Python and True JSX")
|
|
1340
|
-
|
|
1341
|
-
return (
|
|
1342
|
-
<div class="min-h-screen bg-gradient-to-br from-blue-600 via-purple-600 to-pink-600">
|
|
1343
|
-
<div class="bg-white border-b border-white bg-opacity-10 backdrop-blur-md border-opacity-20">
|
|
1344
|
-
<div class="px-4 mx-auto max-w-7xl sm:px-6 lg:px-8">
|
|
1345
|
-
<div class="flex items-center justify-between h-16">
|
|
1346
|
-
<div class="flex items-center">
|
|
1347
|
-
<h1 class="text-xl font-bold text-white">NextPy</h1>
|
|
1348
|
-
</div>
|
|
1349
|
-
<div class="flex space-x-4">
|
|
1350
|
-
<a href="/about" class="px-3 py-2 text-sm font-medium text-white transition-colors rounded-md hover:text-blue-200">
|
|
1351
|
-
About
|
|
1352
|
-
</a>
|
|
1353
|
-
<a href="/features" class="px-3 py-2 text-sm font-medium text-white transition-colors rounded-md hover:text-blue-200">
|
|
1354
|
-
Features
|
|
1355
|
-
</a>
|
|
1356
|
-
<a href="/docs" class="px-3 py-2 text-sm font-medium text-white transition-colors rounded-md hover:text-blue-200">
|
|
1357
|
-
Docs
|
|
1358
|
-
</a>
|
|
1359
|
-
</div>
|
|
1360
|
-
</div>
|
|
1361
|
-
</div>
|
|
1362
|
-
</div>
|
|
1363
|
-
</div>
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
</div>
|
|
1368
|
-
)
|
|
1369
|
-
|
|
1370
|
-
def getServerSideProps(context):
|
|
1371
|
-
return {
|
|
1372
|
-
"props": {
|
|
1373
|
-
"title": "Welcome to NextPy!",
|
|
1374
|
-
"message": "Build amazing web apps with Python and True JSX"
|
|
1375
|
-
}
|
|
1376
|
-
}
|
|
1377
1375
|
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1376
|
+
return (
|
|
1377
|
+
<div class="flex flex-col items-center justify-between min-h-screen p-8 font-sans antialiased text-black bg-white selection:bg-gray-200">
|
|
1378
|
+
<head>
|
|
1379
|
+
{/* optionally load a stylesheet from public/css <link rel="stylesheet" href="static/css/styles.css" /> */}
|
|
1380
|
+
</head>
|
|
1381
|
+
{/* Top spacer to perfectly center the main content vertically */}
|
|
1382
|
+
<div class=""></div>
|
|
1383
|
+
|
|
1384
|
+
{/* Main Centered Content */}
|
|
1385
|
+
<div class="flex flex-col items-center max-w-xl gap-8 text-center">
|
|
1386
|
+
{/* Logo Section */}
|
|
1387
|
+
<h1 class="text-[56px] font-extrabold tracking-tighter leading-none select-none font-mono flex items-baseline">
|
|
1388
|
+
<img src="static/images/logo.png" alt="NextPy Logo" class="w-auto h-16" />
|
|
1381
1389
|
|
|
1382
|
-
|
|
1383
|
-
(project_dir / "pages" / "about.py").write_text(
|
|
1384
|
-
'''"""Enhanced About page with True JSX"""
|
|
1390
|
+
</h1>
|
|
1385
1391
|
|
|
1386
|
-
|
|
1392
|
+
{/* Step-by-Step Instructions */}
|
|
1393
|
+
<ol class="list-decimal list-inside text-left text-[16px] font-mono text-gray-800 space-y-2.5">
|
|
1394
|
+
<li>
|
|
1395
|
+
Get started by editing
|
|
1396
|
+
<code class="bg-black/[0.05] px-1.5 py-0.5 rounded font-bold text-black text-[13px]">
|
|
1397
|
+
pages/index.py
|
|
1398
|
+
</code>
|
|
1399
|
+
.
|
|
1400
|
+
</li>
|
|
1401
|
+
<li>Save and see your changes instantly.</li>
|
|
1402
|
+
</ol>
|
|
1403
|
+
|
|
1404
|
+
{/* Call To Action Buttons */}
|
|
1405
|
+
<div class="flex flex-col items-center gap-4 mt-2 sm:flex-row">
|
|
1406
|
+
|
|
1407
|
+
<a
|
|
1408
|
+
href="https://nextpy-framework.onrender.com/deploy"
|
|
1409
|
+
class="flex items-center gap-2 bg-black text-white px-6 py-3 rounded-full text-[14px] font-medium transition-colors hover:bg-[#2c2c2c] shadow-sm"
|
|
1410
|
+
|
|
1411
|
+
>
|
|
1412
|
+
<svg
|
|
1413
|
+
class="w-6 h-6"
|
|
1414
|
+
fill="none"
|
|
1415
|
+
stroke="currentColor"
|
|
1416
|
+
stroke-width="2"
|
|
1417
|
+
viewBox="0 0 24 24"
|
|
1418
|
+
>
|
|
1419
|
+
<path
|
|
1420
|
+
stroke-linecap="round"
|
|
1421
|
+
stroke-linejoin="round"
|
|
1422
|
+
d="M7 18a4 4 0 010-8 5 5 0 019.7-1.2A3.5 3.5 0 0117.5 18H7z"
|
|
1423
|
+
/>
|
|
1424
|
+
<path
|
|
1425
|
+
stroke-linecap="round"
|
|
1426
|
+
stroke-linejoin="round"
|
|
1427
|
+
d="M12 14V8m0 0l-3 3m3-3l3 3"
|
|
1428
|
+
/>
|
|
1429
|
+
</svg>
|
|
1430
|
+
|
|
1431
|
+
Deploy now
|
|
1432
|
+
</a>
|
|
1433
|
+
|
|
1434
|
+
<a
|
|
1435
|
+
href="https://nextpy-framework.onrender.com/"
|
|
1436
|
+
class="flex items-center justify-center border border-black/[0.08] bg-white text-black px-6 py-3 rounded-full text-[14px] font-medium transition-colors hover:bg-gray-50 hover:border-black/[0.15] min-w-[140px]"
|
|
1437
|
+
|
|
1438
|
+
>
|
|
1439
|
+
Read our docs
|
|
1440
|
+
</a>
|
|
1441
|
+
</div>
|
|
1442
|
+
|
|
1443
|
+
<div class="flex flex-wrap items-center justify-center gap-x-8 text-[14px] font-medium text-gray-600 w-full max-w-2xl py-4 border-t border-gray-100 sm:border-none">
|
|
1444
|
+
<a
|
|
1445
|
+
href="https://nextpy-framework.onrender.com/learn"
|
|
1446
|
+
class="flex items-center gap-2 transition-colors hover:underline hover:text-black"
|
|
1447
|
+
|
|
1448
|
+
>
|
|
1449
|
+
{/* Document Icon */}
|
|
1450
|
+
<svg class="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
|
1451
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
|
|
1452
|
+
</svg>
|
|
1453
|
+
Learn
|
|
1454
|
+
</a>
|
|
1387
1455
|
|
|
1456
|
+
<a
|
|
1457
|
+
href="https://nextpy-framework.onrender.com/templates"
|
|
1458
|
+
class="flex items-center gap-2 transition-colors hover:underline hover:text-black"
|
|
1459
|
+
|
|
1460
|
+
>
|
|
1461
|
+
{/* Window Layout Icon */}
|
|
1462
|
+
<svg class="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
|
1463
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M4 5a1 1 0 011-1h14a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1V5zm0 7a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H5a1 1 0 01-1-1v-6zm10 0a1 1 0 011-1h4a1 1 0 011 1v6a1 1 0 01-1 1h-4a1 1 0 01-1-1v-6z"/>
|
|
1464
|
+
</svg>
|
|
1465
|
+
Examples
|
|
1466
|
+
</a>
|
|
1388
1467
|
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
<div class="px-4 py-16 mx-auto max-w-7xl sm:py-24 sm:px-6 lg:px-8">
|
|
1401
|
-
<div class="text-center">
|
|
1402
|
-
<h1 class="text-4xl font-extrabold tracking-tight sm:text-5xl lg:text-6xl">
|
|
1403
|
-
{title}
|
|
1404
|
-
</h1>
|
|
1405
|
-
<p class="max-w-2xl mx-auto mt-6 text-xl text-blue-100">
|
|
1406
|
-
{description}
|
|
1407
|
-
</p>
|
|
1408
|
-
<div class="flex justify-center mt-10 space-x-4">
|
|
1409
|
-
<a href="/features" class="inline-flex items-center justify-center px-8 py-3 text-base font-medium text-blue-600 bg-white border border-transparent rounded-md hover:bg-blue-50 md:py-4 md:text-lg md:px-10">
|
|
1410
|
-
Explore Features
|
|
1411
|
-
</a>
|
|
1412
|
-
<a href="/getting-started" class="inline-flex items-center justify-center px-8 py-3 text-base font-medium text-white bg-blue-500 border border-transparent rounded-md hover:bg-blue-600 md:py-4 md:text-lg md:px-10">
|
|
1413
|
-
Get Started
|
|
1414
|
-
</a>
|
|
1415
|
-
</div>
|
|
1416
|
-
</div>
|
|
1468
|
+
<a
|
|
1469
|
+
href="https://nextpy-framework.onrender.com/"
|
|
1470
|
+
class="flex items-center gap-1.5 hover:underline hover:text-black transition-colors"
|
|
1471
|
+
|
|
1472
|
+
>
|
|
1473
|
+
{/* Globe Icon */}
|
|
1474
|
+
<svg class="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
|
1475
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9"/>
|
|
1476
|
+
</svg>
|
|
1477
|
+
Go to nextpy.org →
|
|
1478
|
+
</a>
|
|
1417
1479
|
</div>
|
|
1480
|
+
|
|
1418
1481
|
</div>
|
|
1419
1482
|
|
|
1420
|
-
|
|
1483
|
+
<footer class="flex flex-wrap items-center justify-center text-[14px] font-medium text-gray-600 w-full max-w-2xl py-4 border-t border-gray-100 sm:border-none">
|
|
1484
|
+
The Python Web Framework for Everyone
|
|
1485
|
+
</footer>
|
|
1421
1486
|
</div>
|
|
1422
1487
|
)
|
|
1423
1488
|
|
|
1489
|
+
|
|
1424
1490
|
def getServerSideProps(context):
|
|
1425
1491
|
return {
|
|
1426
1492
|
"props": {
|
|
1427
|
-
"title": "
|
|
1428
|
-
"
|
|
1493
|
+
"title": "Welcome to NextPy!",
|
|
1494
|
+
"message": "Build amazing web apps with Python and True JSX"
|
|
1429
1495
|
}
|
|
1430
1496
|
}
|
|
1431
1497
|
|
|
1432
|
-
default = About
|
|
1433
|
-
'''
|
|
1434
|
-
)
|
|
1435
|
-
click.echo(" Created: pages/about.py (enhanced interactive page)")
|
|
1436
|
-
|
|
1437
|
-
# Create interactive demo pages
|
|
1438
|
-
(project_dir / "pages" / "interactive.py").write_text('''"""Interactive Demo Page"""
|
|
1439
|
-
|
|
1440
|
-
from nextpy.psx import component
|
|
1441
|
-
|
|
1442
1498
|
|
|
1443
|
-
|
|
1444
|
-
def InteractiveDemo(props=None):
|
|
1445
|
-
"""Interactive demo showcasing NextPy capabilities"""
|
|
1446
|
-
return (
|
|
1447
|
-
<div class="min-h-screen py-12 bg-gradient-to-br from-indigo-50 to-purple-100">
|
|
1448
|
-
<div class="px-4 mx-auto max-w-7xl sm:px-6 lg:px-8">
|
|
1449
|
-
<h1 class="mb-12 text-4xl font-extrabold text-center text-gray-900">
|
|
1450
|
-
Interactive NextPy Demos
|
|
1451
|
-
</h1>
|
|
1452
|
-
|
|
1453
|
-
<div class="grid grid-cols-1 gap-8 md:grid-cols-2 lg:grid-cols-3">
|
|
1454
|
-
|
|
1455
|
-
<div class="p-6 bg-white shadow-lg rounded-xl">
|
|
1456
|
-
<h2 class="mb-4 text-2xl font-bold text-gray-900">Live Counter</h2>
|
|
1457
|
-
<div class="text-center">
|
|
1458
|
-
<div class="mb-4 text-6xl font-bold text-blue-600" id="counter">0</div>
|
|
1459
|
-
<div class="space-x-4">
|
|
1460
|
-
<button onclick="updateCounter(-1)" class="px-6 py-3 text-white transition-colors bg-red-500 rounded-lg hover:bg-red-600">
|
|
1461
|
-
-
|
|
1462
|
-
</button>
|
|
1463
|
-
<button onclick="updateCounter(1)" class="px-6 py-3 text-white transition-colors bg-green-500 rounded-lg hover:bg-green-600">
|
|
1464
|
-
+
|
|
1465
|
-
</button>
|
|
1466
|
-
<button onclick="resetCounter()" class="px-6 py-3 text-white transition-colors bg-gray-500 rounded-lg hover:bg-gray-600">
|
|
1467
|
-
Reset
|
|
1468
|
-
</button>
|
|
1469
|
-
</div>
|
|
1470
|
-
</div>
|
|
1471
|
-
</div>
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
<div class="p-6 bg-white shadow-lg rounded-xl">
|
|
1475
|
-
<h2 class="mb-4 text-2xl font-bold text-gray-900">Todo List</h2>
|
|
1476
|
-
<div class="space-y-4">
|
|
1477
|
-
<div class="flex space-x-2">
|
|
1478
|
-
<input type="text" id="todoInput" placeholder="Add a new todo..." class="flex-1 px-4 py-2 border border-gray-300 rounded-lg" />
|
|
1479
|
-
<button onclick="addTodo()" class="px-6 py-2 text-white transition-colors bg-blue-500 rounded-lg hover:bg-blue-600">
|
|
1480
|
-
Add
|
|
1481
|
-
</button>
|
|
1482
|
-
</div>
|
|
1483
|
-
<ul id="todoList" class="space-y-2">
|
|
1484
|
-
|
|
1485
|
-
</ul>
|
|
1486
|
-
</div>
|
|
1487
|
-
</div>
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
<div class="p-6 bg-white shadow-lg rounded-xl">
|
|
1491
|
-
<h2 class="mb-4 text-2xl font-bold text-gray-900">Color Picker</h2>
|
|
1492
|
-
<div class="space-y-4">
|
|
1493
|
-
<input type="color" id="colorPicker" class="w-full h-20 rounded-lg cursor-pointer" />
|
|
1494
|
-
<div id="colorDisplay" class="p-4 font-mono text-lg text-center bg-gray-100 rounded-lg">
|
|
1495
|
-
Selected: #3B82F6
|
|
1496
|
-
</div>
|
|
1497
|
-
</div>
|
|
1498
|
-
</div>
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
<div class="p-6 bg-white shadow-lg rounded-xl">
|
|
1502
|
-
<h2 class="mb-4 text-2xl font-bold text-gray-900">Form Validation</h2>
|
|
1503
|
-
<form onsubmit="validateForm(event)" class="space-y-4">
|
|
1504
|
-
<div>
|
|
1505
|
-
<label class="block mb-2 text-sm font-medium text-gray-700">Email</label>
|
|
1506
|
-
<input type="email" id="email" required class="w-full px-4 py-2 border border-gray-300 rounded-lg" placeholder="you@example.com" />
|
|
1507
|
-
</div>
|
|
1508
|
-
<div>
|
|
1509
|
-
<label class="block mb-2 text-sm font-medium text-gray-700">Password</label>
|
|
1510
|
-
<input type="password" id="password" required minlength="6" class="w-full px-4 py-2 border border-gray-300 rounded-lg" placeholder="•••••••••" />
|
|
1511
|
-
</div>
|
|
1512
|
-
<button type="submit" class="w-full px-6 py-3 text-white transition-colors bg-blue-500 rounded-lg hover:bg-blue-600">
|
|
1513
|
-
Validate & Submit
|
|
1514
|
-
</button>
|
|
1515
|
-
</form>
|
|
1516
|
-
<div id="validationResult" class="hidden p-4 mt-4 rounded-lg">
|
|
1517
|
-
|
|
1518
|
-
</div>
|
|
1519
|
-
</div>
|
|
1520
|
-
</div>
|
|
1521
|
-
</div>
|
|
1522
|
-
</div>
|
|
1523
|
-
)
|
|
1499
|
+
default = Home
|
|
1524
1500
|
|
|
1525
|
-
def getServerSideProps(context):
|
|
1526
|
-
return {"props": {}}
|
|
1527
1501
|
|
|
1528
|
-
default = InteractiveDemo
|
|
1529
1502
|
''')
|
|
1530
|
-
click.echo(" Created: pages/
|
|
1503
|
+
click.echo(" Created: pages/index.py ")
|
|
1504
|
+
|
|
1531
1505
|
|
|
1532
1506
|
(project_dir / "components" / "ui" / "Button.py").write_text(
|
|
1533
1507
|
'''"""Button component"""
|
|
1534
|
-
from nextpy.psx import
|
|
1508
|
+
from nextpy.psx import psx
|
|
1509
|
+
|
|
1535
1510
|
|
|
1536
1511
|
|
|
1537
|
-
@component
|
|
1538
1512
|
def Button(props = None):
|
|
1539
1513
|
"""Reusable Button component"""
|
|
1540
1514
|
props = props or {}
|
|
@@ -1556,14 +1530,14 @@ def Button(props = None):
|
|
|
1556
1530
|
|
|
1557
1531
|
class_attr = f"px-6 py-3 rounded-lg font-medium transition-all duration-200 transform hover:scale-105 {variant_class} {className}"
|
|
1558
1532
|
|
|
1559
|
-
return (
|
|
1533
|
+
return psx(f"
|
|
1560
1534
|
<button class={class_attr}
|
|
1561
1535
|
id={props.get("id")}
|
|
1562
1536
|
disabled={props.get("disabled", False)}
|
|
1563
1537
|
onclick={props.get("onClick", "")}>
|
|
1564
1538
|
{children}
|
|
1565
1539
|
</button>
|
|
1566
|
-
)
|
|
1540
|
+
")
|
|
1567
1541
|
|
|
1568
1542
|
default = Button
|
|
1569
1543
|
'''
|
|
@@ -1613,119 +1587,7 @@ default = Layout
|
|
|
1613
1587
|
)
|
|
1614
1588
|
click.echo(" Created: components/layout/Layout.py")
|
|
1615
1589
|
|
|
1616
|
-
|
|
1617
|
-
(project_dir / ".vscode").mkdir(exist_ok=True)
|
|
1618
|
-
(project_dir / ".vscode" / "settings.json").write_text("""{
|
|
1619
|
-
"files.associations": {
|
|
1620
|
-
"*.py": "python",
|
|
1621
|
-
"*.py.jsx": "python",
|
|
1622
|
-
"*.jsx": "javascriptreact"
|
|
1623
|
-
},
|
|
1624
|
-
"emmet.includeLanguages": {
|
|
1625
|
-
"python": "html",
|
|
1626
|
-
"javascriptreact": "html",
|
|
1627
|
-
"typescriptreact": "html"
|
|
1628
|
-
},
|
|
1629
|
-
"emmet.triggerExpansionOnTab": true,
|
|
1630
|
-
"typescript.preferences.includePackageJsonAutoImports": "on",
|
|
1631
|
-
"editor.quickSuggestions": {
|
|
1632
|
-
"strings": true
|
|
1633
|
-
},
|
|
1634
|
-
"editor.suggestSelection": "first",
|
|
1635
|
-
"editor.wordBasedSuggestions": true,
|
|
1636
|
-
"editor.snippetSuggestions": "top",
|
|
1637
|
-
"editor.parameterHints": {
|
|
1638
|
-
"enabled": true
|
|
1639
|
-
},
|
|
1640
|
-
"editor.snippetSuggestions": "top",
|
|
1641
|
-
"html.autoClosingTags": true,
|
|
1642
|
-
"css.autoClosingTags": true,
|
|
1643
|
-
"javascript.autoClosingTags": true,
|
|
1644
|
-
"typescript.autoClosingTags": true,
|
|
1645
|
-
"editor.autoClosingBrackets": "always",
|
|
1646
|
-
"editor.autoClosingQuotes": "always",
|
|
1647
|
-
"editor.formatOnSave": true,
|
|
1648
|
-
"editor.codeActionsOnSave": {
|
|
1649
|
-
"source.fixAll.eslint": true,
|
|
1650
|
-
"source.organizeImports": true
|
|
1651
|
-
},
|
|
1652
|
-
"emmet.preferences": {
|
|
1653
|
-
"css.property.endWithSemicolon": true,
|
|
1654
|
-
"css.value.unit": "rem"
|
|
1655
|
-
},
|
|
1656
|
-
"files.exclude": {
|
|
1657
|
-
"*}__pycache__": true,
|
|
1658
|
-
"*}*.pyc": true,
|
|
1659
|
-
"*}node_modules": true,
|
|
1660
|
-
"*}out": true,
|
|
1661
|
-
"*}.next": true,
|
|
1662
|
-
"*}.pytest_cache": true,
|
|
1663
|
-
"*}.mypy_cache": true
|
|
1664
|
-
},
|
|
1665
|
-
"search.exclude": {
|
|
1666
|
-
"*}node_modules": true,
|
|
1667
|
-
"*}out": true,
|
|
1668
|
-
"*}.next": true,
|
|
1669
|
-
"*}__pycache__": true,
|
|
1670
|
-
"*}.pytest_cache": true,
|
|
1671
|
-
"*}.mypy_cache": true
|
|
1672
|
-
},
|
|
1673
|
-
"python.linting.enabled": true,
|
|
1674
|
-
"python.linting.pylintEnabled": false,
|
|
1675
|
-
"python.linting.flake8Enabled": false,
|
|
1676
|
-
"python.linting.pylintArgs": [
|
|
1677
|
-
"--disable=C0114,C0115,C0116,E1132,E1131,E1130"
|
|
1678
|
-
],
|
|
1679
|
-
"python.formatting.provider": "black",
|
|
1680
|
-
"[python]": {
|
|
1681
|
-
"editor.defaultFormatter": "ms-python.black-formatter",
|
|
1682
|
-
"editor.formatOnSave": true,
|
|
1683
|
-
"editor.rulers": [88],
|
|
1684
|
-
"editor.tabSize": 4,
|
|
1685
|
-
"editor.insertSpaces": true
|
|
1686
|
-
}
|
|
1687
|
-
}""")
|
|
1688
|
-
click.echo(" Created: .vscode/settings.json")
|
|
1689
|
-
|
|
1690
|
-
(project_dir / ".vscode" / "extensions.json").write_text("""{
|
|
1691
|
-
"recommendations": [
|
|
1692
|
-
"ms-python.python",
|
|
1693
|
-
"ms-python.vscode-pylance",
|
|
1694
|
-
"bradlc.vscode-tailwindcss",
|
|
1695
|
-
"esbenp.prettier-vscode",
|
|
1696
|
-
"ms-vscode.vscode-json",
|
|
1697
|
-
"formulahendry.auto-rename-tag",
|
|
1698
|
-
"christian-kohler.path-intellisense",
|
|
1699
|
-
"ms-vscode.vscode-html-css-class-completion",
|
|
1700
|
-
"ms-vscode.vscode-emmet",
|
|
1701
|
-
"ms-vscode.vscode-eslint",
|
|
1702
|
-
"dbaeumer.vscode-eslint",
|
|
1703
|
-
"ms-vscode.vscode-typescript-next",
|
|
1704
|
-
"ritwickdey.liveserver",
|
|
1705
|
-
"ms-vscode.vscode-jest",
|
|
1706
|
-
"esbenp.prettier-vscode",
|
|
1707
|
-
"streetsidesoftware.code-spell-checker",
|
|
1708
|
-
"gruntfuggly.todo-tree",
|
|
1709
|
-
"ms-vscode.vscode-git-graph",
|
|
1710
|
-
"eamodio.gitlens",
|
|
1711
|
-
"ms-vscode.vscode-docker",
|
|
1712
|
-
"ms-vscode.remote-explorer",
|
|
1713
|
-
"ms-vscode-remote.remote-containers",
|
|
1714
|
-
"ms-vscode.vscode-remote-wsl",
|
|
1715
|
-
"redhat.vscode-yaml",
|
|
1716
|
-
"ms-vscode.vscode-markdown",
|
|
1717
|
-
"yzhang.markdown-all-in-one",
|
|
1718
|
-
"shd101wyy.markdown-preview-enhanced",
|
|
1719
|
-
"ms-vscode.vscode-python",
|
|
1720
|
-
"kevinrose.vsc-python-indent",
|
|
1721
|
-
"ms-python.black-formatter",
|
|
1722
|
-
"ms-python.isort",
|
|
1723
|
-
"ms-python.flake8",
|
|
1724
|
-
"ms-python.mypy-type-checker"
|
|
1725
|
-
]
|
|
1726
|
-
}""")
|
|
1727
|
-
click.echo(" Created: .vscode/extensions.json")
|
|
1728
|
-
|
|
1590
|
+
|
|
1729
1591
|
# Create comprehensive API examples
|
|
1730
1592
|
(project_dir / "pages" / "api" / "hello.py").write_text(
|
|
1731
1593
|
'''"""API example - Hello endpoint"""
|
|
@@ -2208,77 +2070,6 @@ Thumbs.db
|
|
|
2208
2070
|
''')
|
|
2209
2071
|
click.echo(" Created: .gitignore")
|
|
2210
2072
|
|
|
2211
|
-
# Create main.py with Tailwind compilation (for pip-installed NextPy)
|
|
2212
|
-
(project_dir / "main.py").write_text('''"""NextPy ASGI Application Entry Point"""
|
|
2213
|
-
|
|
2214
|
-
import os
|
|
2215
|
-
import sys
|
|
2216
|
-
import subprocess
|
|
2217
|
-
from pathlib import Path
|
|
2218
|
-
|
|
2219
|
-
try:
|
|
2220
|
-
print("Compiling Tailwind CSS...")
|
|
2221
|
-
proj_root = Path.cwd()
|
|
2222
|
-
framework_dir = Path(__file__).parent
|
|
2223
|
-
# If the project root doesn't have a styles.css yet, warn the user and create a minimal one.
|
|
2224
|
-
styles_file = proj_root / "styles.css"
|
|
2225
|
-
if not styles_file.exists():
|
|
2226
|
-
print("Warning: styles.css not found, creating a minimal file.")
|
|
2227
|
-
styles_file.write_text("@tailwind base;\n@tailwind components;\n@tailwind utilities;\n")
|
|
2228
|
-
|
|
2229
|
-
import shutil
|
|
2230
|
-
npm_bin = shutil.which("npm")
|
|
2231
|
-
if not npm_bin:
|
|
2232
|
-
raise FileNotFoundError("npm not found on PATH")
|
|
2233
|
-
|
|
2234
|
-
lockfile = framework_dir / "package-lock.json"
|
|
2235
|
-
node_modules = framework_dir / "node_modules"
|
|
2236
|
-
if not node_modules.exists():
|
|
2237
|
-
if lockfile.exists():
|
|
2238
|
-
subprocess.run([npm_bin, "ci"], cwd=str(framework_dir), check=True)
|
|
2239
|
-
else:
|
|
2240
|
-
subprocess.run([npm_bin, "install"], cwd=str(framework_dir), check=True)
|
|
2241
|
-
|
|
2242
|
-
subprocess.run([npm_bin, "run", "build:tailwind"], cwd=str(framework_dir), check=True)
|
|
2243
|
-
print("Tailwind CSS compiled successfully.")
|
|
2244
|
-
except subprocess.CalledProcessError as e:
|
|
2245
|
-
print(f"Error compiling Tailwind CSS: {e}")
|
|
2246
|
-
print("You can also run `cd .nextpy_framework/nextpy && npm ci && npm run build:tailwind` manually.")
|
|
2247
|
-
except FileNotFoundError:
|
|
2248
|
-
print("Error: npm not found. Make sure Node.js is installed and available on PATH.")
|
|
2249
|
-
print("See https://nodejs.org/ for installation instructions.")
|
|
2250
|
-
|
|
2251
|
-
# Import NextPy modules (works when installed via pip)
|
|
2252
|
-
from nextpy.server.app import create_app
|
|
2253
|
-
from nextpy.db import init_db
|
|
2254
|
-
from nextpy.config import settings
|
|
2255
|
-
|
|
2256
|
-
# Initialize database
|
|
2257
|
-
try:
|
|
2258
|
-
init_db(settings["database_url"])
|
|
2259
|
-
print("Database initialized successfully.")
|
|
2260
|
-
except Exception as e:
|
|
2261
|
-
print(f"Warning: Database initialization failed: {e}")
|
|
2262
|
-
|
|
2263
|
-
# Create NextPy app with file-based routing
|
|
2264
|
-
app = create_app(
|
|
2265
|
-
pages_dir="pages",
|
|
2266
|
-
templates_dir="templates",
|
|
2267
|
-
public_dir="public",
|
|
2268
|
-
out_dir="out",
|
|
2269
|
-
debug=settings["debug"],
|
|
2270
|
-
)
|
|
2271
|
-
|
|
2272
|
-
# Note: Routes are automatically loaded from pages/ directory
|
|
2273
|
-
# - / -> pages/index.py
|
|
2274
|
-
# - /about -> pages/about.py
|
|
2275
|
-
# - /api/* -> pages/api/*.py
|
|
2276
|
-
|
|
2277
|
-
if __name__ == "__main__":
|
|
2278
|
-
import uvicorn
|
|
2279
|
-
uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)
|
|
2280
|
-
''')
|
|
2281
|
-
click.echo(" Created: main.py (pip-compatible)")
|
|
2282
2073
|
|
|
2283
2074
|
# Create .env file for development
|
|
2284
2075
|
(project_dir / ".env").write_text("""# NextPy Development Environment
|