dars-framework 1.9.5__tar.gz → 1.9.7__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.
- {dars_framework-1.9.5 → dars_framework-1.9.7}/MANIFEST.in +1 -0
- {dars_framework-1.9.5/dars_framework.egg-info → dars_framework-1.9.7}/PKG-INFO +29 -6
- {dars_framework-1.9.5 → dars_framework-1.9.7}/README.md +28 -5
- dars_framework-1.9.7/dars/cli/generate.py +288 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/cli/main.py +132 -30
- dars_framework-1.9.7/dars/cli/prompts.py +68 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/button.py +1 -1
- dars_framework-1.9.7/dars/docs/index.md +5 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/exporters/web/html_css_js.py +222 -17
- dars_framework-1.9.7/dars/exporters/web/resources/anim.js +317 -0
- dars_framework-1.9.7/dars/exporters/web/resources/dap.js +417 -0
- dars_framework-1.9.7/dars/exporters/web/resources/dars.min.js +1110 -0
- dars_framework-1.9.7/dars/exporters/web/resources/dompurify.js +2633 -0
- dars_framework-1.9.7/dars/exporters/web/resources/router.js +821 -0
- dars_framework-1.9.7/dars/exporters/web/resources/ssr.js +246 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/version.py +2 -2
- {dars_framework-1.9.5 → dars_framework-1.9.7/dars_framework.egg-info}/PKG-INFO +29 -6
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars_framework.egg-info/SOURCES.txt +8 -20
- {dars_framework-1.9.5 → dars_framework-1.9.7}/pyproject.toml +1 -1
- dars_framework-1.9.5/dars/docs/INSTALL.md +0 -164
- dars_framework-1.9.5/dars/docs/KeyEvents.md +0 -492
- dars_framework-1.9.5/dars/docs/animations.md +0 -199
- dars_framework-1.9.5/dars/docs/app.md +0 -344
- dars_framework-1.9.5/dars/docs/backend_api.md +0 -363
- dars_framework-1.9.5/dars/docs/cli.md +0 -130
- dars_framework-1.9.5/dars/docs/components.md +0 -405
- dars_framework-1.9.5/dars/docs/config.md +0 -109
- dars_framework-1.9.5/dars/docs/custom_components.md +0 -288
- dars_framework-1.9.5/dars/docs/env.md +0 -58
- dars_framework-1.9.5/dars/docs/events.md +0 -114
- dars_framework-1.9.5/dars/docs/exporters.md +0 -322
- dars_framework-1.9.5/dars/docs/getting_started.md +0 -96
- dars_framework-1.9.5/dars/docs/hooks.md +0 -1335
- dars_framework-1.9.5/dars/docs/index.md +0 -52
- dars_framework-1.9.5/dars/docs/operations.md +0 -471
- dars_framework-1.9.5/dars/docs/routing.md +0 -337
- dars_framework-1.9.5/dars/docs/scripts.md +0 -155
- dars_framework-1.9.5/dars/docs/ssr.md +0 -448
- dars_framework-1.9.5/dars/docs/state_management.md +0 -334
- dars_framework-1.9.5/dars/docs/styling.md +0 -499
- {dars_framework-1.9.5 → dars_framework-1.9.7}/Dars-logo.png +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/LICENSE +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/__init__.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/actionProtocol.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/all.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/backend/__init__.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/backend/components.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/backend/data.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/backend/http.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/backend/json_utils.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/backend/route_loader.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/backend/ssr.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/cli/__init__.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/cli/doctor/__init__.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/cli/doctor/detect.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/cli/doctor/doctor.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/cli/doctor/installers.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/cli/doctor/persist.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/cli/doctor/preflight.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/cli/doctor/ui.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/cli/dpm.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/cli/hot_reload.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/cli/preview.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/cli/translations.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/__init__.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/advanced/__init__.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/advanced/accordion.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/advanced/card.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/advanced/file_upload.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/advanced/head.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/advanced/modal.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/advanced/navbar.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/advanced/outlet.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/advanced/table.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/advanced/tabs.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/__init__.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/audio.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/checkbox.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/container.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/datepicker.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/image.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/input.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/link.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/markdown.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/page.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/progressbar.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/radiobutton.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/section.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/select.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/slider.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/spinner.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/text.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/textarea.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/tooltip.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/video.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/layout/__init__.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/layout/anchor.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/layout/flex.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/layout/grid.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/visualization/__init__.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/visualization/chart.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/visualization/table.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/config.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/core/__init__.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/core/app.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/core/component.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/core/events.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/core/js_bridge.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/core/properties.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/core/route_types.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/core/routing.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/core/state.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/core/state_v2.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/core/utilities.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/dars_tests/apps_test/health_check.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/dars_tests/run_tests.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/dars_tests/tests/test_advanced_components.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/dars_tests/tests/test_basic_components.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/dars_tests/tests/test_core_and_cli.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/dars_tests/tests/test_layout_components.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/dars_tests/tests/test_version_check.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/desktop/__init__.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/desktop/api.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/desktop/js_generator.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/docs/__init__.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/env.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/exporters/__init__.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/exporters/base.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/exporters/desktop/electron.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/exporters/web/__init__.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/exporters/web/vdom.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/hooks/__init__.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/hooks/form_helpers.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/hooks/set_vref.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/hooks/update_vref.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/hooks/use_dynamic.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/hooks/use_value.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/hooks/use_vref.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/hooks/use_watch.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/hooks/value_helpers.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/scripts/__init__.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/scripts/animations.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/scripts/dscript.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/scripts/keycode.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/scripts/script.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/scripts/utils_ds.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/security.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/__init__.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/desktop/icon.png +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/desktop/template/backend/icons/icon.png +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/desktop/template/backend/main.js +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/desktop/template/backend/package.json +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/desktop/template/backend/preload.js +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/desktop/template/dars.config.json +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/desktop/template/icons/icon.png +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/desktop/template/main.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/desktop/template/public/electron-icon.png +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/desktop/template/public/icon.png +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/README.md +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/advanced/CustomComp/main.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/advanced/Modal_Demo/advanced_modal_demo.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/advanced/StateV2/README.md +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/advanced/StateV2/animation_component.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/advanced/StateV2/counter_component.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/advanced/StateV2/hero_component.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/advanced/StateV2/main.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/advanced/StateV2/styles.css +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/advanced/StateV2/timer_component.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/advanced/VariousComponents/all_components_demo.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/advanced/__init__.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/advanced/dState/state_mods_demo.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/advanced/hooks/useDynamic.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/advanced/hooks/useValue.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/advanced/hooks/useWatch.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/basic/HelloWorld/hello_world.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/basic/Layouts/flex_layout_responsive.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/basic/Layouts/grid_layout_responsive.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/basic/Layouts/layout_multipage_demo.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/basic/PWA/icon-192x192.png +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/basic/PWA/icon-512x512.png +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/basic/PWA/pwa_custom_icons.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/basic/__init__.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/markdown/MarkdownTemplate/README.md +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/markdown/MarkdownTemplate/markdown_template.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/markdown/MarkdownTemplate/other_docs.md +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/markdown/__init__.py +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars_framework.egg-info/dependency_links.txt +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars_framework.egg-info/entry_points.txt +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars_framework.egg-info/requires.txt +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/dars_framework.egg-info/top_level.txt +0 -0
- {dars_framework-1.9.5 → dars_framework-1.9.7}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dars-framework
|
|
3
|
-
Version: 1.9.
|
|
3
|
+
Version: 1.9.7
|
|
4
4
|
Summary: Dars is a Full-Stack multiplatform Python UI framework for building modern, interactive web and desktop apps with Python code. Seamlessly integrated with FastAPI, it allows you to build complete applications with Server-Side Rendering (SSR) and reactive SPA capabilities also classic multipage html and desktop apps in a single codebase.
|
|
5
5
|
Author-email: ztamdev <ztadevs@gmail.com>
|
|
6
6
|
Maintainer-email: ztamdev <ztadevs@gmail.com>
|
|
@@ -480,7 +480,8 @@ For complete documentation, see the [Backend API Guide](https://ztamdev.github.i
|
|
|
480
480
|
| `dars init --type desktop` | Scaffold desktop-capable project (BETA) |
|
|
481
481
|
| `dars init --type ssr` | Scaffold full-stack SSR project (SSR + API) |
|
|
482
482
|
| `dars build` (desktop config) | Build desktop app artifacts (BETA) |
|
|
483
|
-
| `dars preview
|
|
483
|
+
| `dars preview` | Preview exported app (auto-detects output) |
|
|
484
|
+
| `dars preview --port 9000` | Preview on a custom port |
|
|
484
485
|
| `dars init my_project` | Create a new Dars project (also creates dars.config.json) |
|
|
485
486
|
| `dars init --update` | Create/Update dars.config.json in current dir |
|
|
486
487
|
| `dars build` | Build using dars.config.json (entry/outdir/format) |
|
|
@@ -490,6 +491,8 @@ For complete documentation, see the [Backend API Guide](https://ztamdev.github.i
|
|
|
490
491
|
| `dars dev` | Run the configured entry file with hot preview (app.rTimeCompile) |
|
|
491
492
|
| `dars dev --port 9000` | Run dev server on a custom port (overrides config) |
|
|
492
493
|
| `dars dev --backend` | Run only the configured backendEntry (FastAPI/SSR backend) |
|
|
494
|
+
| `dars generate component <name>` | Scaffold a new FunctionComponent |
|
|
495
|
+
| `dars generate page <name>` | Scaffold a new page (static or SPA) |
|
|
493
496
|
| `dars --help` | Show help and all CLI options |
|
|
494
497
|
|
|
495
498
|
Tip: use `dars doctor` to review optional tooling that can enhance bundling/minification.
|
|
@@ -501,6 +504,22 @@ Tip: use `dars doctor` to review optional tooling that can enhance bundling/mini
|
|
|
501
504
|
- Build with `dars build` to produce desktop artifacts under `dist/`.
|
|
502
505
|
- This feature is in BETA: usable for testing, not yet recommended for production.
|
|
503
506
|
|
|
507
|
+
### Code Generation
|
|
508
|
+
|
|
509
|
+
Scaffold new components and pages instantly with automatic project integration.
|
|
510
|
+
|
|
511
|
+
```bash
|
|
512
|
+
# Generate a new FunctionComponent
|
|
513
|
+
dars generate component MyComponent
|
|
514
|
+
|
|
515
|
+
# Generate a new Page (Static, SPA or SSR)
|
|
516
|
+
dars generate page About --page-type spa
|
|
517
|
+
dars generate page Dashboard --page-type ssr
|
|
518
|
+
|
|
519
|
+
# Scaffold and auto-inject into your main.py file
|
|
520
|
+
dars generate page Contact --yes
|
|
521
|
+
```
|
|
522
|
+
|
|
504
523
|
---
|
|
505
524
|
|
|
506
525
|
- Visit dars [official website](https://ztamdev.github.io/Dars-Framework/)
|
|
@@ -530,13 +549,17 @@ python my_app.py --port 8088
|
|
|
530
549
|
|
|
531
550
|
---
|
|
532
551
|
|
|
533
|
-
You can also use the CLI preview command on an exported app:
|
|
552
|
+
You can also use the CLI preview command on an exported app. Starting from v1.9.6, the path is optional and will be automatically detected from your `dars.config.json` (defaults to `./dist`):
|
|
534
553
|
|
|
535
554
|
```bash
|
|
536
|
-
|
|
555
|
+
# Auto-detects output directory and port from config
|
|
556
|
+
dars preview
|
|
557
|
+
|
|
558
|
+
# Or specify a custom path and port
|
|
559
|
+
dars preview ./my_exported_app -p 8080
|
|
537
560
|
```
|
|
538
561
|
|
|
539
|
-
This will start a local server at http://localhost:8000 to view your exported app in the browser.
|
|
562
|
+
This will start a local server at the configured port (defaults to http://localhost:8000) to view your exported app in the browser.
|
|
540
563
|
|
|
541
564
|
---
|
|
542
565
|
|
|
@@ -576,7 +599,7 @@ Example default:
|
|
|
576
599
|
- `utility_styles`: Dictionary defining custom utility classes. Keys are class names, values are lists of utility strings or raw CSS properties.
|
|
577
600
|
- `markdownHighlight`: Auto-inject a client-side syntax highlighter for fenced code blocks in Markdown. Default `true`.
|
|
578
601
|
- `backendEntry`: Python import path for your SSR/backend app (e.g. `"backend.api:app"`). Required when your app uses `RouteType.SSR` routes. Used by `dars dev --backend`.
|
|
579
|
-
- `port`: The port for the development preview server. Default `8000`.
|
|
602
|
+
- `port`: The port for the development preview server. Default `8000`. This port is used by `dars dev`, `python app.py` (rTimeCompile), and `dars preview`.
|
|
580
603
|
|
|
581
604
|
Validate your config:
|
|
582
605
|
|
|
@@ -439,7 +439,8 @@ For complete documentation, see the [Backend API Guide](https://ztamdev.github.i
|
|
|
439
439
|
| `dars init --type desktop` | Scaffold desktop-capable project (BETA) |
|
|
440
440
|
| `dars init --type ssr` | Scaffold full-stack SSR project (SSR + API) |
|
|
441
441
|
| `dars build` (desktop config) | Build desktop app artifacts (BETA) |
|
|
442
|
-
| `dars preview
|
|
442
|
+
| `dars preview` | Preview exported app (auto-detects output) |
|
|
443
|
+
| `dars preview --port 9000` | Preview on a custom port |
|
|
443
444
|
| `dars init my_project` | Create a new Dars project (also creates dars.config.json) |
|
|
444
445
|
| `dars init --update` | Create/Update dars.config.json in current dir |
|
|
445
446
|
| `dars build` | Build using dars.config.json (entry/outdir/format) |
|
|
@@ -449,6 +450,8 @@ For complete documentation, see the [Backend API Guide](https://ztamdev.github.i
|
|
|
449
450
|
| `dars dev` | Run the configured entry file with hot preview (app.rTimeCompile) |
|
|
450
451
|
| `dars dev --port 9000` | Run dev server on a custom port (overrides config) |
|
|
451
452
|
| `dars dev --backend` | Run only the configured backendEntry (FastAPI/SSR backend) |
|
|
453
|
+
| `dars generate component <name>` | Scaffold a new FunctionComponent |
|
|
454
|
+
| `dars generate page <name>` | Scaffold a new page (static or SPA) |
|
|
452
455
|
| `dars --help` | Show help and all CLI options |
|
|
453
456
|
|
|
454
457
|
Tip: use `dars doctor` to review optional tooling that can enhance bundling/minification.
|
|
@@ -460,6 +463,22 @@ Tip: use `dars doctor` to review optional tooling that can enhance bundling/mini
|
|
|
460
463
|
- Build with `dars build` to produce desktop artifacts under `dist/`.
|
|
461
464
|
- This feature is in BETA: usable for testing, not yet recommended for production.
|
|
462
465
|
|
|
466
|
+
### Code Generation
|
|
467
|
+
|
|
468
|
+
Scaffold new components and pages instantly with automatic project integration.
|
|
469
|
+
|
|
470
|
+
```bash
|
|
471
|
+
# Generate a new FunctionComponent
|
|
472
|
+
dars generate component MyComponent
|
|
473
|
+
|
|
474
|
+
# Generate a new Page (Static, SPA or SSR)
|
|
475
|
+
dars generate page About --page-type spa
|
|
476
|
+
dars generate page Dashboard --page-type ssr
|
|
477
|
+
|
|
478
|
+
# Scaffold and auto-inject into your main.py file
|
|
479
|
+
dars generate page Contact --yes
|
|
480
|
+
```
|
|
481
|
+
|
|
463
482
|
---
|
|
464
483
|
|
|
465
484
|
- Visit dars [official website](https://ztamdev.github.io/Dars-Framework/)
|
|
@@ -489,13 +508,17 @@ python my_app.py --port 8088
|
|
|
489
508
|
|
|
490
509
|
---
|
|
491
510
|
|
|
492
|
-
You can also use the CLI preview command on an exported app:
|
|
511
|
+
You can also use the CLI preview command on an exported app. Starting from v1.9.6, the path is optional and will be automatically detected from your `dars.config.json` (defaults to `./dist`):
|
|
493
512
|
|
|
494
513
|
```bash
|
|
495
|
-
|
|
514
|
+
# Auto-detects output directory and port from config
|
|
515
|
+
dars preview
|
|
516
|
+
|
|
517
|
+
# Or specify a custom path and port
|
|
518
|
+
dars preview ./my_exported_app -p 8080
|
|
496
519
|
```
|
|
497
520
|
|
|
498
|
-
This will start a local server at http://localhost:8000 to view your exported app in the browser.
|
|
521
|
+
This will start a local server at the configured port (defaults to http://localhost:8000) to view your exported app in the browser.
|
|
499
522
|
|
|
500
523
|
---
|
|
501
524
|
|
|
@@ -535,7 +558,7 @@ Example default:
|
|
|
535
558
|
- `utility_styles`: Dictionary defining custom utility classes. Keys are class names, values are lists of utility strings or raw CSS properties.
|
|
536
559
|
- `markdownHighlight`: Auto-inject a client-side syntax highlighter for fenced code blocks in Markdown. Default `true`.
|
|
537
560
|
- `backendEntry`: Python import path for your SSR/backend app (e.g. `"backend.api:app"`). Required when your app uses `RouteType.SSR` routes. Used by `dars dev --backend`.
|
|
538
|
-
- `port`: The port for the development preview server. Default `8000`.
|
|
561
|
+
- `port`: The port for the development preview server. Default `8000`. This port is used by `dars dev`, `python app.py` (rTimeCompile), and `dars preview`.
|
|
539
562
|
|
|
540
563
|
Validate your config:
|
|
541
564
|
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import re
|
|
3
|
+
from rich.console import Console
|
|
4
|
+
from rich.prompt import Prompt, Confirm
|
|
5
|
+
from dars.cli.prompts import select_prompt, confirm_prompt
|
|
6
|
+
|
|
7
|
+
API_CONFIG_PY_CODE = """import os
|
|
8
|
+
import sys
|
|
9
|
+
|
|
10
|
+
class DarsEnv:
|
|
11
|
+
# Set this to "production" when deploying
|
|
12
|
+
MODE = "development"
|
|
13
|
+
|
|
14
|
+
DEV = "development"
|
|
15
|
+
BUILD = "production"
|
|
16
|
+
|
|
17
|
+
@staticmethod
|
|
18
|
+
def get_env():
|
|
19
|
+
return DarsEnv.MODE
|
|
20
|
+
|
|
21
|
+
@staticmethod
|
|
22
|
+
def is_dev():
|
|
23
|
+
return DarsEnv.get_env() == DarsEnv.DEV
|
|
24
|
+
|
|
25
|
+
@staticmethod
|
|
26
|
+
def get_urls():
|
|
27
|
+
# Configuration for URLs
|
|
28
|
+
if DarsEnv.is_dev():
|
|
29
|
+
return {
|
|
30
|
+
"backend": "http://localhost:3000", # SSR/API Server
|
|
31
|
+
"frontend": "http://localhost:8000" # Dev Server
|
|
32
|
+
}
|
|
33
|
+
return {
|
|
34
|
+
"backend": "/", # Production: Same origin
|
|
35
|
+
"frontend": "/"
|
|
36
|
+
}
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
API_PY_CODE = """\"""
|
|
40
|
+
SSR Backend - Dars Framework
|
|
41
|
+
Run with: python -m backend.api
|
|
42
|
+
\"""
|
|
43
|
+
from fastapi import FastAPI
|
|
44
|
+
from fastapi.middleware.cors import CORSMiddleware
|
|
45
|
+
from dars.backend.ssr import create_ssr_app
|
|
46
|
+
import sys
|
|
47
|
+
import os
|
|
48
|
+
from backend.apiConfig import DarsEnv
|
|
49
|
+
|
|
50
|
+
# Import the Dars app
|
|
51
|
+
import sys
|
|
52
|
+
sys.path.insert(0, '.')
|
|
53
|
+
from main import app as dars_app
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
# Create FastAPI app with SSR support
|
|
57
|
+
app = create_ssr_app(dars_app)
|
|
58
|
+
|
|
59
|
+
# Enable CORS for local development
|
|
60
|
+
if DarsEnv.is_dev():
|
|
61
|
+
urls = DarsEnv.get_urls()
|
|
62
|
+
app.add_middleware(
|
|
63
|
+
CORSMiddleware,
|
|
64
|
+
allow_origins=[urls['frontend'], "http://127.0.0.1:3000"],
|
|
65
|
+
allow_credentials=True,
|
|
66
|
+
allow_methods=["*"],
|
|
67
|
+
allow_headers=["*"],
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
if __name__ == "__main__":
|
|
71
|
+
import uvicorn
|
|
72
|
+
urls = DarsEnv.get_urls()
|
|
73
|
+
print(" " + "="*60)
|
|
74
|
+
print("Dars SSR Backend")
|
|
75
|
+
print("="*60)
|
|
76
|
+
print(f"Endpoints:")
|
|
77
|
+
print(f" • {urls['backend']}/ - API info")
|
|
78
|
+
print(f" • {urls['backend']}/api/ssr/* - SSR routes")
|
|
79
|
+
print(f"Frontend: {urls['frontend']}")
|
|
80
|
+
print("="*60 + " ")
|
|
81
|
+
|
|
82
|
+
uvicorn.run(app, host="127.0.0.1", port=3000)
|
|
83
|
+
"""
|
|
84
|
+
|
|
85
|
+
console = Console()
|
|
86
|
+
|
|
87
|
+
def handle_generate(args):
|
|
88
|
+
gen_type = args.type
|
|
89
|
+
if not gen_type:
|
|
90
|
+
gen_type = select_prompt("What do you want to generate?", choices=["component", "page"])
|
|
91
|
+
|
|
92
|
+
name = args.name
|
|
93
|
+
if not name:
|
|
94
|
+
while True:
|
|
95
|
+
name = Prompt.ask(f"Enter the name of the {gen_type}")
|
|
96
|
+
if name and name.strip():
|
|
97
|
+
break
|
|
98
|
+
console.print(f"[red]Error: {gen_type.capitalize()} name cannot be empty.[/red]")
|
|
99
|
+
|
|
100
|
+
# Ensure it's a valid python identifier
|
|
101
|
+
safe_name = re.sub(r'[^a-zA-Z0-9_]', '_', name)
|
|
102
|
+
# Avoid python keywords or starting with numbers
|
|
103
|
+
if safe_name and safe_name[0].isdigit():
|
|
104
|
+
safe_name = "_" + safe_name
|
|
105
|
+
|
|
106
|
+
if gen_type == "component":
|
|
107
|
+
os.makedirs("components", exist_ok=True)
|
|
108
|
+
file_path = f"components/{name}.py"
|
|
109
|
+
if os.path.exists(file_path):
|
|
110
|
+
console.print(f"[red]Error: Component {file_path} already exists.[/red]")
|
|
111
|
+
return
|
|
112
|
+
|
|
113
|
+
content = f"""from dars.all import *
|
|
114
|
+
|
|
115
|
+
@FunctionComponent
|
|
116
|
+
def {safe_name}(props):
|
|
117
|
+
return Container(
|
|
118
|
+
Text("{name} Component works!")
|
|
119
|
+
)
|
|
120
|
+
"""
|
|
121
|
+
with open(file_path, "w") as f:
|
|
122
|
+
f.write(content)
|
|
123
|
+
console.print(f"[green]SUCCESS: Component {name} generated successfully at {file_path}[/green]")
|
|
124
|
+
console.print("[yellow]Note: Remember to import and use it in your main application.[/yellow]")
|
|
125
|
+
|
|
126
|
+
elif gen_type == "page":
|
|
127
|
+
page_type = args.page_type
|
|
128
|
+
if not page_type:
|
|
129
|
+
page_type = select_prompt(f"What type of page is '{name}'?", choices=["static", "spa", "ssr"])
|
|
130
|
+
|
|
131
|
+
os.makedirs("pages", exist_ok=True)
|
|
132
|
+
file_path = f"pages/{name}.py"
|
|
133
|
+
if os.path.exists(file_path):
|
|
134
|
+
console.print(f"[red]Error: Page {file_path} already exists.[/red]")
|
|
135
|
+
return
|
|
136
|
+
|
|
137
|
+
if page_type == "static":
|
|
138
|
+
content = f"""from dars.all import *
|
|
139
|
+
|
|
140
|
+
{safe_name} = Page(
|
|
141
|
+
Container(
|
|
142
|
+
Text("{name} Static Page works!")
|
|
143
|
+
)
|
|
144
|
+
)
|
|
145
|
+
"""
|
|
146
|
+
import_statement = f"from pages.{name} import {safe_name}"
|
|
147
|
+
inject_statement = f"app.add_page('{name}', {safe_name})"
|
|
148
|
+
elif page_type == "spa":
|
|
149
|
+
content = f"""from dars.all import *
|
|
150
|
+
|
|
151
|
+
@route("/{name}")
|
|
152
|
+
def {safe_name}():
|
|
153
|
+
return Page(
|
|
154
|
+
Container(
|
|
155
|
+
Text("{name} SPA Page works!")
|
|
156
|
+
)
|
|
157
|
+
)
|
|
158
|
+
"""
|
|
159
|
+
import_statement = f"from pages.{name} import {safe_name}"
|
|
160
|
+
inject_statement = f"app.add_page('{name}', {safe_name}())"
|
|
161
|
+
else: # ssr
|
|
162
|
+
content = f"""from dars.all import *
|
|
163
|
+
|
|
164
|
+
@route("/{name}", route_type=RouteType.SSR)
|
|
165
|
+
def {safe_name}():
|
|
166
|
+
return Page(
|
|
167
|
+
Container(
|
|
168
|
+
Text("{name} SSR Page works!")
|
|
169
|
+
)
|
|
170
|
+
)
|
|
171
|
+
"""
|
|
172
|
+
import_statement = f"from pages.{name} import {safe_name}"
|
|
173
|
+
inject_statement = f"app.add_page('{name}', {safe_name}())"
|
|
174
|
+
|
|
175
|
+
# Check for backend files
|
|
176
|
+
if not os.path.exists("backend"):
|
|
177
|
+
console.print("\n[bold yellow]⚠ WARNING: SSR routes require a backend configuration.[/bold yellow]")
|
|
178
|
+
console.print("[yellow]It seems your project doesn't have the '/backend' directory required for Dars SSR.[/yellow]")
|
|
179
|
+
|
|
180
|
+
if confirm_prompt("Do you want to automatically scaffold the SSR backend now?"):
|
|
181
|
+
os.makedirs("backend", exist_ok=True)
|
|
182
|
+
with open("backend/__init__.py", "w") as f: pass
|
|
183
|
+
|
|
184
|
+
with open("backend/apiConfig.py", "w") as f:
|
|
185
|
+
f.write(API_CONFIG_PY_CODE.strip())
|
|
186
|
+
|
|
187
|
+
with open("backend/api.py", "w") as f:
|
|
188
|
+
f.write(API_PY_CODE.strip())
|
|
189
|
+
|
|
190
|
+
# Update config
|
|
191
|
+
if os.path.exists("dars.config.json"):
|
|
192
|
+
import json
|
|
193
|
+
try:
|
|
194
|
+
with open("dars.config.json", "r") as f:
|
|
195
|
+
config = json.load(f)
|
|
196
|
+
if "backendEntry" not in config:
|
|
197
|
+
config["backendEntry"] = "backend.api:app"
|
|
198
|
+
with open("dars.config.json", "w") as f:
|
|
199
|
+
json.dump(config, f, indent=2)
|
|
200
|
+
console.print("[green]SUCCESS: Updated dars.config.json with backendEntry.[/green]")
|
|
201
|
+
except:
|
|
202
|
+
pass
|
|
203
|
+
|
|
204
|
+
console.print("[green]SUCCESS: SSR Backend scaffolded at /backend[/green]")
|
|
205
|
+
console.print("[yellow]Note: Remember to run 'dars dev --backend' to start the SSR server.[/yellow]")
|
|
206
|
+
|
|
207
|
+
with open(file_path, "w") as f:
|
|
208
|
+
f.write(content)
|
|
209
|
+
console.print(f"[green]SUCCESS: Page {name} generated successfully at {file_path}[/green]")
|
|
210
|
+
|
|
211
|
+
# Inject to main.py
|
|
212
|
+
auto_inject = args.yes
|
|
213
|
+
if not auto_inject:
|
|
214
|
+
auto_inject = confirm_prompt(f"Do you want to automatically add this page to your main app file?")
|
|
215
|
+
|
|
216
|
+
if auto_inject:
|
|
217
|
+
entry_file = "main.py"
|
|
218
|
+
if os.path.exists("dars.config.json"):
|
|
219
|
+
import json
|
|
220
|
+
try:
|
|
221
|
+
with open("dars.config.json", "r") as f:
|
|
222
|
+
config = json.load(f)
|
|
223
|
+
entry_file = config.get("entry", "main.py")
|
|
224
|
+
except:
|
|
225
|
+
pass
|
|
226
|
+
|
|
227
|
+
if not os.path.exists(entry_file):
|
|
228
|
+
if os.path.exists("index.py"):
|
|
229
|
+
entry_file = "index.py"
|
|
230
|
+
else:
|
|
231
|
+
console.print(f"[red]Error: Could not find main application file ({entry_file}). Please add the page manually.[/red]")
|
|
232
|
+
console.print(f"[cyan]{import_statement}[/cyan]")
|
|
233
|
+
console.print(f"[cyan]{inject_statement}[/cyan]")
|
|
234
|
+
return
|
|
235
|
+
|
|
236
|
+
try:
|
|
237
|
+
with open(entry_file, "r") as f:
|
|
238
|
+
lines = f.readlines()
|
|
239
|
+
|
|
240
|
+
content_all = "".join(lines)
|
|
241
|
+
|
|
242
|
+
# Default app variable name might be different
|
|
243
|
+
app_var_match = re.search(r'([a-zA-Z0-9_]+)\s*=\s*App\(', content_all)
|
|
244
|
+
app_var = app_var_match.group(1) if app_var_match else "app"
|
|
245
|
+
|
|
246
|
+
if app_var != "app":
|
|
247
|
+
inject_statement = inject_statement.replace("app.", f"{app_var}.")
|
|
248
|
+
|
|
249
|
+
# 1. Inject Import
|
|
250
|
+
last_import_line = -1
|
|
251
|
+
for i, line in enumerate(lines):
|
|
252
|
+
if line.strip().startswith(("import ", "from ")):
|
|
253
|
+
last_import_line = i
|
|
254
|
+
|
|
255
|
+
if last_import_line != -1:
|
|
256
|
+
lines.insert(last_import_line + 1, import_statement + "\n")
|
|
257
|
+
else:
|
|
258
|
+
lines.insert(0, import_statement + "\n")
|
|
259
|
+
|
|
260
|
+
# 2. Inject add_page
|
|
261
|
+
last_add_page_line = -1
|
|
262
|
+
for i, line in enumerate(lines):
|
|
263
|
+
if f"{app_var}.add_page(" in line:
|
|
264
|
+
last_add_page_line = i
|
|
265
|
+
|
|
266
|
+
if last_add_page_line != -1:
|
|
267
|
+
lines.insert(last_add_page_line + 1, inject_statement + "\n")
|
|
268
|
+
else:
|
|
269
|
+
# Fallback: after app = App(...)
|
|
270
|
+
app_def_line = -1
|
|
271
|
+
for i, line in enumerate(lines):
|
|
272
|
+
if f"{app_var} = App(" in line:
|
|
273
|
+
app_def_line = i
|
|
274
|
+
break
|
|
275
|
+
if app_def_line != -1:
|
|
276
|
+
lines.insert(app_def_line + 1, "\n" + inject_statement + "\n")
|
|
277
|
+
else:
|
|
278
|
+
lines.append("\n" + inject_statement + "\n")
|
|
279
|
+
|
|
280
|
+
with open(entry_file, "w") as f:
|
|
281
|
+
f.writelines(lines)
|
|
282
|
+
|
|
283
|
+
console.print(f"[green]SUCCESS: Successfully added {name} to {entry_file}[/green]")
|
|
284
|
+
except Exception as e:
|
|
285
|
+
console.print(f"[red]Failed to auto-inject: {str(e)}[/red]")
|
|
286
|
+
console.print(f"[yellow]Please add manually:[/yellow]")
|
|
287
|
+
console.print(f"[cyan]{import_statement}[/cyan]")
|
|
288
|
+
console.print(f"[cyan]{inject_statement}[/cyan]")
|