dars-framework 1.9.8__tar.gz → 1.9.9__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.8/dars_framework.egg-info → dars_framework-1.9.9}/PKG-INFO +1 -1
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/exporters/web/resources/dap.js +251 -91
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/scripts/dscript.py +12 -1
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/scripts/utils_ds.py +3 -3
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/version.py +2 -2
- {dars_framework-1.9.8 → dars_framework-1.9.9/dars_framework.egg-info}/PKG-INFO +1 -1
- {dars_framework-1.9.8 → dars_framework-1.9.9}/pyproject.toml +1 -1
- {dars_framework-1.9.8 → dars_framework-1.9.9}/Dars-logo.png +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/LICENSE +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/MANIFEST.in +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/README.md +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/__init__.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/actionProtocol.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/all.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/backend/__init__.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/backend/components.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/backend/data.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/backend/http.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/backend/json_utils.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/backend/middleware.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/backend/route_loader.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/backend/ssr.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/backend/store.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/backend/upload.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/cli/__init__.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/cli/doctor/__init__.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/cli/doctor/detect.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/cli/doctor/doctor.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/cli/doctor/installers.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/cli/doctor/persist.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/cli/doctor/preflight.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/cli/doctor/ui.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/cli/dpm.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/cli/generate.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/cli/hot_reload.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/cli/main.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/cli/preview.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/cli/prompts.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/cli/translations.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/__init__.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/advanced/__init__.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/advanced/accordion.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/advanced/card.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/advanced/file_upload.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/advanced/head.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/advanced/modal.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/advanced/navbar.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/advanced/outlet.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/advanced/table.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/advanced/tabs.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/basic/__init__.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/basic/audio.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/basic/button.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/basic/checkbox.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/basic/container.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/basic/datepicker.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/basic/each_component.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/basic/if_component.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/basic/image.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/basic/input.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/basic/link.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/basic/markdown.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/basic/page.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/basic/progressbar.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/basic/radiobutton.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/basic/section.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/basic/select.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/basic/show_component.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/basic/slider.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/basic/spinner.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/basic/text.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/basic/textarea.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/basic/tooltip.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/basic/video.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/layout/__init__.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/layout/anchor.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/layout/flex.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/layout/grid.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/visualization/__init__.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/visualization/chart.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/components/visualization/table.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/config.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/core/__init__.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/core/app.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/core/component.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/core/events.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/core/js_bridge.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/core/properties.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/core/route_types.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/core/routing.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/core/state.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/core/state_v2.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/core/utilities.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/dars_tests/apps_test/health_check.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/dars_tests/run_tests.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/dars_tests/tests/test_advanced_components.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/dars_tests/tests/test_basic_components.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/dars_tests/tests/test_core_and_cli.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/dars_tests/tests/test_layout_components.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/dars_tests/tests/test_version_check.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/desktop/__init__.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/desktop/api.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/desktop/js_generator.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/docs/__init__.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/docs/index.md +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/env.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/exporters/__init__.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/exporters/base.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/exporters/desktop/electron.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/exporters/web/__init__.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/exporters/web/html_css_js.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/exporters/web/resources/anim.js +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/exporters/web/resources/dars.min.js +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/exporters/web/resources/dompurify.js +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/exporters/web/resources/router.js +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/exporters/web/resources/ssr.js +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/exporters/web/vdom.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/hooks/__init__.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/hooks/form_helpers.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/hooks/form_validator.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/hooks/set_vref.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/hooks/update_vref.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/hooks/use_dynamic.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/hooks/use_fetch.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/hooks/use_value.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/hooks/use_vref.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/hooks/use_watch.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/hooks/value_helpers.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/scripts/__init__.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/scripts/animations.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/scripts/keycode.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/scripts/script.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/security.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/templates/__init__.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/templates/desktop/icon.png +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/templates/desktop/template/backend/icons/icon.png +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/templates/desktop/template/backend/main.js +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/templates/desktop/template/backend/package.json +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/templates/desktop/template/backend/preload.js +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/templates/desktop/template/dars.config.json +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/templates/desktop/template/icons/icon.png +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/templates/desktop/template/main.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/templates/desktop/template/public/electron-icon.png +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/templates/desktop/template/public/icon.png +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/templates/examples/README.md +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/templates/examples/advanced/CustomComp/main.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/templates/examples/advanced/Modal_Demo/advanced_modal_demo.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/templates/examples/advanced/StateV2/README.md +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/templates/examples/advanced/StateV2/animation_component.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/templates/examples/advanced/StateV2/counter_component.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/templates/examples/advanced/StateV2/hero_component.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/templates/examples/advanced/StateV2/main.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/templates/examples/advanced/StateV2/styles.css +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/templates/examples/advanced/StateV2/timer_component.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/templates/examples/advanced/VariousComponents/all_components_demo.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/templates/examples/advanced/__init__.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/templates/examples/advanced/dState/state_mods_demo.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/templates/examples/advanced/hooks/useDynamic.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/templates/examples/advanced/hooks/useValue.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/templates/examples/advanced/hooks/useWatch.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/templates/examples/basic/HelloWorld/hello_world.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/templates/examples/basic/Layouts/flex_layout_responsive.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/templates/examples/basic/Layouts/grid_layout_responsive.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/templates/examples/basic/Layouts/layout_multipage_demo.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/templates/examples/basic/PWA/icon-192x192.png +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/templates/examples/basic/PWA/icon-512x512.png +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/templates/examples/basic/PWA/pwa_custom_icons.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/templates/examples/basic/__init__.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/templates/examples/markdown/MarkdownTemplate/README.md +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/templates/examples/markdown/MarkdownTemplate/markdown_template.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/templates/examples/markdown/MarkdownTemplate/other_docs.md +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars/templates/examples/markdown/__init__.py +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars_framework.egg-info/SOURCES.txt +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars_framework.egg-info/dependency_links.txt +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars_framework.egg-info/entry_points.txt +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars_framework.egg-info/requires.txt +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/dars_framework.egg-info/top_level.txt +0 -0
- {dars_framework-1.9.8 → dars_framework-1.9.9}/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.9
|
|
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>
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
updateVRef,
|
|
10
10
|
__registry,
|
|
11
11
|
} from "./dars.min.js";
|
|
12
|
+
import { _executeExternalScript } from "./ssr.js";
|
|
12
13
|
|
|
13
14
|
export const __commandRegistry = new Map();
|
|
14
15
|
export const __darsConfig = {
|
|
@@ -85,14 +86,15 @@ _registerCommand("confirm", (args, ctx) => {
|
|
|
85
86
|
});
|
|
86
87
|
_registerCommand("log", (args) => console.log(args.message || args));
|
|
87
88
|
|
|
88
|
-
_registerCommand("sequence", (args, ctx) => {
|
|
89
|
+
_registerCommand("sequence", async (args, ctx) => {
|
|
89
90
|
const actions = Array.isArray(args) ? args : args.actions || [];
|
|
90
91
|
for (const a of actions) {
|
|
91
92
|
if (a && a.op === "delay") {
|
|
92
93
|
const ms = a.args?.ms || a.ms || 0;
|
|
93
|
-
|
|
94
|
+
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
95
|
+
if (a.args && a.args.action) await dispatch(a.args.action, ctx);
|
|
94
96
|
} else {
|
|
95
|
-
dispatch(a, ctx);
|
|
97
|
+
await dispatch(a, ctx);
|
|
96
98
|
}
|
|
97
99
|
}
|
|
98
100
|
});
|
|
@@ -136,20 +138,87 @@ _registerCommand("dom_set_value", (args) => {
|
|
|
136
138
|
});
|
|
137
139
|
// Blocked attribute names that could introduce XSS via event handlers or dangerous protocols
|
|
138
140
|
const _BLOCKED_ATTRS = new Set([
|
|
139
|
-
"onclick",
|
|
140
|
-
"
|
|
141
|
-
"
|
|
142
|
-
"
|
|
143
|
-
"
|
|
144
|
-
"
|
|
145
|
-
"
|
|
146
|
-
"
|
|
147
|
-
"
|
|
148
|
-
"
|
|
149
|
-
"
|
|
150
|
-
"
|
|
151
|
-
"
|
|
152
|
-
"
|
|
141
|
+
"onclick",
|
|
142
|
+
"ondblclick",
|
|
143
|
+
"onmousedown",
|
|
144
|
+
"onmouseup",
|
|
145
|
+
"onmouseover",
|
|
146
|
+
"onmouseout",
|
|
147
|
+
"onmousemove",
|
|
148
|
+
"onkeydown",
|
|
149
|
+
"onkeyup",
|
|
150
|
+
"onkeypress",
|
|
151
|
+
"onchange",
|
|
152
|
+
"oninput",
|
|
153
|
+
"onfocus",
|
|
154
|
+
"onblur",
|
|
155
|
+
"onsubmit",
|
|
156
|
+
"onreset",
|
|
157
|
+
"onselect",
|
|
158
|
+
"onload",
|
|
159
|
+
"onunload",
|
|
160
|
+
"onerror",
|
|
161
|
+
"onabort",
|
|
162
|
+
"onresize",
|
|
163
|
+
"onscroll",
|
|
164
|
+
"oncontextmenu",
|
|
165
|
+
"ondrag",
|
|
166
|
+
"ondragend",
|
|
167
|
+
"ondragenter",
|
|
168
|
+
"ondragleave",
|
|
169
|
+
"ondragover",
|
|
170
|
+
"ondragstart",
|
|
171
|
+
"ondrop",
|
|
172
|
+
"onanimationstart",
|
|
173
|
+
"onanimationend",
|
|
174
|
+
"ontransitionend",
|
|
175
|
+
"onpointerdown",
|
|
176
|
+
"onpointerup",
|
|
177
|
+
"onpointermove",
|
|
178
|
+
"onpointerover",
|
|
179
|
+
"onpointerout",
|
|
180
|
+
"onpointerenter",
|
|
181
|
+
"onpointerleave",
|
|
182
|
+
"onpointercancel",
|
|
183
|
+
"ontouchstart",
|
|
184
|
+
"ontouchend",
|
|
185
|
+
"ontouchmove",
|
|
186
|
+
"ontouchcancel",
|
|
187
|
+
"onwheel",
|
|
188
|
+
"oncopy",
|
|
189
|
+
"oncut",
|
|
190
|
+
"onpaste",
|
|
191
|
+
"onbeforeinput",
|
|
192
|
+
"onformdata",
|
|
193
|
+
"oninvalid",
|
|
194
|
+
"onprogress",
|
|
195
|
+
"onratechange",
|
|
196
|
+
"onseeked",
|
|
197
|
+
"onseeking",
|
|
198
|
+
"onstalled",
|
|
199
|
+
"onsuspend",
|
|
200
|
+
"ontimeupdate",
|
|
201
|
+
"onvolumechange",
|
|
202
|
+
"onwaiting",
|
|
203
|
+
"oncanplay",
|
|
204
|
+
"oncanplaythrough",
|
|
205
|
+
"ondurationchange",
|
|
206
|
+
"onemptied",
|
|
207
|
+
"onended",
|
|
208
|
+
"onloadeddata",
|
|
209
|
+
"onloadedmetadata",
|
|
210
|
+
"onloadstart",
|
|
211
|
+
"onplay",
|
|
212
|
+
"onplaying",
|
|
213
|
+
"onpause",
|
|
214
|
+
"srcdoc",
|
|
215
|
+
"formaction",
|
|
216
|
+
"action",
|
|
217
|
+
"href",
|
|
218
|
+
"src",
|
|
219
|
+
"data",
|
|
220
|
+
"codebase",
|
|
221
|
+
"classid",
|
|
153
222
|
]);
|
|
154
223
|
|
|
155
224
|
_registerCommand("dom_set_attr", (args) => {
|
|
@@ -157,13 +226,17 @@ _registerCommand("dom_set_attr", (args) => {
|
|
|
157
226
|
if (!el) return;
|
|
158
227
|
const attrName = String(args.name).toLowerCase().trim();
|
|
159
228
|
if (_BLOCKED_ATTRS.has(attrName)) {
|
|
160
|
-
console.warn(
|
|
229
|
+
console.warn(
|
|
230
|
+
`[Dars:Security] Blocked attempt to set dangerous attribute: "${attrName}"`,
|
|
231
|
+
);
|
|
161
232
|
return;
|
|
162
233
|
}
|
|
163
234
|
// Block javascript: protocol in any remaining attribute value
|
|
164
235
|
const val = String(args.value);
|
|
165
236
|
if (/^\s*javascript\s*:/i.test(val)) {
|
|
166
|
-
console.warn(
|
|
237
|
+
console.warn(
|
|
238
|
+
`[Dars:Security] Blocked javascript: URI in attribute "${attrName}"`,
|
|
239
|
+
);
|
|
167
240
|
return;
|
|
168
241
|
}
|
|
169
242
|
el.setAttribute(attrName, val);
|
|
@@ -306,7 +379,9 @@ _registerCommand("fetch", async (args, ctx) => {
|
|
|
306
379
|
// When backendUrl is "/" or empty, keep the URL as-is (same-origin).
|
|
307
380
|
let fetchUrl = args.url;
|
|
308
381
|
if (fetchUrl && !/^https?:\/\//i.test(fetchUrl)) {
|
|
309
|
-
const base =
|
|
382
|
+
const base =
|
|
383
|
+
(window.__DARS_SPA_CONFIG__ && window.__DARS_SPA_CONFIG__.backendUrl) ||
|
|
384
|
+
"";
|
|
310
385
|
if (base && base !== "/") fetchUrl = base.replace(/\/$/, "") + fetchUrl;
|
|
311
386
|
}
|
|
312
387
|
const resp = await fetch(fetchUrl, args.options || {});
|
|
@@ -370,7 +445,8 @@ _registerCommand("transform", async (args, ctx) => {
|
|
|
370
445
|
if (args.method === "upper") return String(input).toUpperCase();
|
|
371
446
|
if (args.method === "lower") return String(input).toLowerCase();
|
|
372
447
|
if (args.method === "trim") return String(input == null ? "" : input).trim();
|
|
373
|
-
if (args.method === "length")
|
|
448
|
+
if (args.method === "length")
|
|
449
|
+
return String(input == null ? "" : input).trim().length;
|
|
374
450
|
if (args.method === "is_email") {
|
|
375
451
|
const s = String(input == null ? "" : input).trim();
|
|
376
452
|
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(s);
|
|
@@ -378,7 +454,9 @@ _registerCommand("transform", async (args, ctx) => {
|
|
|
378
454
|
if (args.method === "test_pattern") {
|
|
379
455
|
try {
|
|
380
456
|
return new RegExp(args.pattern).test(String(input == null ? "" : input));
|
|
381
|
-
} catch (_) {
|
|
457
|
+
} catch (_) {
|
|
458
|
+
return false;
|
|
459
|
+
}
|
|
382
460
|
}
|
|
383
461
|
if (args.method === "json_stringify") {
|
|
384
462
|
// Return the object itself — network_request will JSON.stringify it
|
|
@@ -391,22 +469,32 @@ _registerCommand("transform", async (args, ctx) => {
|
|
|
391
469
|
if (args.method === "tasks_to_html") {
|
|
392
470
|
try {
|
|
393
471
|
const data = typeof input === "string" ? JSON.parse(input) : input;
|
|
394
|
-
const tasks = Array.isArray(data)
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
472
|
+
const tasks = Array.isArray(data)
|
|
473
|
+
? data
|
|
474
|
+
: data && data.tasks
|
|
475
|
+
? data.tasks
|
|
476
|
+
: [];
|
|
477
|
+
if (!tasks.length)
|
|
478
|
+
return '<p class="text-gray-400 text-sm p-2">No tasks yet.</p>';
|
|
479
|
+
return tasks
|
|
480
|
+
.map((t) => {
|
|
481
|
+
// Safely extract title — handle string, number, or nested object
|
|
482
|
+
let title = "";
|
|
483
|
+
if (t && t.title !== undefined && t.title !== null) {
|
|
484
|
+
title =
|
|
485
|
+
typeof t.title === "object"
|
|
486
|
+
? JSON.stringify(t.title)
|
|
487
|
+
: String(t.title);
|
|
488
|
+
}
|
|
489
|
+
const safeTitle = _sanitize(title);
|
|
490
|
+
const done = t && t.done;
|
|
491
|
+
const id = t && t.id ? t.id : "";
|
|
492
|
+
return `<div class="flex items-center gap-2 p-2 border rounded mb-1 bg-white">
|
|
493
|
+
<span class="flex-1 ${done ? "line-through text-gray-400" : ""}">${safeTitle || '<em class="text-gray-300">untitled</em>'}</span>
|
|
407
494
|
<span class="text-xs text-gray-400">#${id}</span>
|
|
408
495
|
</div>`;
|
|
409
|
-
|
|
496
|
+
})
|
|
497
|
+
.join("");
|
|
410
498
|
} catch (e) {
|
|
411
499
|
return `<p class="text-red-400 text-sm">Error rendering tasks: ${e.message}</p>`;
|
|
412
500
|
}
|
|
@@ -537,7 +625,10 @@ _registerCommand("vref_set", async (args, ctx) => {
|
|
|
537
625
|
*/
|
|
538
626
|
_registerCommand("storage_get_to_vref", async (args, ctx) => {
|
|
539
627
|
const val = localStorage.getItem(args.storage_key);
|
|
540
|
-
return dispatch(
|
|
628
|
+
return dispatch(
|
|
629
|
+
{ op: "vref_update", args: { selector: args.selector, value: val } },
|
|
630
|
+
ctx,
|
|
631
|
+
);
|
|
541
632
|
});
|
|
542
633
|
|
|
543
634
|
/**
|
|
@@ -589,11 +680,17 @@ _registerCommand("network_request", async (args, ctx) => {
|
|
|
589
680
|
|
|
590
681
|
// Set loading state
|
|
591
682
|
if (loading_selector) {
|
|
592
|
-
dispatch(
|
|
683
|
+
dispatch(
|
|
684
|
+
{ op: "vref_update", args: { selector: loading_selector, value: true } },
|
|
685
|
+
ctx,
|
|
686
|
+
);
|
|
593
687
|
}
|
|
594
688
|
|
|
595
689
|
try {
|
|
596
|
-
const fetchConfig = {
|
|
690
|
+
const fetchConfig = {
|
|
691
|
+
method: method.toUpperCase(),
|
|
692
|
+
headers: { ...headers },
|
|
693
|
+
};
|
|
597
694
|
|
|
598
695
|
// Inject auth token if present
|
|
599
696
|
const token = localStorage.getItem("dars_auth_token");
|
|
@@ -624,10 +721,22 @@ _registerCommand("network_request", async (args, ctx) => {
|
|
|
624
721
|
localStorage.removeItem("dars_auth_token");
|
|
625
722
|
const errMsg = "Unauthorized (401)";
|
|
626
723
|
if (loading_selector) {
|
|
627
|
-
dispatch(
|
|
724
|
+
dispatch(
|
|
725
|
+
{
|
|
726
|
+
op: "vref_update",
|
|
727
|
+
args: { selector: loading_selector, value: false },
|
|
728
|
+
},
|
|
729
|
+
ctx,
|
|
730
|
+
);
|
|
628
731
|
}
|
|
629
732
|
if (error_selector) {
|
|
630
|
-
dispatch(
|
|
733
|
+
dispatch(
|
|
734
|
+
{
|
|
735
|
+
op: "vref_update",
|
|
736
|
+
args: { selector: error_selector, value: errMsg },
|
|
737
|
+
},
|
|
738
|
+
ctx,
|
|
739
|
+
);
|
|
631
740
|
}
|
|
632
741
|
if (on_error) dispatch(on_error, { ...ctx, error: errMsg });
|
|
633
742
|
return;
|
|
@@ -646,20 +755,40 @@ _registerCommand("network_request", async (args, ctx) => {
|
|
|
646
755
|
}
|
|
647
756
|
|
|
648
757
|
if (loading_selector) {
|
|
649
|
-
dispatch(
|
|
758
|
+
dispatch(
|
|
759
|
+
{
|
|
760
|
+
op: "vref_update",
|
|
761
|
+
args: { selector: loading_selector, value: false },
|
|
762
|
+
},
|
|
763
|
+
ctx,
|
|
764
|
+
);
|
|
650
765
|
}
|
|
651
766
|
if (data_selector) {
|
|
652
|
-
dispatch(
|
|
767
|
+
dispatch(
|
|
768
|
+
{ op: "vref_update", args: { selector: data_selector, value: data } },
|
|
769
|
+
ctx,
|
|
770
|
+
);
|
|
653
771
|
}
|
|
654
772
|
if (on_success) dispatch(on_success, { ...ctx, response: data });
|
|
655
|
-
|
|
656
773
|
} catch (e) {
|
|
657
774
|
const errMsg = e && e.message ? e.message : String(e);
|
|
658
775
|
if (loading_selector) {
|
|
659
|
-
dispatch(
|
|
776
|
+
dispatch(
|
|
777
|
+
{
|
|
778
|
+
op: "vref_update",
|
|
779
|
+
args: { selector: loading_selector, value: false },
|
|
780
|
+
},
|
|
781
|
+
ctx,
|
|
782
|
+
);
|
|
660
783
|
}
|
|
661
784
|
if (error_selector) {
|
|
662
|
-
dispatch(
|
|
785
|
+
dispatch(
|
|
786
|
+
{
|
|
787
|
+
op: "vref_update",
|
|
788
|
+
args: { selector: error_selector, value: errMsg },
|
|
789
|
+
},
|
|
790
|
+
ctx,
|
|
791
|
+
);
|
|
663
792
|
}
|
|
664
793
|
if (on_error) dispatch(on_error, { ...ctx, error: errMsg });
|
|
665
794
|
}
|
|
@@ -711,19 +840,21 @@ _registerCommand("render_tasks", (args, ctx) => {
|
|
|
711
840
|
if (!el) return;
|
|
712
841
|
try {
|
|
713
842
|
const data = ctx && ctx.response ? ctx.response : {};
|
|
714
|
-
const tasks = Array.isArray(data) ? data :
|
|
843
|
+
const tasks = Array.isArray(data) ? data : data.tasks || [];
|
|
715
844
|
if (!tasks.length) {
|
|
716
845
|
el.innerHTML = '<p class="text-gray-400 text-sm p-2">No tasks yet.</p>';
|
|
717
846
|
return;
|
|
718
847
|
}
|
|
719
|
-
el.innerHTML = tasks
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
848
|
+
el.innerHTML = tasks
|
|
849
|
+
.map((t) => {
|
|
850
|
+
const title = _sanitize(String(t.title || ""));
|
|
851
|
+
const done = t.done ? "line-through text-gray-400" : "";
|
|
852
|
+
return `<div class="flex items-center gap-2 p-2 border rounded mb-1 bg-white shadow-sm">
|
|
723
853
|
<span class="flex-1 ${done}">${title || "<em class='text-gray-300'>untitled</em>"}</span>
|
|
724
854
|
<span class="text-xs text-gray-400 ml-2">#${t.id || ""}</span>
|
|
725
855
|
</div>`;
|
|
726
|
-
|
|
856
|
+
})
|
|
857
|
+
.join("");
|
|
727
858
|
} catch (e) {
|
|
728
859
|
el.innerHTML = `<p class="text-red-400 text-sm p-2">Error: ${e.message}</p>`;
|
|
729
860
|
}
|
|
@@ -743,7 +874,10 @@ if (_origVrefUpdate) {
|
|
|
743
874
|
try {
|
|
744
875
|
const containerSel = container.getAttribute("data-dap-each");
|
|
745
876
|
if (containerSel === sel && container.id) {
|
|
746
|
-
await dispatch(
|
|
877
|
+
await dispatch(
|
|
878
|
+
{ op: "dom_each_render", args: { id: container.id } },
|
|
879
|
+
ctx,
|
|
880
|
+
);
|
|
747
881
|
}
|
|
748
882
|
} catch (_) {}
|
|
749
883
|
}
|
|
@@ -819,7 +953,10 @@ _registerCommand("dom_each_render", async (args, ctx) => {
|
|
|
819
953
|
if (items && !Array.isArray(items) && typeof items === "object") {
|
|
820
954
|
const keys = ["tasks", "items", "data", "results", "list", "rows"];
|
|
821
955
|
for (const k of keys) {
|
|
822
|
-
if (Array.isArray(items[k])) {
|
|
956
|
+
if (Array.isArray(items[k])) {
|
|
957
|
+
items = items[k];
|
|
958
|
+
break;
|
|
959
|
+
}
|
|
823
960
|
}
|
|
824
961
|
}
|
|
825
962
|
|
|
@@ -837,49 +974,72 @@ _registerCommand("dom_each_render", async (args, ctx) => {
|
|
|
837
974
|
|
|
838
975
|
if (!template) {
|
|
839
976
|
// Fallback: plain text rendering
|
|
840
|
-
container.innerHTML = items
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
977
|
+
container.innerHTML = items
|
|
978
|
+
.map((item) => {
|
|
979
|
+
const text = _sanitize(
|
|
980
|
+
String(
|
|
981
|
+
item && typeof item === "object"
|
|
982
|
+
? (item.title ??
|
|
983
|
+
item.name ??
|
|
984
|
+
item.label ??
|
|
985
|
+
item.value ??
|
|
986
|
+
item.text ??
|
|
987
|
+
JSON.stringify(item))
|
|
988
|
+
: item,
|
|
989
|
+
),
|
|
990
|
+
);
|
|
991
|
+
return `<div>${text}</div>`;
|
|
992
|
+
})
|
|
993
|
+
.join("");
|
|
848
994
|
return;
|
|
849
995
|
}
|
|
850
996
|
|
|
851
997
|
// Render each item by substituting placeholders in the template
|
|
852
|
-
const rendered = items
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
998
|
+
const rendered = items
|
|
999
|
+
.map((item) => {
|
|
1000
|
+
if (item === null || item === undefined) return "";
|
|
1001
|
+
let html = template;
|
|
1002
|
+
|
|
1003
|
+
if (typeof item === "object") {
|
|
1004
|
+
// Normalize empty/unknown title values before substitution
|
|
1005
|
+
if (item.title !== undefined) {
|
|
1006
|
+
const t = String(item.title || "").trim();
|
|
1007
|
+
item = {
|
|
1008
|
+
...item,
|
|
1009
|
+
title:
|
|
1010
|
+
t === "" ||
|
|
1011
|
+
t.toLowerCase() === "unknown" ||
|
|
1012
|
+
t.toLowerCase() === "null" ||
|
|
1013
|
+
t.toLowerCase() === "none"
|
|
1014
|
+
? "Unknown"
|
|
1015
|
+
: t,
|
|
1016
|
+
};
|
|
1017
|
+
}
|
|
1018
|
+
// Inject a done_class placeholder value based on the done field
|
|
1019
|
+
const doneClass = item.done ? "line-through text-gray-400" : "";
|
|
1020
|
+
item = { ...item, done_class: doneClass };
|
|
1021
|
+
|
|
1022
|
+
// Replace __item_<field>__ with the sanitized field value
|
|
1023
|
+
for (const [key, val] of Object.entries(item)) {
|
|
1024
|
+
const placeholder = `__item_${key}__`;
|
|
1025
|
+
// Don't sanitize class names — they're safe strings we control
|
|
1026
|
+
const safeVal =
|
|
1027
|
+
key === "done_class"
|
|
1028
|
+
? String(val)
|
|
1029
|
+
: _sanitize(String(val == null ? "" : val));
|
|
1030
|
+
html = html.split(placeholder).join(safeVal);
|
|
1031
|
+
}
|
|
1032
|
+
} else {
|
|
1033
|
+
// Scalar item — replace generic __item_value__ placeholder
|
|
1034
|
+
const safeVal = _sanitize(String(item));
|
|
1035
|
+
html = html.split("__item_value__").join(safeVal);
|
|
872
1036
|
}
|
|
873
|
-
} else {
|
|
874
|
-
// Scalar item — replace generic __item_value__ placeholder
|
|
875
|
-
const safeVal = _sanitize(String(item));
|
|
876
|
-
html = html.split("__item_value__").join(safeVal);
|
|
877
|
-
}
|
|
878
1037
|
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
1038
|
+
// Remove any unreplaced sentinel placeholders
|
|
1039
|
+
html = html.replace(/__item_[a-zA-Z0-9_]+__/g, "");
|
|
1040
|
+
return html;
|
|
1041
|
+
})
|
|
1042
|
+
.join("");
|
|
883
1043
|
|
|
884
1044
|
container.innerHTML = rendered;
|
|
885
1045
|
});
|
|
@@ -171,6 +171,13 @@ def compile_val(v, is_async=False):
|
|
|
171
171
|
return f"String({sub}).toLowerCase()"
|
|
172
172
|
elif method == 'trim':
|
|
173
173
|
return f"String({sub}).trim()"
|
|
174
|
+
elif method == 'length':
|
|
175
|
+
return f"String({sub} || '').trim().length"
|
|
176
|
+
elif method == 'is_email':
|
|
177
|
+
return f"/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(String({sub} || '').trim())"
|
|
178
|
+
elif method == 'test_pattern':
|
|
179
|
+
pat = json.dumps(args.get('pattern', ''))
|
|
180
|
+
return f"(function() {{ try {{ return new RegExp({pat}).test(String({sub} || '')); }} catch(_) {{ return false; }} }})()"
|
|
174
181
|
elif method == 'validate_operator':
|
|
175
182
|
ops = json.dumps(args.get('valid_ops', ['+', '-', '*', '/']), default=_ser)
|
|
176
183
|
return f"(({ops}).includes({sub}) ? {sub} : '+')"
|
|
@@ -179,7 +186,11 @@ def compile_val(v, is_async=False):
|
|
|
179
186
|
elif op == 'bool_expr':
|
|
180
187
|
left = compile_val(args.get('left'), is_async=is_async)
|
|
181
188
|
right = compile_val(args.get('right'), is_async=is_async)
|
|
182
|
-
op_map = {
|
|
189
|
+
op_map = {
|
|
190
|
+
'==': '==', '===': '===', '!=': '!=', '!==': '!==',
|
|
191
|
+
'>': '>', '<': '<', '>=': '>=', '<=': '<=',
|
|
192
|
+
'&&': '&&', '||': '||'
|
|
193
|
+
}
|
|
183
194
|
js_op = op_map.get(args.get('operator'), '==')
|
|
184
195
|
return f"({left} {js_op} {right})"
|
|
185
196
|
|
|
@@ -514,7 +514,7 @@ def getValue(input_id: str, target_id: str) -> RawJS:
|
|
|
514
514
|
return RawJS(code=Action.dom_set_text(id=target_id, text=RawJS(f"document.getElementById('{input_id}').value")))
|
|
515
515
|
|
|
516
516
|
|
|
517
|
-
def clearInput(input_id: str) ->
|
|
517
|
+
def clearInput(input_id: str) -> dScript:
|
|
518
518
|
"""
|
|
519
519
|
Clear the value of an input field and trigger the 'input' event.
|
|
520
520
|
|
|
@@ -522,14 +522,14 @@ def clearInput(input_id: str) -> RawJS:
|
|
|
522
522
|
input_id (str): The ID of the input or textarea.
|
|
523
523
|
|
|
524
524
|
Returns:
|
|
525
|
-
|
|
525
|
+
dScript: The compiled `input_clear` action.
|
|
526
526
|
|
|
527
527
|
Example:
|
|
528
528
|
```python
|
|
529
529
|
Button("Clear Search", on_click=clearInput("search_box"))
|
|
530
530
|
```
|
|
531
531
|
"""
|
|
532
|
-
return
|
|
532
|
+
return dScript(data={"op": "input_clear", "args": {"id": input_id}})
|
|
533
533
|
|
|
534
534
|
|
|
535
535
|
# ============= Storage Utilities =============
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dars-framework
|
|
3
|
-
Version: 1.9.
|
|
3
|
+
Version: 1.9.9
|
|
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>
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "dars-framework"
|
|
7
|
-
version = "1.9.
|
|
7
|
+
version = "1.9.9"
|
|
8
8
|
description = "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."
|
|
9
9
|
dependencies = [ "rich==15.0.0", "bs4==0.0.2", "uvicorn==0.46.0", "markdown2==2.5.5", "requests==2.33.1", "plotly==6.7.0", "fastapi==0.136.1", "rjsmin==1.2.5", "rcssmin==1.2.2", "starlette==0.47.3", "python-multipart==0.0.28"]
|
|
10
10
|
license = "MPL-2.0"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|